반응형
타입 변환과 다형성
같은 타입이지만 실행 결과가 다양한 객체 대입이 가능한 성질입니다. 상위 타입에서는 모든 하위의 객체가 대입이 가능하며, 하위 타입은 자동으로 상위 타입으로 타입 변환이 됩니다.
자동 타입변환은 바로 위의 상위 클래스가 아니더라도 상속계층의 상위이면 자동으로 타입 변환이 가능합니다.
예시. 클래스가 각각 Amom, B, C, D, E 가 있을경우
public class Amom {
}
public class B extends Amom {
}
public class C extends Amom {
}
public class D extends B {
}
public class E extends C {
}
public class AmomExample {
public static void main (String[] args) {
B b = new B();
C c = new C();
D d = new D();
E e = new E();
Amom a1 = b;
Amom a2 = c;
Amom a3 = d;
Amom a4 = e; // Amom은 상속 계층의 상위이기 때문에 BCDE 모두 사용가능.
B a = d; // B의 상속 계층 D 사용가능
// B b = e; // B의 상속계층이 아닌 E는 사용 불가.
C b1 = e; // C의 상속 계층 E는 사용가능
// C b2 = d; // C의 상속계층이 아닌 D는 사용 불가.
}
}
필드의 다형성
상위(부모) 메소드보다 파생 or하위(자식) 메소드가 더욱 우수할 수 있다면 @Override(재정의)하여, 메소드의 실행 내용을 변경함으로써 @Override(재정의)된 파생 or하위(자식) 메소드를 상위(부모) 타입으로 변환할 수 있습니다..
예시
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 + "Trie수명: " + (maxRotation - accumulatedRotation) + " 회");
return true;
} else {
System.out.println(" *** " + location + " 펑크***");
return false;
}
}
}
public class Ktire extends Tire {
//필드
//생성자
public Ktire(String location, int maxRotation) {
super(location, maxRotation);
}
//메소드
@Override
public boolean roll() {
++accumulatedRotation;
if(accumulatedRotation<maxRotation) {
System.out.println(location + "Ktire수명: " + (maxRotation - accumulatedRotation) + " 회");
return true;
} else {
System.out.println("*** " + location + " 펑크***");
return false;
}
}
}
public class Car {
// 필드
Tire leftTire = new Tire("앞왼", 6);
Tire rightTire = new Tire("앞오", 1);
Tire backleftTire = new Tire("뒤왼", 2);
Tire backRightTire = new Tire("뒷오", 4);
//생성자
//메소드
int run(){
System.out.println("출발~");
if(leftTire.roll()==false) {
stop();
return 1;
}
if(rightTire.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 CarExample {
public static void main(String[] args) {
Car car = new Car();
for(int i=1; i<=10; i++) {
int TT1 = car.run();
switch(TT1) {
case 1:
System.out.println("앞왼쪽 Tire로 교체");
car.leftTire = new Tire("앞왼쪽", 3);
break;
case 2:
System.out.println("앞오른쪽 Ktire로 교체");
car.rightTire = new Ktire("앞오른쪽", 15);
break;
case 3:
System.out.println("뒷왼 Ktire로 교체");
car.backleftTire = new Ktire("뒷왼쪽", 15);
break;
case 4:
System.out.println("뒷오 Ktire로 교체");
car.backRightTire = new Ktire("뒷오른쪽", 15);
break;
}
System.out.println("********************************************");
}
}
}
하나의 배열로 객체 관리도 가능합니다.
public class Tire {
//필드
public int maxR; // 최대 회전수
public int accu; // 누적 회전수
public String location; // 타이어 위치
//생성자
public Tire (String location, int maxR) {
this.location = location;
this.maxR = maxR;
}
//메소드
public boolean roll() {
++accu;
if(accu<maxR) {
System.out.println(location + "Tire수명: " + (maxR - accu) + " 회");
return true;
} else {
System.out.println("*** " + location + " ***");
return false;
}
}
}
public class KoreanTire extends Tire {
public KoreanTire(String location, int maxR) {
super(location, maxR);
}
@Override
public boolean roll() {
++accu;
if(accu<maxR) {
System.out.println(location + "Tire수명: " + (maxR - accu) + " 회");
return true;
} else {
System.out.println("*** " + location + " ***");
return false;
}
}
}
public class Car {
//필드
Tire[] Tires = { // 하나의 배열로 객체를 관리할수있다. ex A[] As = { new..., new..., new... };
new Tire("앞왼", 4),
new Tire("앞오", 1),
new Tire("뒷왼", 2),
new Tire("뒷오", 6)
};
/* 이런식으로 A[] As = {
new A("d",1), new A("d3",1), new A("d1",1)
}; */
//메소드
int run() {
System.out.println("출발~");
for(int i=0; i<Tires.length; i++) {
if(Tires[i].roll()==false) {
stop();
return(i+1);
}
}
return 0;
}
void stop() {
System.out.println("정지~");
}
}
public class CarExample {
public static void main(String [] args) {
Car car = new Car();
for(int i=0; i<=5; i++) { // 5번 반복한다.
int lol = car.run();
if(lol !=0) { // 만일 lol즉 run이 (부정되어)! 0과 같지 않을 경우
System.out.println(car.Tires[lol-1].location+ "KoreanTire로 교체"); // car의 Tires의 값을을 -1개를 location(로케이션) 계속 돌린다. 만일 0이되면 교체라는 문구를 출력하고
car.Tires[lol-1] = new KoreanTire(car.Tires[lol-1].location, 15); // 0이된Tires를 15개를 부여하고 다시 -1씩뺸다.
}
System.out.println("-------------------------------------");
}
}
}
매개변수의 다형성
매개변수가 클래스 타입일 경우 해당 클래스의 객체 대입이 원칙이나, 하위 or파생(자식) 객체에 대입하는 것도 허용합니다.
객체 타입 확인(instanceof)
상위(부모) 타입이면 모든 하위 or파생(자식) 타입으로 강제 변환할 수 있는 것은 아닙니다 따라서 하위(자식) 타입인지 확인 후 강제 타입을 실행해야 합니다.
예시
Amom mom = new Amom();
Baby baby = new Baby();
Amom mom1 = new Baby();
Baby baby1 = new Amom(); // 불가
강제 변환
Baby baby2 = (Baby)mom1;
반응형
'Java > Java' 카테고리의 다른 글
자바[Java] 인터페이스(interface)란? 개념정리 (1) | 2021.10.14 |
---|---|
자바[Java] 추상클래스(abstract)란? 개념정리 (0) | 2021.10.14 |
자바[Java] 상속 이란? (0) | 2021.10.13 |
자바[Java] Getter와 Setter 메소드란? (0) | 2021.10.12 |
자바[Java] 상수 final란 (0) | 2021.10.12 |