[JAVA] 다형성

Coastby·2022년 8월 8일
0

JAVA

목록 보기
21/33

다형성

다형성 (polymorphism) 하나의 메소드나 클래스가 있을 때 이것들이 다양한 방법으로 동작하는 것을 의미한다.

overloading과 다형성

같은 이름의 메소드지만 매개변수에 따라서 다른 방식으로 실행이 되므로 오버로딩은 메소드의 다형성 중 하나이다.

클래스와 다형성

클래스 B는 클래스 A를 상속하고 있다. 이런 경우에는 클래스 B로 인스턴스를 만드는데, 데이터타입을 A (부모클래스)로 할 수 있다.

class A{}

class B extends A {}

public class PolyclassDemo {

	public static void main(String[] args) {
		A obj = new B();

	}

}

데이터타입을 A로 설정을 했더니 클래스 B의 메소드가 동작되지 않는다.

class A{
	public String x() {return "x";}
}

class B extends A {
	public String y() {return "y";}
}

public class PolyclassDemo {

	public static void main(String[] args) {
		A obj = new B();
		obj.x();
		obj.y();

	}

}

//error
The method y() is undefined for the type A

클래스 A의 메소드를 오버라이딩하는 메소드를 추가하면 결과는 오버라이딩 된 결과가 나온다.

class A{
	public String x() {return "x";}
}

class B extends A {
	public String y() {return "y";}
	public String x() {return "z";}
}

public class PolyclassDemo {

	public static void main(String[] args) {
		A obj = new B();
		//obj.x();
		//obj.y();
		System.out.println(obj.x());
	}

}

//result
z

💡 즉, 클래스 B를 클래스 A 데이터타입으로 인스턴흐화 했을 때, 상위클래스(A)에 존재하는 멤버만 하위 클래스(B)의 멤버가 될 수 있다. 그러나 하위 클래스(B)에서 오버라이딩했다면 이를 따라가게 된다.

여기서 클래스 A를 상속하는 다른 클래스 B2를 생성하고 x() 메소드에 오버라이딩을 한다. 그리고 같은 방법으로 인스턴스화한다.

두 인스턴스의 x()를 호출한 결과는 서로 다르다.

class A{
	public String x() {return "x";}
}

class B extends A {
	public String y() {return "y";}
	public String x() {return "z";}
}

class B2 extends A {
	public String x() {return "zz";}
}

public class PolyclassDemo {

	public static void main(String[] args) {
		A obj = new B();
		A obj2 = new B2();
		//obj.x();
		//obj.y();
		System.out.println(obj.x());
		System.out.println(obj2.x());
	}

}

//result
z
zz

💡 이것이 상속과 오버라이딩 그리고 형변환을 이용한 다형성이다.

실전 예제

abstract class Calculator{
    int left, right;
    public void setOprands(int left, int right){
        this.left = left;
        this.right = right;
    } 
    int _sum() {
        return this.left + this.right;
    }
    public abstract void sum();  
    public abstract void avg();
    public void run(){
        sum();
        avg();
    }
}
class CalculatorDecoPlus extends Calculator {
    public void sum(){
        System.out.println("+ sum :"+_sum());
    }
    public void avg(){
        System.out.println("+ avg :"+(this.left+this.right)/2);
    }
} 
class CalculatorDecoMinus extends Calculator {
    public void sum(){
        System.out.println("- sum :"+_sum());
    }
    public void avg(){
        System.out.println("- avg :"+(this.left+this.right)/2);
    }
} 
public class CalculatorDemo {
    public static void execute(Calculator cal){
        System.out.println("실행결과");
        cal.run();
    }
    public static void main(String[] args) { 
        Calculator c1 = new CalculatorDecoPlus();
        c1.setOprands(10, 20);
         
        Calculator c2 = new CalculatorDecoMinus();
        c2.setOprands(10, 20);
         
        execute(c1);
        execute(c2);
    }
}

다른 클래스를 인스턴스화 했지만 같은 상위 클래스를 상속받은 점을 이용하여 데이터타입을 통일화할 수 있다. 그리고 다른 클래스이기 때문에 다른 행동을 할 수 있다.

또한 데이터타입을 통일함으로써 이를 사용하는 메소드에서 (execute())상위 클래스의 공통된 메소드 (run())를 가지고 있다는 것을 보장받을 수 있다.

인터페이스와 다형성

인터페이스는 다형성을 구성하는데 있어서 중요한 도구이다.

인터페이스를 구현하는 클래스로 인스턴스화할 때 인터페이스를 데이터타입으로 할 수 있다.

interface I {}

class C implements I {}

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

클래스가 사용할 때 하나의 인터페이스의 기능만 사용하고 싶다면 데이터타입으로 그 인터페이스를 지정한다면 다른 인터페이스 관련 메소드는 사용하지 않아도 된다.

다른 기능은 건드리지 못하도록 방지할 수도 있다.

하나의 인터페이스를 사용하는 여러 클래스들에서 각각의 인스턴스를 하나의 인터페이스 데이터타입으로 묶을 수도 있다.

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 PolymorphismDemo3 {
    public static void main(String[] args) {
        D obj = new D();
        I2 objI2 = new D();
        I3 objI3 = new D();
         
        obj.A();
        obj.B();
         
        objI2.A();
        //objI2.B();
         
        //objI3.A();
        objI3.B();
    }
}

이해

다른 기능을 하는 인스턴스를 생성하면서 이들을 어떤 역할로 모으고 싶을 때

같은 이름을 가지고 있지만 다른 기능을 할 수 있도록 하기위해

비유가 너무나 잘 이해된다

https://www.youtube.com/watch?v=wxthfU10x2U&list=PLuHgQVnccGMCeAy-2-llhw3nWoQKUvQck&index=120

profile
훈이야 화이팅

0개의 댓글