💡상위 클래스 타입의 참조변수로 하위 클래스 타입의 객체를 다루는 것
class Tv {
boolean power;
int channel;
void power(){...}
void channelUp(){...}
void channelDown(){...}
}
class SmartTv extends Tv {
String text;
void caption(){...}
}
Tv t = new Tv();
SmartTv s = new SmartTv();
이것처럼 참조 변수를 선언할 때 두 개의 타입이 같아야 하지만
Tv t = new SmartTv();
이와 같이 타입이 불일치 하더라도 사용이 가능한 것을 다형성이라고 한다.
단, 상위 클래스가 하위클래스의 객체를 정의할 때에만 가능
SmartTv s = new Tv(); // 에러 발생
상위클래스의 타입으로 선언한 t는 5개의 버튼을 가지지만 하위 클래스로 인스턴스를 생성하였기 때문에 7개의 멤버를 가진다.
💡 가지고 있는 기능을 실행할 버튼이 없는 것은 괜찮지만 버튼이 있음에도 구현되는 기술이 없는 것은 문제!
💡 하위클래스로 다운캐스팅을 하기 위해서는 업캐스팅이 선행되어야 한다.
이 때문에 instanceof 연산자로 확인 후 형변환을 하는 것이 안전!
💡 실제 객체가 중요! 실제 객체의 멤버 수 이상으로 늘어날 수 없다.
컴파일 에러는 발생하지 않아 실행을 해봤더니 ClassCastException 에러가 발생 했다.
이는 생성된 참조변수 c가 Car 클래스의 인스턴스이기 때문이다.
water 메서드는 Car 클래스를 상속 받은 FireEngine 클래스에서 만들어진 메서드이기 때문에 Car 클래스로 생성된 인스턴스는 형변환을 하더라도 water 메서드가 생성되지 않는다.
💡 참조변수 ani는 Animal클래스의 인스턴스이기 때문에 Anmimal 클래스에 상속받아 확장된 Bat 클래스로 변환이 불가능하다. -> 사용하지 못할 리모컨 버튼이 생길 수도 있기 때문에
class Product {};
class Tv extends Product {};
class Computer extends Product {};
void buy(Tv t) {
money = money - t.price;
}
void buy(Computer c) {
money = money - c.price;
}
.
.
.
=> 하나로 변경 가능
void buy(Product p) {
money = money - p.price;
}
💡 여러번 작성해야 하는 코드를 상위 클래스 참조변수를 매개변수로 사용하여 그 밑에 있는 하위 클래스도 하나의 메서드로 사용할 수 있다.
Product p1 = new Tv();
Product p2 = new Computer();
Product p3 = new Audio();
===>
Product p[] = new product[3];
p[0] = new Tv();
p[1] = new Computer();
p[2] = new Audio();