메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

한빛랩스 - 지식에 가능성을 머지하다 / 강의 콘텐츠 무료로 수강하시고 피드백을 남겨주세요. ▶︎

IT/모바일

[자바] 상속 작동 방식과 상속 구조를 제대로 만들었는지 확인하는 방법

한빛미디어

|

2024-10-11

|

by 한빛미디어

1,790

✅자바의 상속 이해하기

 

상속Inheritance은 부모가 자식에게 물려주는 행위를 말합니다. 객체지향 프로그램에서도 부모 클래스의 필드와 메소드를 자식 클래스에게 물려줄 수 있습니다.

 

 

 

 

 

상속은 이미 잘 개발된 클래스를 재사용해서 새로운 클래스를 만들기 때문에 중복되는 코드를 줄여 개발 시간을 단축시킵니다. 예를 들어 다음 그림처럼 자식 클래스(B)에서 처음부터 필드와 메소드 4개를 작성하는 것보다는 field1과 method1을 부모 클래스(A)에서 상속받고 field2와 method2만 추가 작성하는 것이 보다 효율적이죠.

 

 

 

 

 

실제로 B 클래스를 객체 생성해서 다음과 같이 사용할 때는 마치 B가 field1과 method1을 가지고 있는 것처럼 보입니다.

 

B b = new B();
b.field1 = 10; //A로부터 물려받은 필드와 메소드
b.method1(); //A로부터 물려받은 필드와 메소드
b.field2 = "홍길동"; //B가 추가한 필드와 메소드
b.method2(); //B가 추가한 필드와 메소드

 

 

상속의 또 다른 이점은 클래스의 수정을 최소화할 수 있다는 것입니다. 부모 클래스를 수정하면 모든 자식 클래스에 수정 효과를 가져옵니다. 예를 들어 B, C가 A를 상속할 경우 A의 필드와 메소드를 수정하면 B, C를 수정하지 않아도 수정된 A의 필드와 메소드를 이용할 수 있습니다. 

 

 

 

 

 

☑️이해하기 쉬운 상속 예제

 

여러 가지 서로 다른 동물이 특정 환경에 함께 모여 있을 때 어떤 일이 일어나는지 살펴볼 수 있게 해 주는 시뮬레이션 프로그램을 설계해야 한다고 가정해 보겠습니다. 


프로그램에 들어갈 모든 동물의 목록은 아직 없고 일부 동물의 목록만 받은 상태입니다. 각 동물은 객체로 표현할 수 있고, 그 객체는 각 타입을 프로그래밍할 때 지정한 대로 환경 내에서 움직이게 됩니다. 또한 다른 프로그래머들도 언제든지 프로그램에 새로운 종류의 동물을 추가할 수 있게 만들고 싶습니다. 우선 모든 동물에게 있는 공통적이고 추상적인 특성을 파악하고, 그러한 특성을 클래스로 만든 다음에 모든 동물이 그 클래스를 확장하게 만들면 됩니다.

 

 

 

① 공통적인 상태와 행동을 나타내는 클래스를 설계하기

이 객체들은 모두 동물이므로 Animal이라는 공통적인 상위 클래스를 만들어 볼게요. 그리고 그 안에는 모든 동물이 필요로 하는 메서드와 인스턴스 변수를 집어넣어야겠죠?

 

 

 

 

② 특정 하위 클래스 타입에만 적용되는 행동 (메서드 구현)이 필요한지 결정하기

Animal 클래스를 보면 각 하위 클래스에서 eat() 및 makeNoise()를 오버라이드해야 한다는 결정을 내릴 수 있습니다.

 

 

 

 

③ 공통적인 행동이 필요한 하위 클래스를 두 개 이상 찾아서 추상화의 개념을 더 폭넓게 활용할 수 있을지 찾아보기

여러 클래스를 살펴보면 Wolf, Dog에 공통적인 행동이 있고 Lion, Tiger, Cat에도 공통적인 행동이 있다는 것을 알 수 있습니다.

 

 

 

 

④ 클래스 계층구조(hierarchy)를 완성하기

동물들은 이미 조직적인 계층구조(계, 과, 속, 종 등)가 있으니까 클래스를 설계하는 과정에서도 최대한 활용해 보겠습니다. 여기서는 생물 분류 체계에서의 ‘과(科)’를 활용해서 Feline(고양이과) 클래스와 Canine(개과) 클래스를 만들어서 동물을 조직화 해볼게요.

 

개과 동물은 무리를 지어서 움직이는 성향이 있다는 점을 감안하면 Canine 클래스에서 공통적인 roam() 메서드를 만들 수 있습니다. 또한, 고양이과 동물은 같은 종류에 속하는 다른 동물을 피하려는 습성이 있으므로 공통적인 roam() 메서드를 만들 수 있겠죠. Hippo 클래스에서는 그냥 Animal 클래스에 들어 있는 일반적인 roam() 메서드를 활용합니다.

 

 

 

 

 

 

 

☑️어떤 메서드가 호출될까요?

 

Wolf 클래스에는 메서드가 네 개 있습니다. 하나는 Animal에서, 하나는 Canine에서(Animal 클래스에 있는 메서드를 오버라이드한 것) 상속받은 것이고 두 개는 Wolf 클래스에서 오버라이드한 것입니다. Wolf 객체를 만들어서 변수에 대입하면 그 레퍼런스 변수에 대해 점 연산자를 사용해서 메서드 네 개를 호출할 수 있습니다. 하지만 그 메서드 중에서 어떤 버전이 호출될까요?

 

 

 

 

객체 레퍼런스에 있는 메서드를 호출하면 그 객체 타입의 메서드 중에서 가장 구체적인 버전이 호출됩니다. 즉, 가장 아래에 있는 것이 호출됩니다. 

 

가장 아래에 있는 것은 상속 트리에서 가장 아래쪽에 있는 것을 의미합니다. Canine은 Animal보다 아래에 있고 Wolf는 Canine보다 아래에 있으므로 Wolf 객체에 대한 레퍼런스에서 어떤 메서드를 호출하면 JVM에서는 일단 Wolf 클래스에 들어 있는 것을 찾아봅니다. JVM에서 Wolf 클래스에 있는 버전을 찾을 수 없으면 일치하는 것을 찾을 때까지 상속 계층구조를 따라 올라갑니다.

 

 

 

 

 

☑️상속 구조를 제대로 만들었는지 어떻게 알 수 있나요?

 

한 클래스가 다른 클래스를 상속하는 것을 하위 클래스가 상위 클래스를 확장한다고 합니다. 어떤 것이 다른 것을 확장해야 하는지 알고 싶다면 ‘A는 B다’ 를 떠올려 보세요. 삼각형(Triangle)은 도형(Shape)입니다. 되죠? 고양이(Cat)는 고양이과(Feline)입니다. 이것도 되네요. 외과의사는 의사입니다. 이것도 마찬가지입니다.

 

타입을 제대로 설계했는지 알고 싶다면 ‘A는 B다’ 관계가 성립하는지 확인해 보면 됩니다. 그런 관계가 성립하지 않으면 설계상에 어떤 문제가 있는지를 의심해 봐야 합니다. 욕조와 화장실 사이의 관계를 생각해 보면 “욕조는 화장실이다.”라는 명제가 틀렸다는 것을 알 수 있습니다. 화장실이 욕조를 확장한다고 거꾸로 생각해 보면 어떨까요? 이것도 틀리죠? “화장실은 욕조다.”라고 말할 수 없으니까요.

 

욕조와 화장실 사이에 전혀 관계가 없는 것은 아니지만, 그 관계는 상속 관계가 아닙니다. 욕조와 화장실 사이에는 ‘A에는 B가 있다’ 관계가 있습니다. “화장실에는 욕조가 있다.”라는 관계가 성립한다고 할 수 있을까요? 그렇다면 화장실(Bathroom)에는 욕조(Tub) 인스턴스 변수가 들어간다고 할 수 있습니다. 즉, Bathroom 객체에는 Tub에 대한 레퍼런스가 있다고 할 수 있지
만 Bathroom이 Tub를 확장한다거나 Tub가 Bathroom을 확장한다고 할 수는 없습니다.

 

 

‘A는 B다’ 테스트는 상속 트리의 어느 곳에서도 성립합니다. 즉, 상속 트리를 잘 설계했다면 어떤 하위 클래스를 골라도 ‘하위 클래스는 상위 클래스다’라는 관계가 성립합니다.

 

B라는 클래스가 A라는 클래스를 확장하면 B 클래스는 A 클래스입니다.

이런 테스트는 상속 트리의 어느 곳에서도 참입니다. C라는 클래스가 B라는 클래스를 확장한다면 C라는 클래스는 B와 A 모두에 대해 ‘~는 ~이다’라는 관계가 성립해야 합니다.

 

 

 

왼쪽에 있는 것과 같은 상속 트리가 있으면 언제든지 “늑대는 동물을 확장한다.” 또는 “늑대는 동물이다.”라고 할 수 있습니다. Animal이 Wolf의 상위 클래스의 상위 클래스인 경우에도 전혀 다를 것은 없습니다. Animal이 상속 계층구조에서 Wolf 위에 있기만 하면 “Wolf는 Animal이다.”라는 명제는 항상 참이라고 할 수 있습니다.

 

 

상속에서 ‘A는 B다’ 관계는 한 방향으로만 작동합니다. 

‘삼각형은 도형이다’라는 명제는 참이므로, Triangle은 Shape 클래스를 확장할 수 있습니다. 하지만 그 반대(도형은 삼각형이다)는 참이 성립하지 않으므로 Shape 클래스가 Triangle 클래스를 확장하게 만들면 안 됩니다. 즉, ‘X는 Y다’라고 하면 X는 Y가 할 수 있는 것(또는 그 이상)을 모두 할 수 있다는 뜻임을 잊지 마세요.

 

 

 

 

 

 

 

 

 

 

 

 


 

위 컨텐츠는 『이것이 자바다(3판)』과 『헤드 퍼스트 자바(3판)』의 내용을 재구성하여 작성되었습니다.

 

 

 

댓글 입력
자료실

최근 본 상품0