1. 다형성(polymorphism)
- 여러가지 형태를 가질 수 있는 능력.
- 하나의 참조변수로 여러 타입의 객체를 참조할 수 있는 것.
- 조상클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있도록 하는 것.
- 조상타입의 참조변수로 자손타입의 인스턴스를 참조할 수 있지만, 자손타입의 참조변수로 조상타입의 인스턴스를 참조할 수 없다.
- 참조변수의 타입이 참조변수가 참조하고 있는 객체에서 사용할 수 있는 멤버의 개수를 결정한다.
2. 참조변수의 형변환
- 서로 상속관계에 있는 타입간의 형변환만 가능하다.
- 자손타입 => 조상타입 (Up-casting) : 형변환 생략가능
- 조상타입 => 자손타입 (Down-casting) : 형변환 생략불가
- 바로 윗 조상이나 자손이 아닌 간접적인 상속관계 경우에도 형변환이 가능하다.
- 형변환을 수행하기 전에 instanceof 연산자를 사용해서 인스턴스 타입을 확인하는 것이 안전하다.
class Car { String color; int door; void drive() { System.out.println("운전 합니다. 부릉부릉"); } // drive : 운전하는 메서드 void stop() { System.out.println("정지합니다. 끼이이익"); } // stop : 정지하는 메서드 } // Car class FireEngineCar extends Car { void water() { System.out.println("물 뿌립니다."); } // water : 물뿌리는 메서드 } // FireEngineCar extends Car public class Cating { public static void main(String[] args) { Car car = null; // Car 클래스 타입의 참조변수 car 선언하고 null 로 초기화 FireEngineCar fireEngineCar = new FireEngineCar(); // FireEngineCar 클래스 타입의 참조변수 fireEngineCar 선언, FireEngineCar 인스턴스 생성 FireEngineCar fireEngineCar2 = null; // FireEngineCar 클래스 타입의 참조변수 fireEngineCar 선언하고 null 로 초기화 fireEngineCar.water(); car = fireEngineCar; // car = (Car) fe; 자손 => 조상 형변환은 생략가능 // car.water(); Car 타입의 참조변수로는 자식클래스인 FireEngineCar의 water() 메서드를 호출 할 수 없다. fireEngineCar2 = (FireEngineCar) car; // 조상 => 자손 형변환 fireEngineCar2.water(); } // main } // Cating /* * 결과 * * 물 뿌립니다. * 물 뿌립니다. */
3. instanceof 연산자
- 참조변수가 참조하는 인스턴스의 실제 타입을 알아보기 위해 사용한다.
- 왼쪽에는 참조변수, 오른쪽에는 참조형 변수와 타입, 연산결과는 true, false 하나를 반환한다. (null인 참조변수는 false 결과를 얻는다)
- instanceof 결과가 true 이면, 해당 타입으로 형변환이 가능하다.
class Car { } // Car class FireEngine extends Car { } // FireEngine extends Car public class InstanceofTest { public static void main(String[] args) { FireEngine fireEngine = new FireEngine(); if(fireEngine instanceof FireEngine) { System.out.println("FireEngine 인스턴스"); } if(fireEngine instanceof Car) { System.out.println("Car 인스턴스"); } if(fireEngine instanceof Object) { System.out.println("Object 인스턴스"); } } // main } // InstanceofTest /* * 결과 * * FireEngine 인스턴스 * Car 인스턴스 * Object 인스턴스 */
4. 참조변수와 인스턴스의 연결
- 멤버변수가 중복정의된 경우, 참조변수의 타입에 따라 연결되는 멤버변수가 달라진다.
- 메서드가 중복정의된 경우, 참조변수의 타입에 관계없이 항상 실제 인스턴스(오바라이딩된 메서드)의 타입에 정의된 메서드가 호출된다.
class Parent { int z = 100; void method() { System.out.println("부모 메서드"); } } // Parent class Child extends Parent { int z = 200; void method() { System.out.println("z = " + z); // this.z 와 같다. System.out.println("super.z = " + super.z); System.out.println("this.z = " + this.z); } } // Child extends Parent public class BindingTest { public static void main(String[] args) { Parent parent = new Child(); Child child = new Child(); System.out.println("parent.z = " + parent.z); // 인스턴스 변수인 z는 참조변수의 타입에 따라서 달라진다. parent.method(); // Child 인스턴스를 참조하기 때문에 Child의 메서드가 실행된다. System.out.println(); System.out.println("child.z = " + child.z); // 인스턴스 변수인 z는 참조변수의 타입에 따라서 달라진다. child.method(); // Child 인스턴스를 참조하기 때문에 Child의 메서드가 실행된다. } // main } // BindingTest
5. 매개변수의 다형성
- 참조형 매개변수는 메서드 호출시, 자신과 같은 타입 또는 자손타입의 인스턴스를 넘겨줄 수 있다.
class Product { int price, bonusPoint; public Product(int price) { this.price = price; bonusPoint = (int) (price / 10.0); // 보너스 점수는 제품가격의 10% } // Product todtjdwk } // Product class Tv extends Product { Tv() { super(100); // 조상클래스의 생성자 Product(int price)를 호출 } public String toString() { return "TV"; } } // Tv extends Product class Computer extends Product { public Computer() { super(200); } public String toString() { return "Computer"; } } // Computer extends Product class Buyer { int money = 1000; // 소유 금액 int bonusPoint = 0; // 보너스 포인트 void buy(Product p) { if(money < p.price) { System.out.println("잔액이 부족하여 물건을 살 수 없습니다."); return; } // if money -= p.price; bonusPoint += p.bonusPoint; System.out.println(p + " 을 / 를 구입하셨습니다."); } } // Buyer public class PolyArgumentTest { public static void main(String[] args) { Buyer buyer = new Buyer(); Tv tv = new Tv(); Computer computer = new Computer(); buyer.buy(tv); System.out.println("현재 남은 돈은 : " + buyer.money + " 만원 입니다."); System.out.println("현재 보너스 점수는 : " + buyer.bonusPoint + " 점 입니다."); System.out.println(); buyer.buy(computer); System.out.println("현재 남은 돈은 : " + buyer.money + " 만원 입니다."); System.out.println("현재 보너스 점수는 : " + buyer.bonusPoint + " 점 입니다."); } // main } // PolyArgumentTest
'Java > Java SE' 카테고리의 다른 글
Java 인터페이스(interface) (2) | 2013.08.07 |
---|---|
Java 추상클래스(abstract class) (0) | 2013.08.07 |
Java 제어자(modifier), 접근 제어자(access modifier) (0) | 2013.08.06 |
Java super, super() (0) | 2013.08.06 |
Java 오버라이딩(overriding) (0) | 2013.08.05 |