Programming Lang/Java

[Java] Polymorphism (작성중입니다)

haema_dev 2022. 9. 11. 00:45

다형성이란?

polymorphism (다형성)
a word or phrase that is used with another word or phrase to limit or add to its meaning
그 의미를 제한하거나 더하기 위해 다른 단어나 구와 함께 사용되는 단어나 구

 

 

다형성

List<Integer> list = new ArrayList<Integer>();
Map<String, Object> map = new HashMap<String, Object>();
  • 다른 타입으로 객체 생성
  • 조상클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있는 것

 

다형성의 조건

1. 상속 관계일 것

class AirConditional {}
class SmartTv extends Tv{ }
class Tv { }

class Main {
    public static void main(String[] args) {
        /**
         * SmartTv class 는 Tv class 를 상속받았다.
         * 자손클래스에서 replay() 라는 메소드를 추가해주었다. */

        Tv tv1 = new SmartTv();
        //tv1.replay();
        //자손클래스 메소드를 부모클래스가 사용하려고 할 시, 에러 : Cannot resolve method 'replay' in 'Tv'

        //Tv tv2 = (Tv)new AirConditional();
        //상속관계 아닐 시, 형변환 에러 : Cannot cast from AirConditional to Tv
    }
}
  • 모든 인스턴스 사용 불가
  • 참조변수의 타입에 따라 사용할 수 있는 멤버의 갯수가 달라진다

 

상속을 받게 되면 자손클래스에서는 부모클래스의 모든 것을 사용할 수 있지만, 그 반대는 불가능하다.

상속의 주체인 부모클래스는 자손클래스에서 생성한 것을 사용할 수 없다.

그러므로 타입에 따라 사용할 수 있는 멤버의 갯수도 다르다.

 

2. 형변환은 넓은 범위여야할 것

SmartTv smart = new Tv();
  Case to '~~'


SmartTv smart = (SmartTv) new Tv();
  ClassCastException

형변환은 메모리 범위를 넓혀줄 때는 가능하지만 그 반대는 되도록 사용해서는 안 된다.

첫 번째와 같이 작성을 한다면 컴파일 에러가 발생한다.

두 번째와 같이 작성하면 컴파일 에러는 사라지지만, 런타임 시에 에러 메시지가 표시된다.

 

instanceof 연산자

  • 참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아보기 위함
  • true/false 결과를 뱉으므로 주로 조건문에 사용됨
  • true : 검사한 타입으로 형변환 가능
public class InstanceofTest {

   public static void main(String args[]) {
   
      FireEngine fire = new FireEngine();

      if(fire instanceof FireEngine) {
         System.out.println("This is a FireEngine instance.");
      }

      if(fire instanceof Car) {
         System.out.println("This is a Car instance.");
      }
      
      if(fire instanceof Object) {
         System.out.println("This is an Object instance.");
      }
   }
}

 

다형성의 특징

class ElectronicProduct {
    public ElectronicProduct() { }
    void printMethod() {
        System.out.println("electronicProduct Method");
    }
}

class Pc extends ElectronicProduct {
    public Pc() { }
    void printMethod() {
        System.out.println("pc Method");
    }
}
class Tv extends ElectronicProduct {
    public Tv() { }
    void printMethod() {
        System.out.println("tv Method");
    }
}

class Main {
    public static void main(String[] args) {
        /**
         * Pc class 와 Tv class 는 ElectronicProduct class 를 상속받았다. */

        ElectronicProduct electronicProduct = new ElectronicProduct();
        ElectronicProduct Pc = new Pc();
        ElectronicProduct Tv = new Tv();
        
        electronicProduct.printMethod();
        Pc.printMethod();
        Tv.printMethod();
    }
}
결과
electronicProduct Method
pc Method
tv Method

선언한 객체 타입이 ElectronicProduct 임에도 불구하고 호출하는 method 는 제 각각 달랐다.

즉, 형변환을 하더라도 실제 호출되는 것은 원래 객체에 있는 메소드가 호출된다는 의미이다.

 

 

더보기

참고 자료 : 자바의 정석, 자바의 신

(+개인 생각)