- 하위 클래스가 상위 클래스의 멤버를 물려받는다는 것
- 아래의 말들은 모두 상속 관계를 나타낸다.
- 하위 클래스가 상위 클래스로부터 상속
- 하위 클래스가 상위 클래스를 확장(extend)
- 상속을 활용하는 경우
- 어떤 클래스가 다른 클래스를 더 구체화한 형식일 때
- 여러 클래스에서 공유해야 하는 메소드가 있을 때
- 공통적 속성과 행동 파악
- 공통적인 상태(속성)와 행동을 나타내는 클래스 설계
- 특정 하위 클래스 유형에만 적용되는 행동(메소드)이 필요한지 결정
- 하위 클래스들 사이에서 공통적 행동을 가지는 그룹 파악
- 클래스 계층 구조 완성
- 상위 클래스의 인스턴스 변수와 메소드는 하위 클래스에 자동 상속
- 하위 클래스에서 별도의 메소드와 인스턴스 변수 추가 가능
- 상위 클래스에서 받은 메소드를 하위 클래스에서 오버라이딩 가능
- 인스턴스 변수는 오버라이딩 하지 않음 (할 필요 X)
- 접근 단계(access level)에 따른 상속
public
으로 지정한 멤버는 상속
private
으로 지정한 멤버는 상속되지 않음
- 하위 클래스에서 멤버를 상속받는 것은 하위 클래스에서 멤버 자체를 새로 정의하는 것과 같음
- 객체 레퍼런스의 메소드 호출 시 JVM에서는 반드시 객체에서 호출할 수 있는 가장 올바른 버전을 골라서 호출
- 해당 클래스의 메소드 중 가장 구체적 버전 호출
- 상속 계층 구조 내 클래스들의 메소드 중 가장 아래에 있는 메소드
- ‘A는 B다’
- 하위 클래스는 상위 클래스다.
- A는 B를 상속 받은 하위 클래스
- 한 방향으로만 작동 → ‘B는 A다’는 성립하지 않음
- 해당 관계가 성립하지 않는다면 상속을 사용하면 안 됨
- ‘A에는 B가 있다’
- A와 B는 서로 상속 관계가 아님
- 클래스 A 내에 B 인스턴스 변수가 들어감
- 클래스 A → 클래스 B → 클래스 C 순서로 상속된 경우
- ‘B는 A이다’ 성립
- ‘C는 B이다’ 성립
- ‘C는 A이다’ 성립
- 코드 중복 방지
- 메소드 수정 시 상위 클래스만 수정하면 하위 클래스에 자동 반영
- 일련의 클래스를 위한 공통적 규약(protocol) 정의
- 상위 클래스의 모든 메소드가 하위 클래스에 들어가기 때문
- 확장성이 좋은 코드 개발 가능
- 다형성 사용 시 레퍼런스 유형을 실제 객체 유형의 상위 클래스 유형으로 지정 가능
- 레퍼런스 변수와 객체를 연결하려면 각각의 유형이 동일해야 함
- 레퍼런스 유형과 객체 유형 동일한 경우 (#1)
- 클래스 Dog가 클래스 Animal을 상속 받은 경우, 유형이 다르지만 다형성을 활용했기 때문에 성립 (#2)
// #1
Dog myDog = new Dog();
// #2
Animal myDog = new Dog();
- 다형적인 배열
- 클래스 Dog, Cat, Wolf, Hippo, Lion이 클래스 Animal을 상속 받은 경우
- 배열
animals
에는 클래스 Animal
의 하위 클래스에 속하는 모든 객체 삽입 가능 (#1)
- 배열
animals
의 모든 원소를 순회하며 클래스 Animal
의 메소드 실행 시, 각 객체에 따라 올바른 버전의 메소드 실행 (#2)
// #1
Animal[] animals = new Animal[5];
animals[0] = new Dog();
animals[1] = new Cat();
animals[2] = new Wolf();
animals[3] = new Hippo();
animals[4] = new Lion();
// #2
for (int i = 0; i < animals.length; i++) {
animals[i].eat();
animals[i].roam();
}
- 인자와 리턴 유형에 다형성 적용
- Animal 매개변수 자리에는 Animal 객체 뿐만 아니라, 해당 클래스의 하위 클래스 객체들을 넣어 호출 가능
- 인자에 들어간 각 객체에 따라 올바른 버전의 메소드 실행
class Vet {
public void giveShot (Animal a) {
a.makeNoise();
}
}
class PetOwner {
Vet v = new Vet();
Dog d = new Dog();
Hippo h = new Hippo();
v.giveShot(d);
v.giveShot(h);
}
- 클래스를 public으로 선언하지 않은 경우
- 해당 클래스와 같은 패키지 안에서만 하위 클래스 생성 가능 (패키지가 다르면 생성 불가)
- 클래스를
final
로 지정한 경우
final
지정 시 해당 클래스는 상속 계층에서 가장 아래의 위치한 클래스가 됨
final
클래스는 절대 확장 불가
- 일반적으로는
final
로 지정하지 않지만, 보안상 오버라이딩을 금지하는 경우 지정 (ex. 클래스 String
)
- 클래스의 생성자가 모두
private
으로 지정된 경우
- 오버라이딩 (overriding)
- 인자는 같아야 하고, 리턴 유형은 호환 가능해야 함
- 오버라이딩 시 접근 단계는 유지하거나 완화시켜야 함 (
public
→ private
불가)
- 오버로딩 (overloading)
- 다형성과 전혀 관계 없는 개념
- 인자 목록과 리턴 유형 제한
- 인자 목록이 같은 경우
- 인자 목록이 다른 경우
- 리턴 유형이 달라도 됨 (같거나 다르거나 상관 X)
- 오버로딩 시 접근 단계는 바뀌어도 됨
- 하위 클래스에서 오버라이딩한 버전과 상위 클래스의 버전를 둘 다 사용할 경우
super
키워드를 사용하여 상위 클래스 버전의 메소드 호출
- 특정 메소드만 오버라이딩을 금지하고 싶다면 해당 메소드에
final
지정