ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java - 상속 다형성(다형성 활용하기:IS-A 관계, HAS-A 관계)6-2
    개발언어/JAVA 2023. 11. 3. 12:00

    다형성 활용하기

    상속은 언제 사용할까?

    VIP 고객 등급을 추가하는 문제를 다시 생각해 보자. 이미 Customer 클래스가 구현되어 있는데 추가 요구 사항이 생긴 것이다. 사실 가장 간당하게 생각해보면, 이미 Customer 클래스가 존재 하므로 여기에 추가 내용을 함께 구현할 수도 있다. Customer 클새스에 VIP 고객의 내용도 함께 구현하는 것이다. 그런데 추가 기능을 이렇게 구현하면 코드가 굉장히 복잡해진다. 그 이유는 일반 등급 고객이 사용하지 않는 속성(상담원ID,할인율 등)뿐만 아니라 VIP 고객만을 위한 서비스 내용까지 추가 해야 하기 때문이다. 

    if(customerGrade == "VIP"){ //할인해 주고, 적립도 많이 해주고
    }
    else if(customerGrade == "Gold"){ //할인해 주고, 적립은 적당히
    }
    else if(customerGrade == "SILVER"){ //적립만 해준다.
    }

     

    고객 등급에 따라 다르게 구현해야 하기 때무에 if-else if-else문을 사용한다. calcPrice()메서드뿐 아니라 여러 다른 메서드에서도 등급에 따라 다른 구현이 필요하다면 클래스 전체에서 이러한 if-else if-else문이 많이 사용된다. 이런 경우 고객의 등급이 하나라도 추가되거나 삭제 되면 유지 보수가 매우 복잡해진다.

     

    상속을 항상 사용하는 것이 좋을까?

    당연히 그렇지 않다. 'IS-A 관계(is a relationship; inheritance)'라는 용어가 있다. IS-A 관계란 일반적인 개념과 구체적인 개념의 관계이다. 즉 '사람은 포유류다'와 같은 관계다. 상속은 IS-A 관계에서 사용하는 것이 가장 효율적이다. 일반 클래스를 점차 구체촤 하는 상황에서 상속을 사용하는 것이다. 상속을 사용하면 많은 장점이 있지만, 하위 클래스가 상위 클래스형에 종속되기 때문에 이질적인 클래스 간에 상속을 사용하지 않는 것이 좋다. 단순히 코드를 재사용할 목적으로 서로 관련이 없는 클래스들을 상속 관계로 사용하는 것은 좋지 않는 코드 작성 방법이다.

     

    과목을 나타내는 Subject 클래스

    package inheritance2;
    
    public class Subject{
    	private int subjectId;
        private int subjectName;
        
        public int getSubjectId(){
        	return subjectId;
        }
        
        public void setSubjectId(int subjectId){
        	this.subjectId = subjectId;
        }
        
        public int getSubjectName(){
        	return subjectId;
        }
        
        public void setSubjectName(int subjectName){
        	this.subjectName = subjectName;
        }
        
        public void showSubjectInfo(){
        	System.out.println(subjectId+","+subjectName);
        }
    }

    과목 아이디, 이름을 변수로 가비고 get(),set()메서드도 제공한다.

     

    학생을 나타내는 Student 클래스

    class Student extends Subject{}

    이제 Student(학생) 클래스를 만들고자 한다. 모든 학생은 전공 과목(subject)을 가지고 있다. 그러므로 Subject클래스에서 제공하는 여러 메서드를 활용하면 좋을지도 모른다. 이런 경우 위화 같이 Student클래스가 Subject클래스를 상속 받으면 되는 것일까?

     

    이런 경우에는 상속을 상속사지 않는 것이 좋다. 왜냐하면 Subject가 Student를 포과하는 개념의 클래스가 아니기 때문다. 또한 Student 클래스를 상속받는 다른 클래스가 있을 수도 있다. 이런 경우에는 'HAS-A 관계(has a relationship; association)'로 표현한다.

     

    class Student{
        Subject majorSubject;
    }

    HAS - A 관계란 한 클래스가 다른 클래스를 소유한 관계이다. Subject는 Student에 포함되어 Student의 멤버 변수로 사용하는 것이 적적하다.

     

    상속을 코드 재사용 개면으로 이애하면 안되는 이유가 이것이다. 재사용할 수 있는 코드가 있다고 해서 무조건 상속을 받는 것은 아니다. 상속을 사용하면 클래스 간의 결합도가 높아져서 상위 클래스의 변화가 하위 클래스에 미치는 영향이 크다. 따라서 상속은 '일반적 인 클래스' 와 '구체적인(확장되는) 클래스'의 관계에서 구현하는 것이 적절하다. 

     

    💡 tip) 여러 클래스를 한 번에 상속받을 수도 있을까?

    한 클래스가 여러 클래스를 상속받는 것을 다중 상속이라고 한다. 자바 이전의 객체 지향 언어인 C++는 다중 상속을 지원했지만, 자바는 다중 상속을 지원하지 않는다. 여러 클래스에서 상속을 받으면 그만큼 다양한 기능을 상속받을 수 있는 장점이 있을 텐데 자바는 왜 다중 상속을 지원하지 않는 걸까? 그 이유는 다중 상속으로 인한 모호성 때문이다. 예를 들어 두 개 이상의 상위 클래스에 같은 이름의 메서드가 정의되어 있다면, 다중 상속을 받는 하위 클래스는 어떤 메서드를 상속 받을지 모호해니다. 객체 지향에서 다중 상속의 모호성에 대한 예가 다이아몬드 문제(diamond problem)이다. C++ 같은 언어에서 문법적으로 이러한 문제를 해결하지만, 자바에서는 다중 상속의 장점보다는 모호함을 없애는 쪽을 선택해 다중 상속을 사용하지 않는 것이다. 따라서 extends 예약어 뒤에 오는 클래스는 반드시 한 개 여야 한다.

     

     

    [출저 - Do it! 자바 프로그래밍 입문 , 박은종]

    http://www.easyspub.co.kr/20_Menu/BookView/A001/267/PUB

     

    http://www.easyspub.co.kr/20_Menu/BookView/A001/267/PUB

     

    www.easyspub.co.kr

     

    댓글

Designed by Tistory.