본문 바로가기

Java/Basic

[Java] 상속(inheritance)

상속의 정의와 장점  

- 상속이란, 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것이다.

- 상속을 통해서 클래스를 작성하면 보다 적은 양의 코드로 새로운 클래스를 작성할 수 있고 코드를 공통적으로 관리할 수 있기 때문에 코드의 추가 및 변경이 매우 용이하다.

- 상속의 특징은 코드의 재사용성을 높이고 코드의 중복을 제거하여 프로그램의 생산성과 유지보수에 크게 기여한다.

- 자바에서 상속을 구현하는 방법은 새로 작성하고자 하는 클래스의 이름 뒤에 상속받고자 하는 클래스의 이름을 키워드 'extends'와 함께 써 주기만하면 된다.

 

- Childe 클래스와 Parent 클래스는 서로 상속 관계에 있다고 하며, 상속해주는 클래스를 '조상 클래스'라 하고 상속 받는 클래스를 '자손 클래스'라 한다.

- 자손 클래스는 조상 클래스의 모든 멤버를 상속받기 때문에, Child 클래스는 Parent 클래스의 멤버들을 포함한다고 할 수 있다.

 

 

- 만일 Parent 클래스에 age라는 정수형 변수를 멤버변수로 추가하면, 자손 클래스는 조상의 멤버를 모두 상속받기 때문에, Child클래스는 자동적으로 age라는 멤머변수가 추가된 것과 같은 효과를 얻는다.

 

- Child 클래스에 새로운 코드가 추가되어도 조상인 Parent클래스는 아무런 영향도 받지 않는다.

- 조상 클래스가 변경되면 자손 클래스는 자동적으로 영향을 받게 되지만, 자손 클래스가 변경되는 것은 조상 클래스에 아무런 영향을 주지 못한다.

 

- 자손 클래스는 조상 클래스의 모든 멤버를 상속받으므로 항상 조상 클래스보다 같거나 많은 멤버를 갖는다.

- 상속에 상속을 거듭할수록 상속받는 클래스의 멤버 개수는 점점 늘어나게 된다.

- 상속을 받는 다는 것은 조상 클래스를 확장(extends)한다는 의미로 해석할 수도 있으며 이것이 상속에 사용되는 키워드가 'extends'인 이유이기도 하다.

 

- 접근 제어자(access modifier)가 private 또는 default인 멤버들은 상속되지 않는다기보다 상속은 받지만 자손 클래스로부터의 접근이 제한된다.

 

 


클래스간의 관계 - 포함관계

- 상속이외에도 클래스를 재사용하는 또 다른 방법이 있는데, 그것은 클래스 간에 '포함(Composite)'관계를 맺어 주는 것이다.

- 클래스 간의 포함관계를 맺어 주는 것은 한 클래스의 멤버변수로 다른 클래스 타입의 참조변수를 선언하는 것을 뜻한다.

 

- 위 두 코드는 각각 원을 표현하기 위한 Circle 클래스와 좌표상의 한 점을 다루기 위한 Point 클래스

 

- Point 클래스를 재사용해서 Circle 클래스를 작성한다면 위 코드와 같다.

- 이와 같이 한 클래스를 작성하는 데 다른 클래스를 멤머변수로 선언하여 포함시키는 것은 좋은 생각이다.

- 하나의 거대한 클래스를 작성하는 것보다 단위별로 여러 개의 클래스를 작성한 다음, 이 단위 클래스들을 포함관계로 재사용하면 보다 간결하고 손쉽게 클래스를 작성할 수 있다.

- 작성된 클래스들은 다른 클래스를 작성하는데 재사용될 수 있다.

 

- 위와 같은 Car클래스를 작성할 때, Car클래스의 단위구성요소인 Engine, Door와 같은 클래스를 미리 작성해 놓고 이 들을 Car클래스의 멤버변수로 선언하여 포함관계를 맺어주면, 클래스를 작성하는 것도 쉽고 코드도 간결해서 이해하기 쉽다.

- 단위클래스 별로 코드가 작게 나뉘어 작성되어 있기 때문에 코드를 관리하는데도 수월하다.

 


클래스간의 관계 설정하기

- 클래스를 작성하는데 있어서 상속관계를 맺어 줄 것인지 포함관계를 맺어 줄 것인지 결정하는 것은 때때로 혼돈스러울 수 있다.

 

- 두 경우를 비교해보면 Circle클래스를 작성하는데 있어서 Point클래스를 포함시키거나 상속받도록 하는것은 결과적으로 별 차이가 없다.

- 이럴 때는 '~은 ~이다(is -a)'와 '~은 ~을 가지고 있다(has -a)'를 넣어서 문장을 만들어보면 클래스 간의 관계가 보다 명확해 진다.

 

- 원은 원점(Point)과 반지름으로 구성되므로 위의 두 문장을 비교해보면 첫 번째 문장보다 두 번째 문장이 더 적합하다.

- 클래스를 가지고 문장을 만들었을 때 '~은 ~이다.'라는 문장이 성립한다면, 서로 상속관계를 맺어주고, '~은 ~을 가지고 있다.'라는 문장이 성립한다면 포함관계를 맺어준다.

 


단일 상속(signle inheritance)

- 다른 객체지향언어인 C++에서는 여러 조상 클래스로부터 상속받는 것이 가능한 '다중상속(multiple inheritance)'을 허용하지만 Java에서는 단일 상속만을 허용한다.

- Java에서는 하나 이상의 클래스로부터 상속받을 수 없다. 

- 다중상속을 허용하면 여러 클래스로부터 상속받을 수 있기 때문에 복합적인 기능을 가진 클래스를 쉽게 작성할 수 있다는 장점이 있지만, 클래스간의 관계가 매우 복잡해진다는 것과 서로 다른 클래스로부터 상속받은 멤버간의 이름이 같은 경우 구별할 수 있는 방법이 없다는 단점을 가지고 있다.

 


Object클래스 - 모든 클래스의 조상

- Object클래스는 모든 클래스 상속계층도의 최상위에 있는 조상 클래스이다.

- 다른 클래스로부터 상속 받지 않는 모든 클래스들은 자동적으로 Object클래스로부터 상속받게 함으로써 이것을 가능하게 한다.

- 모든 상속계층도의 최상위에는 Object 클래스가 위치힌다. 그래서 Java의 모든 클래스들은 Object 클래스에 정의된 멤버들을 사용할 수 있다.

- toString()이나 equals(Object o)와 같은 메서드들은 따로 정의하지 않아도 사용할 수 있는 이유는 이 메서드들이 Object 클래스에 정의된 것들이기 때문이다.

- Object클래스에는 모든 인스턴스가 가져야할 기본적인 11개의 메서드가 정의되어 있다.