chapter 7 객체지향 3

JMG·2022년 1월 18일
0

자바의 정석

목록 보기
11/13

📖 참조변수의 형변환

사용할 수 있는 멤버의 갯수를 조절하는 것입니다.
(주소값이나 객체는 그대로 유지)
조상 자손 관계의 참조변수만 서로 형변환이 가능합니다.(중요!!)

예제)

class Car {
	String color;
	int door;
	
	void drive() {
		System.out.println("drive~~~");
	}

	void stop() {
		System.out.println("stop!!!");
	}
	
}

class FireEngine extends Car {
	void water() {
		System.out.println("water");
	}
}

class Ambulance extends Car {
	//.....
}

class Ex7_7 {
	public static void main(String[] args) {
	
		FireEngine f = new FireEngine();
		f.water(); 

		Car c = (Car)f; // OK. 조상인 Car타입으로 형변환 가능(형변환 생략가능)
		c.water();// 에러!! Car타입의 참조변수로는 water()를 호출할 수 없다.

		FireEngine f2 = (FireEngine)c; // OK. 자손인 FireEngine타입으로 형변환(형변환 생략불가)
		f2.water();

		Ambulance a = (Ambulance)f; // 에러!! 상속관계가 아닌 클래스 간의 형변환 불가
		
		
		//컴파일러는 괜찮으나 예외에러가 발생하는 경우
		
		//NullPointer Exception
		//문법상 문제가 없으나 실제 인스턴스가 생성이 안되어 예외가 발생
		Car c2 = null;
		FireEngine f3 = (FireEngine)c2; //exception발생
		
		//ClassCast Exception
		//참조변수가 가르키는 실제 객체가 중요하다.
		//조상의 인스턴스로 생성된 참조변수가 자손으로 형변환시 발생
		Car c3 = new Car();
		FireEngine f4 = (FireEngine)c3; //exception발생
		f4.water();
	
	}
}

📖 instanceof 연산자

참조변수의 형변환(조상, 자손관계확인) 가능여부 확인에 사용합니다.
가능하면 true를 반환합니다.

예제)


void doWork(Car c) {
	if(c instanceof FireEngine) {	// 1. 형변환이 가능한지 확인
		FireEngine fe = (FireEngine)c; // 2. 형변환
		fe.water();
		......
FireEngine fe = new FireEngine();
System.out.println(fe instanceof Object); // true
System.out.println(fe instanceof Car); // true
System.out.println(fe instanceof FireEngine); // true

📌 Q. 참조변수의 형변환은 왜 하나요?

A. 참조변수(리모콘)을 변경함으로써 사용할 수 있는 멤버의 갯수를 조절하기 위해서입니다.

📌 Q. instanceof 연산자는 언제 사용하나요?

A. 참조변수를 형변환하기 전에 형변환 가능여부를 확인할 때 사용합니다.

📖 매개변수의 다형성

참조형 매개변수는 메서드 호출시, 자신과 같은 타입 또는 자손타입의 인스턴스를 넘겨줄 수 있습니다.

예제)

class Product {
	int price; // 제품가격
	int bonusPoint; // 보너스 점수
}

class Tv extends Product {}
class Computer extends Product {}
class Audio extenda Product {}

class Buyer { // 물건사는 사람
	int money = 1000; // 소유금액
	int bonusPoint = 0; // 보너스 점수

	void buy(Product p) { //오버로딩할 필요없이 하나의 함수로 해결가능하다.
		money -= p.price;
		bonusPoint += p.bonusPoint;
	}
}

📖 여러 종류의 객체를 배열로 다루기

조상타입의 배열에 자손들의 객체를 담을 수 있습니다.
하나의 타입 배열에 여러타입의 변수를 배열로 담아봅시다.

예제)

Product[] p = new Product[3];
p[0] = new Tv();
p[1] = new Computer();
p[2] = new Audio();


class Buyer {
	int money = 1000;
	int bonusPoint = 0;

	Product [] cart = new Product[10]; //구입한 물건을 담을 배열

	int i = 0;
	
	void buy(Product p) {
		if(money < p.price) {
			System.out.println("잔액부족");
			return;
		}
		
		money -= p.price;
		bonusPoint += p.bonucPoint;
		cart[i++] = p;
	}

}

실제사용예)


public class Vector extends AbstractList
		implements List, Cloneable, java.io.Serializable {
	
	// 모든 클래스의 최고조상인 Object를 이용해서
	//어떤 객체든 담을 수 있는 배열 생성
	protected Object elementData[]; 
	.....
}

📖 추상 클래스(abstract class)

미완성 설계도.
미완성 메서드를 갖을 수 있는 클래스입니다.

abstract class Player { // 추상클래스(미완성클래스)
	abstract void play(int pos); //추상메서드(몸통{}이 없는 미완성 메서드)
	abstract void stop(); // 추상메서드
}

//다른 클래스 작성에 도움을 주기 위한 것. 인스턴스 생성 불가
Player p = new Player(); // 에러. 추상 클래스의 인스턴스 생성 불가

//상속을 통해 추상 메서드를 완성해야 인스턴스 생성가능
class AudioPlayer extends Player {
	void play(int pos) { // 추상메서드 구현
		//생략...
	}
	void stop() { // 추상메서드 구현
		//생략....
	}
}


Player ap = new AudioPlayer(); //추상클래스도 형변환이 가능하다!

📖 추상 메서드(abstract method)

미완성 메서드. 구현부(몸통, {}가 없는 메서드)
꼭 필요하지만 자손마다 다르게 구현될 것으로 예상되는 경우에 사용됩니다.

abstract 리턴타입 메서드이름();

예제)

abstract class Player {
	abstract void play(int pos);
	abstract void stop();
}

class AudioPlayer extends Player {
	void play(int pos) { // 추상메서드 구현
		//내용 생략
	}
	void stop() { // 추상메서드 구현
		//내용 생략
	}
}

//추상메서드를 일부만 구현할 경우 abstract키워드를 붙여야한다.
abstract class AbstractPlayer extends Player {
	void play(int pos) { // 추상메서드 1개만 구현 
		//내용 생략
	}
}

📖 추상클래스의 작성

여러 클래스에 공통적으로 사용될 수 있는 추상클래스를 바로 작성하거나 기존 클래스의 공통 부분을 뽑아서 추상클래스를 만듭니다.

예제)

abstract class Unit { //공통된 부분을 추상클래스로 작성
	int x, y; //위치
	abstract void move(int x, int y);
	void stop() {
		//현재위치에서 정지
	};
}

class Marine extends Unit { 
	void move(int x, int y) {
		//지정된 위치로 이동
	}
	void stimPack() {
		//스팀팩 사용
	}
}

class Tank extends Unit { 
	void move(int x, int y) {
		//지정된 위치로 이동
	}
	void changeMode() {
		//공격모드로 변환한다.
	}
}

class Dropship extends Unit { 
	void move(int x, int y) {
		//지정된 위치로 이동
	}
	void load() {
		//선택된 대상을 태운다
	}
	void unload() {
		//선택된 대상을 내린다
	}
}

public class Ex7_10 {
	public static void main(String[] args) {
		Unit[] group = {new Marine(), new Tank(), new Dropship()};

		for(Unit u : group) {
			u.move(100, 200);
		}
	}
}
profile
초보개발 블로그입니다~

0개의 댓글