클래스에서 자동 타입 변환은 다음과 같은 조건에서 일어난다.
부모 클래스 변수 = 자식 클래스 타입
일때 자동 타입 변환이 일어난다.
예를 들어 다음과 같은 상황이라 가정하자
이와 같은 상황일때
Cat cat = new Cat();
Animal ani = cat;
또는
Animal ani = new Cat();
와 같이 타입 변환으로 객체를 생성할 수 있다.
위와 같은 상황에서 메모리 상태를 그림으로 묘사하면
와 같이 생성이 된다. 즉 변수 타입만 다를뿐 동일한 객체를 참조하고 있다.
위와 같은 상태에선
B b= new B();
C c= new C();
D d= new D();
E e= new E();
A a1 = b; (가능)
A a2 = c; (가능)
A a3 = d; (가능)
A a4 = e; (가능)
B a1 = d; (가능)
C c1 = e; (가능)
B b3 = e; (불가능)
C c2 = d; (불가능)
을 보여준다. 이유는 상속관계가 아닌 것을 보여주고, 바로 위의 부모가 아니더라도 상속 계층에서 상위 타입이라면 자동 타입 변환이 일어날 수 있는 것을 보여준다.
그리고 큰 특징이 하나 있다. 아래 소스를 보자
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
class Parent { public void method1() { System.out.println("parent-method1"); } public void method2() { System.out.println("parent-method2"); } } class Child extends Parent { public void method2() //오버라이딩 { System.out.println("child-method2"); } public void method3() { System.out.println("child-method3"); //자식 메소드 } } public class ChildExample { public static void main(String[] args) { Child c = new Child(); Parent p = c; p.method1(); p.method2(); //재정의된 메소드가 호출됨 -> 다형성!! //p.method3(); 호출 불가능 } } Colored by Color Scripter |
자동 타입 변환으로 부모 = 자식; 이 되면
자식이 메소드 오버라이딩 한 내용은 그대로 접근이 가능하지만, 자식 클래스에서 정의한 자신만의 메소드는 사용할 수 없다.
왜나하면 변수 타입이 부모의 것으로 정의가 되어 있기 때문이다.
즉 이렇게 되면 부모 클래스에 선언된 필드와 메소드만 접근이 가능하다. 하지만 오버라이딩한 내용은 오버라이딩 한 것으로 호출이 된다.
여기서 다형성의 성질이 나온다.
다형성이란 동일한 타입을 사용하지만 다양한 결과가 나오는 성질이다.
예를 들어 자동차를 예로 들어보자. 자동차의 타이어는 4개이다. 이때 어떤 타이어가 고장이나면 어떤 타이어는 k타이어 어떤 타이어는 H타이어로 교체 될 수 있다. 즉 같은 타이어지만 각 타이어 회사마다 다르게 적용되는 것처럼 다양한 결과가 나오게 된다.
1 2 3 4 5 6 7 8 9 10 11 |
class car{ Tire frontLeftTire = new Tire("앞왼쪽", 6); Tire frontRightTire = new Tire("앞오른쪽", 2); Tire backLeftTire = new Tire("뒤왼쪽", 3); Tire backRightTire = new Tire("뒤오른쪽", 4); } Car car = new Car(); car.frontLeftTire = new HTire(); car.frontRightTire = new HTire(); |
위와 같이 말이다.
이것이 자바다 라는 책에 매우 좋은 예제가 있어 여기다 풀어보았다.
클래스는 Tire, Car, HankookTire, KumhooTire, CarExample 5개이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
public class CarExample { public static void main(String[] args) { Car car = new Car(); for(int i = 1 ; i<= 5 ; i++) { int problemLocation = car.run(); switch(problemLocation) { case 1: System.out.println("앞왼쪽 한국 타이어로 교체"); car.frontLeftTire = new HankookTire("앞왼쪽", 15); break; case 2: System.out.println("앞오른쪽 금호 타이어로 교체"); car.frontRightTire = new KumhoTire("앞오른쪽", 13); break; case 3: System.out.println("뒤 왼쪽 한국 타이어로 교체"); car.backLeftTire = new HankookTire("뒤왼쪽", 14); break; case 4: System.out.println("뒤오른쪽 금호타이어로 교체"); car.backRightTire = new KumhoTire("뒤오른쪽", 13); break; } System.out.println("----------------------------"); } } } public class Car { Tire frontLeftTire = new Tire("앞왼쪽", 6); Tire frontRightTire = new Tire("앞오른쪽", 2); Tire backLeftTire = new Tire("뒤왼쪽", 3); Tire backRightTire = new Tire("뒤오른쪽", 4); int run() { System.out.println("자동차가 달립니다"); if(frontLeftTire.roll() == false) { stop(); return 1; } if(frontRightTire.roll() == false) { stop(); return 2; } if(backLeftTire.roll() == false) { stop(); return 3; } if(backRightTire.roll() == false) { stop(); return 4; } return 0; } void stop() { System.out.println("자동차가 멈춥니당"); } } public class HankookTire extends Tire{ public HankookTire(String location, int maxRotation) { super(location, maxRotation); } public boolean roll() { ++accumulatedRotation; if(accumulatedRotation < maxRotation) { System.out.println(location+" 한국 타이어 수명 : "+(maxRotation-accumulatedRotation)+" 회"); return true; } else { System.out.println("타이어 펑크크크크크"); return false; } } } public class KumhoTire extends Tire{ public KumhoTire(String location, int maxRotation) { super(location, maxRotation); } public boolean roll() { ++accumulatedRotation; if(accumulatedRotation < maxRotation) { System.out.println(location + " 금호 타이어 수명 "+(maxRotation-accumulatedRotation)+" 회"); return true; } else { System.out.println("타이어 펑쿠"); return false; } } } public class Tire { public int maxRotation; public int accumulatedRotation; public String location; public Tire(String location, int maxRotation) { this.location = location; this.maxRotation = maxRotation; } public boolean roll() { ++accumulatedRotation; if(accumulatedRotation < maxRotation) { System.out.println(location + " Tire 수명 : "+(maxRotation-accumulatedRotation)+" 회"); return true; } else { System.out.println(location+" 타이어 펑크!!!"); return false; } } } Colored by Color Scripter |
위 예제는 꼭 풀어보면 좋다. 정말 좋은 예제이다.
이것이 다형성의 특징이다.
'java' 카테고리의 다른 글
자바 추상 클래스, 추상 메소드, 자동 타입 변환 (0) | 2017.08.16 |
---|---|
자바 instanceof (0) | 2017.08.16 |
자바 상속과 오버라이딩, super (0) | 2017.08.16 |
자바 get, set 메소드(getter, setter) (0) | 2017.08.14 |
자바 접근 제한자(publlic, private, protected, default) (0) | 2017.08.14 |