1. 업캐스팅(Up-casting)과 다운캐스팅(Down-casting)


# 객체의 형 변환은 반드시 상속 관계에 있는 객체끼리만 가능하다. 


1) 업캐스팅(Up-casting)

- 자식 클래스 객체를 부모 클래스 객체로 형 변환하는 것

- 묵시적 형변환: 형 변환 연산자를 생략해도 무방하다. (상속이 트리 구조로 구현되어 있기 때문이다)


2) 다운캐스팅(Down-casting)

- 부모 클래스 객체를 자식 클래스 객체로 형 변환하는 것

- 명시적 형변환: 부모 클래스의 시각에서는 여러 개의 자식 클래스가 있을 수 있으므로

다운캐스팅 시에는 반드시 형 변환 연산자를 사용해서 어떤 데이터형으로 형 변환할 것인지 명확하게 적어줘야 한다.


# 객체의 형 변환 예시





# 설명

업캐스팅 사용예: 자식 클래스인 Second obj1 객체를 부모 클래스인 First obj2로 묵시적 형 변환 

다운캐스팅 사용예: 부모 클래스인 First obj1 객체를 자식 클래스인 Second obj2로 명시적 형 변환



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
package polymorphismex;
 
class Car {
    
    String color;
    int doorNum;
    void drive() {System.out.println("주행");}
    void stop() {System.out.println("멈춤");}
}
 
class FireEngine extends Car {
    @Override
    void drive() {System.out.println("소방차 주행");}
    void water() {System.out.println("화재진압");}
}
 
class Ambulance extends Car {
    @Override
    void drive() {System.out.println("응급차 주행");}
    void siren() {System.out.println("사이렌");}
}
 
public class PolyTest02 {
    public static void main(String[] args) {
 
        Car c1 = null;
        FireEngine f1 = null;
        Ambulance a1 = null;
        
        // Up-casting 
        c1 = f1;
        c1 = a1;
        
        // Down-casting
        f1 = (FireEngine)c1;
        a1 = (Ambulance)c1;
        
        // 상속관계가 아닌 클래스간의 형변환은 불가능하다.
        // f1 = (FireEngine)a1;
        // a1 = (Ambulance)f1;
        
    }
}
cs



2. 객체끼리 비교하는 3가지 방법 


1) == 연산자

2) equals()

3) instanceof 연산자 




# == 연산자와 equals() 예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package objectex;
 
class Apple {}
 
public class ObjectTest04 {
    public static void main(String[] args) {
 
        Apple a1 = new Apple();
        Apple a2 = new Apple();
        
        System.out.println(a1);
        System.out.println(a2);
        
        System.out.println(a1 == a2);
        System.out.println(a1.equals(a2));
        
    }
}
 
# 실행 결과 
objectex.Apple@3d012ddd
objectex.Apple@6f2b958e
false
false
cs


# 설명 

Line 8~9: Singleton로 생성한 객체들이 아니기 때문에 두 객체의 비교문 Line 14~15의 결과는 false가 나오게 된다.



3. instanceof


# 연산자의 일종으로, 인스턴스(객체)와 데이터형(클래스)을 비교하는 연산자 


1) 대상 객체가 비교 클래스의 인스턴스이거나 서로 같은 지 비교하는 것 

즉, 상속 관계에 있을 경우 true를 반환하며 객체의 형 변환이 가능함을 뜻한다.




# instanceof 연산자 예시 

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
package polymorphismex;
 
class Tv {
    
    boolean power;
    int channel;
    
    void power() {power = !power;}
    void channelUp() {channel++;}
    void channelDown() {channel--; }
}
 
class CaptionTv extends Tv {
    
    String text;
    void caption() {}
}
 
class HdTv extends Tv {
    
    int hdLevel;
    void display() {}
}
 
public class PolyTest01 {
    public static void main(String[] args) {
        
        CaptionTv c = new CaptionTv();
        Tv            t = new CaptionTv();
        // CaptionTv p = new Tv();
        
        Tv           t1 = new Tv();
        CaptionTv c1 = new CaptionTv();
        HdTv       h1 = new HdTv();
        
        System.out.println("t1 instanceof Tv: " + (t1 instanceof Tv));    
        System.out.println("t1 instanceof CaptionTv: " + (t1 instanceof CaptionTv));
        System.out.println("t1 instanceof HdTv: " + (t1 instanceof HdTv));
        
        System.out.println();
        
        System.out.println("c1 instanceof Tv: " + (c1 instanceof Tv));        
        System.out.println("c1 instanceof CaptionTv: " + (c1 instanceof CaptionTv));
        // System.out.println(c1 instanceof HdTv);    
        
        System.out.println();
        
        System.out.println("h1 instanceof Tv: " + (h1 instanceof Tv));
        // System.out.println(h1 instanceof CaptionTv);
        System.out.println("h1 instanceof HdTv: " + (h1 instanceof HdTv));
        
    }
}
 
# 실행 결과
t1 instanceof Tv: true
t1 instanceof CaptionTv: false
t1 instanceof HdTv: false
 
c1 instanceof Tv: true
c1 instanceof CaptionTv: true
 
h1 instanceof Tv: true
h1 instanceof HdTv: true
cs

# 설명

Line 3~23: Tv 클래스를 CaptionTv 클래스와 HdTv 클래스가 각각 상속받고 있다. 

Line 36: t1 객체는 Tv 클래스 자체이기 때문에 true

Line 37~38: t1 객체는 CaptionTv 클래스와 HdTv 클래스의 부모 클래스이지 두 클래스에 대해 인스턴스화 한 객체가 아니기 때문에 false

Line 42: c1 객체는 Tv 클래스의 자식 클래스이므로 true

Line 43: c1 객체는 CaptionTv 클래스 자체이기 때문에 true



4. 다형성 (Polymorphism)


# 여러가지 형태를 가질 수 있는 성질

- 한 타입의 참조변수가 여러 타입의 객체를 참조할 수 있도록 하는 것 

- 오버로딩(Overloading): valueOf()


# 다형성이란 '상속 관계' 에서 성립하며,

부모클래스의 참조변수 = new 자손클래스();    (O)

자식클래스의 참조변수 = new 부모클래스();    (X)



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
package polymorphismex;
 
class Tv {
    
    boolean power;
    int channel;
    
    void power() {power = !power;}
    void channelUp() {channel++;}
    void channelDown() {channel--; }
}
 
class CaptionTv extends Tv {
    
    String text;
    void caption() {}
}
 
class HdTv extends Tv {
    
    int hdLevel;
    void display() {}
}
 
public class PolyTest01 {
    public static void main(String[] args) {
        
        CaptionTv c = new CaptionTv();
        Tv           t = new CaptionTv();
        Tv          v = new HdTv();
        
        // CaptionTv p = new Tv();
        // HdTv h = new Tv();
        
    }
}
cs

# 설명 

부모클래스 참조변수는 자식클래스로 참조할 수 있지만, 자식클래스 참조변수는 부모클래스로 참조할 수 없다.