ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [자바] 다형성
    자바 2022. 8. 6. 13:13
    728x90
    다형성 - 하나의 메소드나 클래스가 있을때 다양한 방법으로 동작하는 것을 의미한다

     

    다형성의 쉬운 예제는 오버로딩이다. ( 같은 이름 동작 방법 )

    class O {
        public void a(int param) {
            System.out.println(param);
        }
        public void a(String param) {
            System.out.println(param);
        }   
    }
    
    public class polyDemo {
        public static void main(String[] args) {
            O o = new O();
            o.a(10);
            o.a("ten");
        }
    }

     

    클래스와 다형성

    class A {
        public String x() {
            return "x";
        }
    }
    
    class B extends A {
        // 오버라이딩 -> 부모클래스보다 우선순위가 높다
        public String x() { return "B.x"; }
        public String y() {
            return "y";
        }
    }
    
    public polyDemo {
        public static void main(String[] args) {
            A obj = new B(); // B의 인스턴트가 A의 형태를 한다 
            // obj의 데이터 타입은 A 이다
            obj.x(); 
            obj.y(); // 얘 때매 오류남
            // obj.x(); -> x가 아닌 B.x가 출력된다
        }
    }

     

    여기에서 알아야 할 것

    1. 어떤 클래스를 인스턴스화 할때, 인스턴스를 담는 변수의 데이터 타입은 그 클래스(B)가 될수 있고, 부모클래스(A)가 될 수 있다 
    효과 ) 인스턴스가 부모클래스인 A처럼 동작을 할 수 있다.
    쓰는 이유) 오버라이딩하면 부모가 아닌 오버라이딩한 메소드가 있는 클래스의 메소드가 호출된다 ( B )

     

     

    실전예제

    부모클래스데이터타입 참주변수 = new 자식클래스데이터타입

     

    abstract class Cal {
        int left, right
        public void setOprands(int left, int right) {
        ...
        }
    }
        
        
    public class CalDemo {
        public static void main(String[] args) {
            // 다형성 추가 x
            CalPlus c1 = new CalPlus();
            // 다형성 추가 o
            Cal c1 = new CalPlus();
            
            c1.setOprands(10,20);
            c1.run(); // sum, avg메소드
            
            // 다형성 추가x
            CalMinus c2 = new CalMinus();
            // 다형성 추 가 o
            Cal c1 = new CalMinus();
            
            c2.setOprands(10,20);
            c2.run();
        }
    }
    
    
    // 조금더 다형성 추가
    abstract class Cal {
        int left, right
        public void setOprands(int left, int right) {
        ...
        }
    }
        
        
    public class CalDemo {
        public static void execute(Cal cal) {
            cal.run(); // 부모클래스의 sum, avg 메소드를 실행시켜준다
        }
        
        /*다형성 추가 x -> 코드 중복
        public static void execute(CalPlus cal) {
            cal.run(); // 부모클래스의 sum, avg 메소드를 실행시켜준다
        }
        public static void execute(CalMinus cal) {
            cal.run(); // 부모클래스의 sum, avg 메소드를 실행시켜준다
        }
        public static void main(String[] args) {
            CalPlus c1 = new CalPlus();
            CalMinus c1 = new CalMinus();
        }
        */
    
        public static void main(String[] args) {
            Cal c1 = new CalPlus();
            c1.setOprands(10,20);
            
            Cal c1 = new CalMinus();
            c2.setOprands(10,20);
            
            execute(c1);
            execute(c2);
        }
    }

     

    인터페이스와 다형성

    기본 예시 코드

    interface I {}
    class C implements I {}
    public class polyDemo {
        public static void main(String[] args) {
             I obj = new C();
        }
    }

     

    설명

    클래스 C가 인스턴스화가 될때 데이터 타입이 I 가 될 수 있는 이유는 C가 I를 구현하기 때문이다.

     

    new 예시

    interface I2 {
        public String A();
    }
    
    interface I3 {
        public String B();
    }
    
    class D implements I2, I3 {
        public String A() {
            return "A";
        }
        public String B() {
            return "B";
        }
    }
    
    public class polyDemo {
        public static void main(String[] args) {
            D obj = new D(); // ( 모든 기능을 쓰고 싶다면 이렇게 해야함 )
            I2 objI2 = new D(); // 특정 기능만 사용하겠다
            I3 objI3 = new D();
            
            obj.A(); // class D를 가져오기에 모두 사용 가능 
            obj.A();
            
            objI2.A(); // I2는 A메소드만, B호출시 에러
            objI3.B();
        }
    }

     

    쉬운 예시

    개발자를 고용하는데 있어서 특정 기능 ( 코딩을 하는 스타일 ) 이 궁금하지, 모든 기능 ( 코딩 스타일 + 가족관계 ) 모두가 필요한건 아니다.

     

    위의 설명 바탕의 코드

    interface father{}
    interface mother{}
    interface beliver{}
    interface programmer{
        public void coding();
    }
    
    class Steve implements father, programmer, believer {
        public boid coding() {
            System.out.println("fast");
        }
    }
    
    class Rachel implements mother, programmer {
        public boid coding() {
            System.out.println("elegance");
        }
    }
    
    public class workspace {
        public static void main(String[] args) {
             progrmmer employee1 = new Steve();
             progrmmer employee2 = new Rachel();
             
             employee1.coding();
             employee2.coding();
         }
    }

     

    구체적으로, 조상클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있도록 한다.

     

    Tv t = new Tv();
    CaptionTv c = new CaptionTv();

    지금까지는 생성된 인스턴스를 다루기 위해서는 인스턴스의 타입과 일치하는 타입의 참조변수만을 사용했다.

    즉, Tv 인스턴스를 다루기 위해서는 Tv타입의 참조변수를 사용하고, CaptionTv 인스턴스를 다루기 위해서는 CaptionTv타입의 참조변수를 사용했다.

     

    Tv t = new CaptionTv();

    하지만, 상속의 경우에는 조상 클래스 타입의 참조변수로 자손 클래스의 인스턴스를 참조가 가능하다.

     

     

    주의!

    CaptionTv c = new CaptionTv();
    Tv t = new CaptionTv();

    실제 인스턴스가 CaptionTv타입이라 할지라도, 참조변수 t로는 CaptionTv인스턴스의 모든 멤버를 사용할 수 없다. 

    ( CaptionTv 인스턴스 중에서 Tv 클래스의 멤버들 ( 상속받은 멤버포함 ) 만 사용이 가능하다. CaptionTv의 것은 사용 불가능 )

    -> Tv : power(), power, channel, channelUp(), channelDown()

    -> CaptionTv : power(), power, channel, channelUp(), channelDown(), text, cpation()

    여기서는 text랑 caption() 사용이 불가능

     

    둘 다 같은 타입의 인스터스지만 참조변수의 타입에 따라 사용할 수 있는 멤버 개수가 다르다.

     

    조상타입의 참조변수로 자손타입의 인스턴스를 참조할 수 있다.
    반대로 조상타입의 참조변수로 조상타입의 인스턴스를 참조할 수 없다.

     

    '자바' 카테고리의 다른 글

    [자바] Youtub Tutorial 게임을 만들면서 정리한 점 ( 주석 및 정리 )  (1) 2022.09.19
    [자바] 참조  (0) 2022.08.06
    [자바] 인터페이스  (0) 2022.08.05
    [자바] final  (0) 2022.08.05
    [자바] abstract 추상  (0) 2022.08.05
Designed by Tistory.