본문 바로가기
JAVA

[JAVA] Chapter 11. Inheritance (3)

by varcode 2023. 7. 15.
반응형

① Polymorphism
상속과 Method Overriding의 개념을 잘 조합하면, 다형성을 이해할 수 있다.
가장 기본 형태인 rv.m()에서, 상속이 걸려있다면 reference variable(rv)은 최상위 Super class로 고정한다. 이렇게 하면, 나중에 Sub class가 만들어지더라도 rv로 해당 클래스의 인스턴스를 참조할 수 있다. 또한 method overriding이 걸려있다면 method(m) Sub Class의 메서드로 고정된다.
, rv.m()라는 코드는 바뀌지 않는데 Overriding된 메서드의 body가 다르기 때문에 인스턴스마다 다른 결과가 나온다. 이것이 한 객체가 여러 개의 형태로 나타날 수 있는 성질인 Polymorphism, 다형성이다.

어떤 언어가 객체 지향이 맞는지 확인할 때 가장 먼저 확인하는 것이 다형성을 지원하는지의 여부이다. 객체지향의 패러다임을 정확히 이해하고 있다면 똑같은 문제를 만났을 때 설계가 비슷하게 나오기 때문에 코드가 비슷하게 나온다. 따라서 설계를 제대로 하면 코드를 확장하는 자리가 결정이 되기 때문에 유지 보수가 쉬워진다.

class Car {
    int velocity;
    public void Car(int velocity){
        this.velocity = velocity;
    }
    public void speedUp() {}
}

class Accent extends Car {
    int velocity;
    public void speedUp() {
        velocity + 1;
    }
}

class Sonata extends Car {
    int velocity;
    public void speedUp() {
        velocity + 2;
    }
}

class Veloster extends Car {
    int velocity;
    public void speedUp() {
        velocity + 3;
    }
}

public class main {
    public void static main(String[] args){
        Scanner sc = new Scanner(.in);
        int num = sc.parseInt();
        switch(num){
            case 1:
                Car myCar = new Accent();
                break;
            case 2:
                Car myCar = new Sonata();
                break;
            case 3:
                Car myCar = new Veloster();
                break;
        }
        myCar.speedUp();
    }
}

위는 다형성을 잘 보여주는 예시로, 여러 3개의 클래스가 Car 클래스를 상속받고 있다. 각 클래스는 speedup 메서드를 overriding 하여 각각의 특성을 새롭게 정의하고 있다.

main에서는 선택문을 통해 어떤 차를 선택할 것인지를 입력받는다. 선택문 안에서는 인스턴스만 생성하고, 선택문을 나가서 myCar.speedUP()이라는 동일한 코드로 여러 클래스를 조작할 수 있는 것이다. 프로그램이 확장되더라도 switch case만 추가하면 되기 때문에 유지 보수가 편해진다.

 

② 추상화된 메서드
상속의 개념을 배운 현재, 우리는 현실적인 문제에 마주칠 수 있다. 우리 회사 서버에 들어있는 코드는 과연 제대로 설계되어 있을까?
만일 코드를 살펴보았을 때 상속이 걸려있는데 overriding이 안 걸려있다면,
다형성을 사용할 수 없다. 클래스마다 method 이름이 다르다면 모든 method 이름을 외우고 있어야 한다. method 이름이 다른데 공통적으로 들어가는 기능이 있다면, 상속을 건드려서 다형성을 만드는 대신 추상화된 메서드를 통해 다형성을 사용할 수 있다.

class BasicPackage {
    public void basicPack() {}
}

class IntermediatePackage extends BasicPackage {
    public void interPack() {}
}

class LuxuryPackage extends IntermediatePackage {
    public void luxPack() {}
}

public class AbstractionMethod {
    public static void main(String[] args) {
        BasicPackage bp = new BasicPackage();
        BasicPackage ip = new IntermediatePackage();
        BasicPackage lp = new LuxuryPackage();
        
        pack(bp);
        pack(ip);
        pack(lp);
    }
    
    public static void pack(BasicPackage bpk) {
        if (bpk instanceof LuxuryPackage) ((LuxuryPackage)bpk).luxPack();
        else if (bpk instanceof IntermediatePackage) ((Intermediate)bpk).interPack();
        else bpk.basicPack();
    }
}

main method의 pack 호출 부분을 살펴보면, 같은 클래스 내부에 있는 이름이 같은 메서드에 대해 다른 파라미터로 호출하고 있는 것을 볼 수 있다. 이를 바탕으로 method overloading을 사용하고 있음을 알 수 있다. 그렇다면 서로 다른 인자를 가진 pack method3개가 필요한데, 위의 코드에서는 하나밖에 없다. 현업에서는 method overloading을 기피하는 경향이 있기 때문에 추상화된 메서드를 사용하여 overloading을 피할 수 있다.
pack method
를 살펴보면, 세 가지 클래스의 인스턴스를 모두 인자로 받을 수 있어야 하기 때문에, 최상위 super classBasicPackage로 인자를 받은 것을 확인할 수 있다.

instanceof는 객체가 특정 클래스의 인스턴스인지 확인하는 데 사용되는 연산자로, object instance of Class의 형태로 사용되며 true/false를 반환한다. ObjectClass의 인스턴스이거나 해당 인터페이스를 구현한 경우 true를 반환하고, 그렇지 않은 경우 false를 반환한다. , instanceof 뒤의 type이 앞의 type과 같거나 super 일 때 true를 반환한다.

pack(bp)에서 bpk BasicPackage class의 인스턴스이므로 첫 번째 조건문은 false, 두 번째 조건문도 false, 마지막 조건문에서 true이므로 bpk.basicPack()이 호출된다. 같은 방식으로 pack(ip)에서 bpk IntermediatePackage의 인스턴스이므로 두 번째 조건문이 true이고, Super Classreference variableSub class의 메서드를 직접 호출할 수 없기 때문에 형 변환으로 호출했음을 확인할 수 있다.

이렇게 추상화된 메서드를 구현해놓으면, 추후에 다른 포장 패키지가 생기더라도 조건문만 추가로 만들어주면 된다. 한 가지 주의할 점은 상속이 걸려있는 순서의 역순으로 조건문의 순서를 맞춰주어야 하기 때문에 추가할 것이 있다면 조건문을 아래가 아닌 위에 붙여야 한다.

추상화된 메서드는 단기적으로 class 구조를 바꾸지 않고 다형성 효과를 낼 수 있다는 장점이 있다.

반응형

'JAVA' 카테고리의 다른 글

[JAVA] Chapter 12. Abstract & Interface (2)  (0) 2023.07.17
[JAVA] Chapter 12. Abstract & Interface (1)  (0) 2023.07.16
[JAVA] Chapter 11. Inheritance (2)  (0) 2023.07.14
[JAVA] Chapter 11. Inheritance (1)  (0) 2023.07.13
[JAVA] Chapter 10. Array  (0) 2023.07.12

댓글