본문 바로가기

개발지/Today I learn

[0728] 자바 객체지향 프로그래밍 심화 (다형성)

#다형성

- 한 타입의 참조 변수를 여러 타입의 객체가 참조할 수 있도록 만든 것.

class Sports {
	public void sportsInfo() {
		System.out.println("스포츠는 즐겁습니다.");
	}
}

class Soccer extends Sports {
	public void sportsInfo() {
		System.out.println("축구는 즐겁습니다.");
	}
}

class BasketBall extends Sports {
	public void sportsInfo() {
		System.out.println("농구는 즐겁습니다.");
	}
}

public class SportsTest {
	public static void main(String[] args) { 
		Sports sports = new Sports();
		Soccer soccer = new Soccer();
		BasketBall basketball = new BasketBall();
        
		sports.sportsInfo(); // 출력값: 스포츠는 즐겁습니다.
		soccer.sportsInfo(); // 출력값: 축구는 즐겁습니다.
		basketball.sportsInfo(); // 출력값: 농구는 즐겁습니다.
    }
}

- 상위 클래스 타입의 참조 변수로 하위 클래스의 객체를 참조하는 것.

- 상위 클래스 타입인 Sports로 하위 클래스 BasketBall, Soccer를 참조 가능

- 하위 클래스 타입 BasketBall, SoccerSports 참조 불가능

 

#참조 변수의 타입 변환

 - 타입 변환의 조건

  (1) 서로 상속 관계에 있는 상위 - 하위 클래스 사이에만 타입 변환이 가능하다.

  (2) 하위 -> 상위 클래스으로의 타입 변환(업캐스팅)은 형 변환 연산자를(괄호)를 생략할 수 있다.

  (3) 상위 -> 하위 클래스으로의 타입 변환(다운캐스팅)은 형 변환 연산자(괄호)를 생략할 수 없다.

       (다운캐스팅은 업캐스팅이 되어 있는 참조 변수에 한해서만 가능하다.)

public class SoccerTest {
	public static void main(String[] args) {
		Foward son = new Foward();
		SoccerPlayer soccerPlayer = (SoccerPlayer) foward; // 상위클래스 SoccerPlayer 타입으로 변환(괄호 생략 가능)
		Foward hwang = (Foward) SoccerPlayer; // 하위클래스 Foward타입으로 변환(괄호 생략 불가)
		GoalKeeper kim = (Foward) goalKeeper; // 상속 관계가 아니므로 타입 변환 불가 (에러 발생)
	}
}

class SoccerPlayer {
	String name;
	String teamName;
	int uniformNumber;
	
	void sprint() {
		System.out.println("스프린트!");
	}
    
	void pass() {
		System.out.println("패스!");
	}
}

class Foward extend SoccerPlayer {
	void goal() {
		System.out.println("골!");
	}
}

class GoalKeeper extend SoccerPlayer {
	void save() {
		System.out.println("선방!");
	}
}

- 상위 클래스인 SoccerPlayer와 상속받은 FowardGoalKepper 클래스가 있다.

- 상속 관계에 있는 상위 클래스와 하위 클래스는 서로 간의 타입변환이 가능하다 (업캐스팅만 타입괄호 생략 가능)

 

#instanceof 연산자

- 타입변환(캐스팅)이 가능한 지의 여부를 boolean 타입으로 확인할 수 있는 문법 요소

- 타입변환 가능 여부는 객체의 생성자 / 클래스 사이의 상속관계로 결정된다.

- 참조_변수 instanceof 타입으로 사용한다. (리턴 값이 True면 타입 변환 가능)

public class ExampleOfInstance {
	public static void main(String[] args) {
		Fruit fruit = new Fruit();
		System.out.println(Fruit instanceof Object); //True
		System.out.println(Fruit instanceof Fruit); //True
		System.out.println(Fruit instanceof WaterMelon); //True
        
		Fruit apple = new Apple();
		System.out.println(apple instanceof Object); //True
		System.out.println(apple instanceof Fruit); //True
		System.out.println(apple instanceof WaterMelon); //False
		System.out.println(apple instanceof Apple); //True
	}
}

class Fruit {};
class WaterMelon extends Fruit{};
class Apple extends Fruit{};

- 상위 클래스 Fruit 클래스와 상속받은 하위클래스 WaterMelonApple 클래스가 있다.

- instanceof 연산자를 통해 타입 변환이 가능한 지 확인해 보면 상속관계에 따라 결과가 다른 것을 알 수 있다.