여러 가지 형태를 가질 수 있는 능력
자바는 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록 하여 프로그램적으로 구현
= 조상 클래스 타입의 참조 변수로 자손 클래스의 인스턴스를 참조할 수 있도록 하였다는 것
예시)
class Tv {
boolean power;
int channel;
void power() {
power = !power;
}
void channelUp() {
++channel;
}
void channelDown() {
--channel;
}
}
class CaptionTv extends Tv {
String text;
void caption() {
// ...
}
}
CaptionTv c = new CaptionTV();
Tv t = new CaptionTv();t는 CaptionTV 인스턴스의 모든 멤버를 사용할 수 없다. CaptionTv 인스턴스 중 Tv 클래스의 멤버(상속받은 멤버 포함)만 사용 가능.t는 t.text 혹은 t.caption()을 사용할 수 없다. CaptionTV c = new Tv(); //불가능!instanceof()로 참조변수가 참조하고 있는 실제 인스턴스 타입 확인하는 것이 안전instanceof 연산자참조변수 instanceof 타입(클래스명)package main.java.polymorphism;
public class InstanceofTest {
public static void main(String[] args) {
FireEngine fe = new FireEngine();
if (fe instanceof FireEngine) {
System.out.println("This is a FireEngine instance.");
}
if (fe instanceof Car) {
System.out.println("This is a Car instance.");
}
if (fe instanceof Object) {
System.out.println("This is an Object instance.");
}
System.out.println(fe.getClass().getName());
}
}
class Car {}
class FireEngine extends Car {}
// This is a FireEngine instance.
// This is a Car instance.
// This is an Object instance.
// main.java.polymorphism.FireEngine
instanceof 연산 외에 조상 타입의 instanceof 연산에도 true를 결과로 얻음 -> 검사한 타입으로의 형변환을 해도 아무런 문제 x!참조변수.getClass().getName() : 참조변수가 가리키고 있는 인스턴스의 클래스 이름을 문자열(String)으로 반환클래스이름.메서드()로 호출해야 함.public class BindingTest {
public static void main(String args[]) {
Parent p = new Child();
Child c = new Child();
System.out.println("p.x = " + p.x); // p.x = 100
p.method(); // Child Method
System.out.println("c.x = " + c.x); // c.x = 200
c.method(); // Child Method
}
}
class Parent {
int x = 100;
void method() {
System.out.println("Parent Method");
}
}
class Child extends Parent {
int x = 200;
void method() {
System.out.println("Child Method");
}
}
참조변수 p, c 모두 Child 인스턴스를 참조 + Parent와 Child는 서로 같은 멤버들을 정의하고 있음
p로 Child 인스턴스의 멤버들을 사용했을 때,method()는 실제 인스턴스의 타입인 Child 클래스에 정의된 메서드가 호출x는 참조 변수 p의 타입에 따라 Parent 클래스에 정의된 변수가 호출웬만하면 멤버변수를 접근 제한시켜야 하는 이유
public class BindingTest3 {
public static void main(String[] args) {
Parent p = new Child();
Child c = new Child();
System.out.println("p.x = " + p.x); // (1)
p.method(); // (2)
System.out.println();
System.out.println("c.x = " + c.x); // (3)
c.method(); // (2)
}
}
class Parent {
int x = 100;
void method() {
System.out.println("Parent Method");
}
}
class Child extends Parent {
int x= 200;
void method() {
System.out.println("x = " + x); // (4)
System.out.println("super.x = " + super.x);
System.out.println("this.x = " + this.x);
}
}
실행 결과
p.x = 100 // (1)
x = 200 // (2)
super.x = 100
this.x = 200
c.x = 200 // (3)
x = 200 // (2)
super.x = 100
this.x = 200
p가 조상 타입이므로 조상 클래스 Parent의 멤버변수 x가 호출됐다.Child의 method()가 실행되었다.c가 자손 타입이므로 자손 클래스 Child의 멤버변수 x가 호출됐다.x는 this.x와 동일하다.주로 멤버변수들은 private으로 접근을 제한, 외부에서는 메서드를 통해서만 접근할 수 있도록 함. 위의 예제와 같이 인스턴스변수에 직접 접근하면 참조변수의 타입에 따라 사용되는 인스턴스변수가 달라질 수 있으니 주의.
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(200); }
public String toString() { return "Computer"; }
}
class Buyer {
int money = 1000;
int bonusPoint = 0;
void buy(Product p) { // (1)
if (money < p.price) {
System.out.println("잔액 부족");
return;
}
money -= p.price;
bonusPoint += p.bonusPoint;
System.out.println(p + "을/를 구입하셨습니다.");
}
}
public class PolyArgumentTest1 {
public static void main(String[] args) {
Buyer b = new Buyer();
b.buy(new Tv());
b.buy(new Computer());
System.out.println("현재 남은 돈은 " + b.money + "만원입니다.");
System.out.println("현재 보너스점수는 " + b.money + "점입니다.");
}
}
Product 타입의 참조변수 설정 -> Product 클래스의 자손타입이라면 어느 것이나 매개변수로 받아들일 수 있다.buy() 메서드가 필요했을 것.조상 타입의 참조변수 배열 사용 -> 공통의 조상을 가진 서로 다른 종류의 객체를 배열로 묶어서 다룰 수 있음.
Product p[] = new Product[3];
p[0] = new Tv();
p[1] = new Computer();
p[2] = new Audio();
or 묶어서 다루고 싶은 객체들의 상속관계를 따져서 가장 가까운 공통조상 클래스 타입의 참조변수 배열을 생성, 객체들을 저장
Vector 클래스
Object 타입의 배열 가지고 있음. 이 배열에 객체 추가/제거 가능
소중한 정보 감사드립니다!