class Parent {
void a() {}
void b() {}
}
class Child extends Parent {
void c() {}
}
public class Main {
public static void main(String[] args) {
Parent p = new Child();
Child c = new Child();
}
}
위의 코드를 보면 Child클래스가 Parent클래스를 상속받고 있다.
앞서 설명한 것처럼 조상클래스 Parent타입인 참조변수 p로 자손클래스 Child인스턴스를 참조할 수 있다.
반대로 자손클래스 타입의 참조변수로 조상클래스의 인스턴스를 참조하는 것은 불가능하다.
조상클래스 타입의 참조변수로 자손클래스 인스턴스를 참조했을 경우에, 자손 인스턴스의 멤버는 사용할 수 없고, 조상클래스에 있는 멤버만 사용가능하다.
위의 참조변수 p와 c가 참조하는 인스턴스는 Child로 같지만 참조변수(리모콘)의 타입에 따라서 사용할 수 있는 멤버에는 차이가 있다.
기본형인 int와 long을 예로 들어 설명하면,
int에서 long으로 형변환을 하는 것은 값의 손실이 발생하지 않기 때문에, 형변환을 생략할 수 있다.
반대로 long에서 int로 형변환을 하려면, long타입의 값의 범위가 더 크기 때문에 형변환을 명시해주어야 한다.
참조변수의 형변환도 이와 마찬가지이다.
자손타입에서 조상타입으로 형변환을 하는 경우에는 자손타입의 인스턴스가 가진 멤버가 더 많거나 같기 때문에, 형변환을 생략할 수 있다.
반대로 조상타입에서 자손타입으로 형변환을 하는 경우에는 형변환을 명시해 주어야 한다.
자손타입 -> 조상타입 : 형변환 생략가능
조상타입 -> 자손타입 : 형변환 생략불가
다형성의 장점 중 하나는 매개변수의 형태로 여러객체를 취할 수 있다는 것이다.
아래의 코드를 보자
class Product {
int price;
int bonusPoint;
Product(int price) {
this.price = price;
bonusPoint = (int)(price / 10.0);
}
}
class Tv extends Product {
Tv() {
super(100);
}
public String toString() { return "Tv"; }
}
class Computer extends Product {
Computer() { super(250); }
public String toString() { return "Computer"; }
}
class Audio extends Product {
Audio() { super(50); }
public String toString() { return "Audio"; }
}
class Buyer {
int money = 1000;
int bonusPoint = 0;
void buy(Product p) { //Product의 자손 객체가 들어갈 수 있으므로 객체 각각에 대해서 메서드를 만들 필요가 없다.
if(money < p.price) {
System.out.println("잔액이 부족합니다");
return;
}
money -= p.price;
bonusPoint += p.bonusPoint;
System.out.println(p + " 구입완료");
}
}
Tv, Computer, Audio클래스는 각각 Product라는 하나의 클래스를 상속받고 있다.
Buyer클래스의 buy메서드의 매개변수가 Product타입이다.
이것은 곧 product클래스를 상속받는 클래스들이 모두 buy메서드의 매개변수로 사용될 수 있다는 것을 의미한다.
이렇게 다형성을 이용함으로써, Tv, Computer, Audio클래스 각각에 대해서 buy메서드를 만들지 않아도 되는 것이다. -> 코드 중복 감소, 코드 재사용
Product p1 = new Tv();
Product p2 = new Computer();
Product p3 = new Audio();
int[] array = new int[];
위와 같이 int타입의 배열을 생성하면 그 배열의 요소로는 int타입만 들어갈 수 있다.
하지만 객체지향의 다형성을 활용하면 특정 타입의 배열의 요소에 여러가지 타입의 객체를 넣을 수 있다.
위의 Product, Tv, Computer, Audio클래스를 보자
Tv, Computer, Audio클래스는 Product를 상속받는다.
Product[] p = new Product[2];
p[0] = new Tv();
p[1] = new Computer();
p[2] = new Audio();
위와 같이 Tv, Computer, Audio가 공통으로 상속받는 Product타입의 배열을 생성하면 Product클래스를 상속받는 Tv, Computer, Audio타입의 객체가 해당 배열의 요소로 들어갈 수 있다.