🔸 여러가지 형태를 가질 수 있는 능력으로 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있다.
➡️ 조상클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있다.class Tv{ boolean power; int channel; void power(); void channelUp(){ ++channel; } void channelDown(){ --channel; } } class CaptionTv extends Tv{ String text; void caption(){ ... } CaptionTv captionTv = new CaptionTv(); Tv tv = new CaptionTv(); // 조상타입의 참조변수로 자손 타입의 인스턴스를 참조 }
🔸 참조변수 captionTv로는 조상과 자손클래스의 모든 멤버변수와 메서드를 사용할 수 있지만
🔸 참조변수 tv로는 실제 인스턴스가 자손클래스 타입이라도 조상클래스의 멤버변수와 메서드만 사용할 수 있다.
➡️ 참조변수의 타입에 따라 사용할 수 있는 멤버의 개수가 달라진다.
CaptionTv captionTv = new Tv(); // 에러
🔸 참조변수가 사용할 수 있는 멤버의 개수는 인스턴스의 멤버개수보다 같거나 적어야 한다.
🔸 왜?
➡️ captionTv에는 있는 text라는 멤버와 caption이라는 메서드가 조상클래스 Tv에는 없기때문에 사용하려고 하면 에러가 날 수 밖에 없다.
➡️ 반대로 참조변수가 조상타입일 경우, 애초에 조상클래스에 있는 멤버만 사용할 수 있기 때문에 아무런 문제가 없다.(리모컨에 버튼 자체가 없다고 생각하면 된다.)
➡️ 조상타입의 참조변수로 자손타입의 인스턴스를 참조할 수는 있지만, 자손타입의 참조변수로 조상타입의 인스턴스는 참조할 수 없다.
🔸 서로 상속관계에 있는 경우, 참조변수도 형변환이 가능하다.
Up-casting : 자손타입 -> 조상타입(형변환 생략가능)
Down-casting : 조상타입 -> 자손타입(형변환 생략불가)class Car{ String color; int door; void drive(){...} void stop(){...} } class FireEngine extends Car{ void water(){...} } class Test{ Car car = null; FireEngine fe = new FireEngine(); fe.water(); car = fe; // 형변환이 생략됨, Car타입의 참조변수 car가 FireEngine인스턴스의 주소값을 가지게 됨 car.water(); // 컴파일에러 FireEngine fe2 = (FireEngine)car; // 조상 -> 자손, fe2가 car가 참조하고 있는 인스턴스를 참조하게 함. (타입이 서로 다르기 때문에 형변환을 해줘야 함) fe2.water(); }
🔸 형변환은 인스턴스를 바꾸는 것이 아니라 참조변수의 타입을 바꾸는 것이므로 인스턴스에는 아무런 영향이 없다.
➡️ 형변환을 통해서 참조하고 있는 인스턴스에서 사용할 수 있는 멤버의 범위(개수)를 조절하는 것
🔸 boolean
🔸 참조변수가 참조하고 있는 인스턴스의 타입을 알아볼 때 사용FireEngine fe = new FireEngine(); if(fe instanceof FireEngine){ System.out.println("This is a FireEngine"); } if(fe instanceof Car){ System.out.println("This is a Car"); } if(fe instanceof Object){ System.out.println("This is an Object"); } // 클래스 이름 출력하기 System.out.println(fe.getClass().getName()); ------------------------------------------------- // 결과 This is a FireEngine This is a Car This is an Object FireEngine
🔸 메서드의 매개변수에도 다형성을 적용할 수 있다.
class Product{} class Tv extends Product{} class Audio extends Product{} clsss Buyer{ //void buy(Audio audio){...} //void buy(Tv tv){...} void buy(Product product){...} //buy()를 오버로딩 할 필요없이 조상클래스 타입으로 매개변수를 받으면 자손클래스를 매개변수로 사용할 수 있다. }
🔸 조상타입의 참조변수 배열을 사용하면 서로 다른 종류의 객체(같은 조상클래스)를 배열로 묶어서 사용할 수 있다.
Product[] products = new Product[3]; products[0] = new Tv(); // == Product p1 = new Tv(); products[1] = new Audio(); // == Product p2 = new Audio(); products[2] = new Mobile(); // == Product p3 = new Mobile();
🔸 배열을 생성할 때 크기를 한 번 정하면 바꿀 수 없다. 그래서 동적으로 크기가 관리되는 객체 배열이 필요할 때는 Vector클래스를 사용한다.
🔸 메서드
- Vector() : 객체 10개를 저장할 수 있는 Vector인스턴스 생성
- add(Object object) : boolean
- remove(Object object) : boolean
- isEmpty() : boolean
- get(int index) : Object
- int size() : 저장된 객체의 수 반환