[스터디할래 06] 상속
이 글은 ‘백기선’ 개발자님과 함께하는 온라인 자바 스터디에 참여하여 준비/학습한 내용을 정리하는 글입니다.📚
- 6주차 : https://github.com/whiteship/live-study/issues/6
- 목표 : 자바의 상속에 대해 학습
정리는 Java Tutorials - Inheritance를 기반으로 하였습니다.
자바 상속의 특징
- 상속은 심플한 아이디어를 기반으로 한다 : 필드, 메소드를 재사용해서 중복을 없애는 것이다.
- subclass(자식 클래스)는 superclass(부모 클래스)의 모든
ppublic, protected
멤버(=필드, 메소드왜 중첩 클래스)를 상속받는다. 같은 패키지 내에서 상속받았다면,package-pricate
멤버도 상속받는다. - 생성자는 멤버가 아니다. 즉, 생성자는 상속받지 않는다. 하지만, subclass에서 superclass의 생성자를 호출할 수는 있다.
Object
클래스는 모든 클래스의 최상위 클래스이다.
Subclass 에서 하는 일
- superclass와 동일한 필드를 정의해서 superclass의 필드를 숨길 수 있다.(추천하지는 않는다고 한다.)
- 새로운 필드/메소드를 정의한다.
- 동일한 메소드를 정의 = 오버라이딩 한다.
- 생성자를 작성해서 superclass의 생성자를 암시적으로 또는
super
키워드로 호출할 수 있다.
다중 상속
Multiple Inheritance of State
- 클래스와 상속의 가장 큰 차이는 클래스는 필드를 소유하고 있다는 것이다. 또, 클래스로는 객체를 생성할 수 있다.
- 자바에서 한 클래스가 여러 클래스를 한 번에 상속할 수 없도록 하는 이유는, multiple inheritance of state 이슈를 방지하기 위함이다. 여러 클래스를 상속하는 순간, 여러 다른 superclass의 필드를 소유하게 된다. 생성자에서는 어떤 부모클래스의 생성자를 먼저 호출해야할 지 알 수 없다. 인터페이스는 필드가 없이 때문에 이러한 문제가 생기지 않는다.
Multiple Inheritance of Implementation
- 여러 클래스의 메소드 정의를 상속할 수 있는 것이다.
- 동일한 이름의 메소드가 존재하면 컴파일러가 경고를 띄운다.
- 인터페이스의 default methods가 Multiple Inheritance of Implementation 특징의 예시이다. 클래스는 동일한 명의 default methods를 가지고 있는 여러 인터페이스를 상속할 수 있다.
Multiple Inheritance of Type
- 한 클래스가 하나 이상의 인터페이스를 구현할 수 있는 것을 ‘multiple inheritance of type’라고 한다.
- 객체는 여러 종류의 타입을 가질 수 있다 : 자기 자신 클래스 타입과, 구현한 모든 인터페이스 타입이다.
- 즉, 어떤 변수가 특정 인터페이스 타입으로 선언되면, 그 변수에는 해당 인터페이스를 구현한 모든 객체 레퍼런스를 가질 수 있다.
Super 키워드
superclass 멤버에 접근하기
메소드가 수퍼클래스의 메소드를 오버라이드할 때 super
키워드로 수퍼클래스의 overriden 된 메소드를 호출할 수 있다.
subclass의 생성자
- 서브클래스의 생성자에서 수퍼클래스의 생성자를 호출할 수 있다.
- 서브클래스의 생성자에서 부모클래스의 생성자를 직접 호출하지 않더라도, 컴파일러가 자동으로 부모클래스의 기본 생성자(no-argument constructor)를 호출해준다.
super()
로 호출하며 반드시 서브클래스의 초기화 코드가 시작되기 이전에 호출해야한다.public Subclass { Subclass() { super(parameter list); // initialize code } }
- 부모클래스의 생성자가 연속적으로 호출되는 것을 constructor cahining라 한다.
오버라이딩과 메소드 숨기기
Instance Methods
- 수퍼클래스의 메소드와 동일한 이름, 파라미터, 리턴타입을 가진 인스턴스 메소드는 수퍼클래스의 메소드를 오버라이딩 한다.
- overriding 메소드는 overriden 메소드의 리턴 타입과 같은 종류의 타입 변수(=covariant return type)를 리턴할 수 있다.
- 오버라이딩 메소드에
@Override
애노테이션을 붙일 수도 있다.
Static Methods
- 서브클래스가 수퍼클래스와 동일한 static method를 선언하면, 이 메소드는 수퍼클래스의 메소드를 숨긴다.
- hide와 override의 차이점은
- overridden 메소드의 호출은 subclass 에서만 일어난다.
- static method를 hide한 경우,
Superclass.a()
,Subclass.a()
메소드 모두 호출할 수 있다.
Final 메소드, 클래스
- 메소드가 subclass에서 오버라이드될 수 없도록
final
키워드를 붙일 수 있다.Object
클래스에서 많은 메소드들에final
키워드가 붙어 있다. - 주로 생성자에서 사용하는 메소드들은
final
키워드를 붙여 상속받은 클래스에서 재정의하지 않도록 해야 한다. - final 클래스를 생성해 immutable class로 생성할 수도 있다.
Abstract 메소드, 클래스
- 추상 클래스는
abstract
선언된 클래스이다. 추상메소드를 포함할 수도, 하지 않을 수도 있다. - 추상메소드는 몸체가 구현되지 않은 메소드인다. (
{}
없이) - 클래스에 추상메소드가 포함되면 반드시 추상 클래스로 선언해야한다.
- 인터페이스에 선언한 default method나 static method로 선언하지 않은 메소드도 (
abstract
키워드가 생략된) 추상메소드이다.
Abstract 클래스와 Interface
- 추상클래스와 인터페이스는 비슷하다. 둘 다 객체를 생성할 수 없고, 몸체가 없는 메소드를 포함한다.
- 추상클래스는
static
,final
이 아닌 필드를 선언할 수 있고, 완전한public, protected, pricate
메소드를 선언할 수 있다. - 반면, 인터페이스는 모든 메소드가
public
이다. - 추상클래스는 하나만 상속할 수 있는 반면, 인터페이스는 여러 개 구현할 수 있다.
추상클래스가 적합할 때
- 연관된 클래스끼리 코드를 공유하려 할 때
- 공통 메소드나 필드가 많을 때
public
이외의 접근제어자가 필요할 때- non-static/non-final 필드 정의가 필요할
인터페이스가 적합할 때
- 무관한 클래스에서 특정 하나의 기능 공유가 필요할 때
- 특정 행동이나 타입을 지정하고 싶지만, 구체적 내부 행동은 다르게 구현하고 싶을 때
- 다중 타입 상속(multiple inheritance of type) 기능을 이용하고 싶을
예시
- 자바에서 추상 클래스
AbstractMap
을 구현한 클래스에는HashMap, TreeMap, ConcurrentHashMap
등이 있다.AbstractMap
에는get, put, isEmpty, containsKey
등의 메소드가 있다. - 한편,
HashMap
은AbstractMap
을 상속하며,Serializable, Cloneable, Map<K,V
인터페이스를 구현한다.