본문 바로가기
공부/java

자바(java)의 객체의 다형성

by 샤샤샤샤 2022. 11. 29.

다형성

클래스는 하나의 객체가 여러 자료형 타입을 가질수 있는데, 이를 다형성이라고 부른다.

부모 클래스의 타입을 자식 클래스가 가질수 있다.

 

자바의 모든 클래스는 Object 라는 클래스를 상속한다. 따라서 이를 이용하면 모든 객체 타입을 전달할수 있고, 따라서 프로그래밍이 더 유연해질수 있다.

 

상속의 개념을 생각해보자. 부모(상위), 자식(하위) 클래스라고 표현해서 헷갈리기 쉽지만, 실제로는 자식 클래스가 더 큰 개념이다. 부모 클래스의 모든 특징을 계승하고, 거기에 자신만의 속성과 메소드를 추가한 것이 자식 클래스다. 굳이 표현하자면 보강형이라고 봐도 무방하다.

따라서 부모 클래스의 기능을 자식 클래스도 그대로 가지고 있기 때문에, 자식 클래스 역시 부모 클래스 타입을 가질수 있따.

 

1.업캐스팅

자식 클래스의 객체가 부모 클래스의 타입을 가지는 것을 말한다.

자식 클래스의 객체 주소를, 부모 클래스 타입으로 전환.

 

new를 통한 방법

Parent parent = new Child();
System.out.println( parent.name );

Parent는 부모 클래스고 Child는 자식 클래스다.

객체를 만들때, 객체 생성 명령어 new다음에 부모 클래스가 아닌 자식 클래스를 넣을 있다.

이경우, parent의 name 변수가 출력될 것이다.

 

형변환 연산을 통한 업캐스팅

타입을 바꿀때 우리는 ''(타입)변수'' 이런 식으로 표현한다. 클래스 역시 마찬가지다. 클래스의 객체는 그자체로 하나의 형식이 되기 때문에, 그 타입 역시 형변환 형식으로 바꿀수 있는 것이다.

        Parent parent2 = (Parent)child;
        System.out.println( parent2.name );

이런 식으로 표현한다.

이경우 역시, parent2.name는 자식클래스의 name 변수가 아닌 부모 클래스의 name를 출력한다.

 

2. 다운캐스팅

부모 클래스 타입을 자식 클래스 타입으로 전환.

부모 클래스 객체 주소를, 자식 클래스 타입으로 전환.

 

더 큰 개념인 자식 클래스에서, 더 작은 개념인 부모 클래스를 호출하려면 어떻게 할까?

일단 객체 생성은 당연하게도 불가능하다. 둘 다 포함하고 있는 변수만 호출할수 있을 뿐이다.

 

        System.out.println( ((Child)parent).name );

이 경우, 자식 클래스의 변수가 출력된다.

 

따라서 설령 부모 클래스 객체라고 하더라도, 그것이 자식 클래스를 가리킬수도 있고, 부모 클래스를 카리킬수도 있는 것이다.

 

이런 성질로 인해 오버라이딩이 가능하다.

 

**메소드 오버라이딩: 상속관계에서 부모의 메소드를 자식클래스가 재정의 하는 것을 말한다.

 

이미 부모 클래스에서 정의가 된 함수를, 다시 자식클래스에서 똑같은 이름으로 만들면서 새로운 실행문을 정의하면 된다.

이경우 

@Override 라는 표시가 붙는데, 이는 우리가 쓰는 언어가 아닌 컴파일러에게 오버라이드라는 것을 알리기 위한 일종의 표시다. 덮어쓰기라고 보면 된다.

 

class People {  //사람
    void think(){
        System.out.println("생각한다.");
    }
}
class Man extends People{ //남자<-사람
    @Override
    void think() {
        System.out.println("남자가 생각한다.");
    }
    void soccer(){
        System.out.println("축구한다.");
    }
}
class Woman extends People{//여자<-사람
    @Override
    void think() {
        System.out.println("여자가 생각한다.");
    }
    void makeUp(){
        System.out.println("화장한다.");
    }
}
public class ex88 {
    public static void main(String[] args) {

        People people = new Man();
        people.think();

오버라이딩된 위의 호출문은 무엇을 출력할까?

오버라이딩이 되지 않았다면 "생각한다"라는 출력문이 나올 터이다.

그러나 우리는 이미 오버라이딩을 통해, 업캐스팅 된 이 부모 객체는, 자식 객체에서 재정의된 함수로 덮어씌워졌다.

고로 "남자가 생각한다"라는 문장이 출력된다.

 

즉, 부모 객체 타입으로 자식 객체들에 접근한 것이다.

 

        ((Man)people).soccer(); //"축구한다."

이 경우 역시 마찬가지다.

다운 캐스팅을 통해, 부모 클래스 객체 주소를 자식 클래스 타입으로 변환해 자식 클래스의 함수를 실행시켰다.

 

//다형성 (Polymorphism:폴리모피즘)
//  : 하나의 객체가 여러 자료형 타입을 가질 수 있는 것
//  : 부모클래스의 타입이 자식클래스이 타입을 가질 수 있다.
// 사용하는 이유 : 하나의 객체타입에서 여러 타입을 가질 수 있다.
//              유연한 프로그램밍을 가능하게 해준다.
// 사용예) 자바의 모든 클래스는 Object를 상속한다.
//        최상위객체 Object타입으로 모든 객체타입을 전달할 수 있다.

class Parent{
    String name = "Parent";
    void parentMethod(){
        System.out.println("Parent 내 이름은 " + this.name);
    }
}
class Child extends Parent{
    String name = "Child";
    void childMethod(){
        System.out.println("Child 내 이름은 " + this.name);
    }
}
public class ex87 {
    public static void main(String[] args) {
        Child child = new Child();
        System.out.println( child.name );

        Parent p = new Parent();
        System.out.println( p.name );

        //업캐스팅(자식클래스의 객체가 부모클래스의 타입을 가지는 것)
        //  :자식클래스의 객체주소를 부모클래스 타입으로 전환
        //1. new를 통해서
        Parent parent = new Child(); // Child + Parent
        System.out.println( parent.name );
        //2. 형변환연산자를 통해서
        Parent parent2 = (Parent)child;
        System.out.println( parent2.name );

        //다운캐스팅(부모클래스의 타입을 자식클래스의 타입으로 전환)
        //  : 부모클래스의 객체주소를 자식클래스 타입으로 전환
        System.out.println( ((Child)parent).name );

        //                 v다운캐스팅 v 업캐스팅
        //                 +-------+--------+
        //Child클래스 객체 = | Child + Parent |
        //                 +-------+--------+

        //4가지 형태
        Parent a = new Parent(); //가능
        Child b = new Child(); //가능
        Parent c = new Child(); //가능 왜냐면 Child는 Parent를 상속!
        Parent c2 = (Parent)(new Child()); //가능 왜냐면 Child는 Parent를 상속!
        //Child d = new Parent(); //오류
    }
}
//다형성 사용 예
//다형성이란? 하나의 객체타입이 여러 객체의 타입을 가질 수 있다.
//       : 부모클래스의 객체타입으로 자식클래스의 타입(다운캐스팅) 또는
//         부모클래스의 타입(업캐스팅)을 가질 수 있다.
// Parent p는 Parent객체를 가리킬수도, Child객체를 가리킬수도 있다.
// C는 B를 상속, B는 A를 상속했다. C = C + B + A
// A objA는 C객체와 B객체와 A객체를 다 가리킬수있다.(주소값)

//메소드 오버로딩 : 확장. 매개변수를 다르게 함으로 메소드의 기능을 확장.
//               같은 이름의 메소드가 생기는 것을 방지
//메소드 오버라이딩 : 재정의. 상속관계에서 부모클래스의 메소드를 자식클래스에서
//                재정의한다.
class People {  //사람
    void think(){
        System.out.println("생각한다.");
    }
}
class Man extends People{ //남자<-사람
    @Override
    void think() {
        System.out.println("남자가 생각한다.");
    }
    void soccer(){
        System.out.println("축구한다.");
    }
}
class Woman extends People{//여자<-사람
    @Override
    void think() {
        System.out.println("여자가 생각한다.");
    }
    void makeUp(){
        System.out.println("화장한다.");
    }
}
public class ex88 {
    public static void main(String[] args) {
        //다형성을 이용하면, 부모객체타입으로
        //모든 자식객체들에 접근할 수 있다는 장점이 있다.
        //1. 업캐스팅 
        //   자식클래스의 객체주소를 부모클래스 타입으로 변환
        People people = new Man();
        people.think(); //"남자가 생각한다." <- 메소드 오버라이딩

        //2. 다운캐스팅
        //  부모클래스의 객체주소를 자식클래스 타입으로 변환
        ((Man)people).soccer(); //"축구한다."

        //  V 다운캐스팅
        //  +--------+------------+
        //  |        V 업캐스팅--+ |
        //  | Man    |  People  | |
        //  |        +----------+ |
        //  +--------+------------+
        
        //다형성을 이용한 객체 전달
        //People객체타입은 Man객체도 전달 가능하고,
        //               Woman객체도 전달 가능하다. 유연함.
        myFunc( new Man() );
        myFunc( new Woman() );
    }//main()
    static void myFunc( People p ){
        //p는 Man인가? Woman인가? People인가?
        //객체 타입을 확인하는 연산자 : instance of 연산자
        //맞으면 true, 틀리면 false
        if( p instanceof Man ) {
            System.out.println("Man클래스입니다.");
            ((Man)p).soccer();
        }
        if( p instanceof Woman ){
            System.out.println("Woman클래스입니다.");
            ((Woman)p).makeUp();
        }
    }
}//class

 

'공부 > java' 카테고리의 다른 글

14일차 복습  (0) 2022.12.01
13일차  (0) 2022.11.30
자바(java)의 클래스  (1) 2022.11.28
자바(java)의 함수 종류  (0) 2022.11.25
자바(java) 문제 풀이 복습  (0) 2022.11.25