Skip to content

Latest commit

 

History

History
160 lines (125 loc) · 5.97 KB

3주차 정리.md

File metadata and controls

160 lines (125 loc) · 5.97 KB

Chapter 7. 상속과 다형성

상속 관계란?

  • 하위 클래스가 상위 클래스의 멤버를 물려받는다는 것
  • 아래의 말들은 모두 상속 관계를 나타낸다.
    • 하위 클래스가 상위 클래스로부터 상속
    • 하위 클래스가 상위 클래스를 확장(extend)
  • 상속을 활용하는 경우
    • 어떤 클래스가 다른 클래스를 더 구체화한 형식일 때
    • 여러 클래스에서 공유해야 하는 메소드가 있을 때

상속 설계 방법

  1. 공통적 속성과 행동 파악
  2. 공통적인 상태(속성)와 행동을 나타내는 클래스 설계
  3. 특정 하위 클래스 유형에만 적용되는 행동(메소드)이 필요한지 결정
    • 해당 메소드 오버라이딩
  4. 하위 클래스들 사이에서 공통적 행동을 가지는 그룹 파악
  5. 클래스 계층 구조 완성

상속의 작동 방법

  • 상위 클래스의 인스턴스 변수와 메소드는 하위 클래스에 자동 상속
    • 하위 클래스에서 별도의 메소드와 인스턴스 변수 추가 가능
    • 상위 클래스에서 받은 메소드를 하위 클래스에서 오버라이딩 가능
    • 인스턴스 변수는 오버라이딩 하지 않음 (할 필요 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이다’ 성립

상속의 장점

  1. 코드 중복 방지
    • 메소드 수정 시 상위 클래스만 수정하면 하위 클래스에 자동 반영
  2. 일련의 클래스를 위한 공통적 규약(protocol) 정의
    • 상위 클래스의 모든 메소드가 하위 클래스에 들어가기 때문
  3. 확장성이 좋은 코드 개발 가능

상속과 다형성

  • 다형성 사용 시 레퍼런스 유형을 실제 객체 유형의 상위 클래스 유형으로 지정 가능
  • 레퍼런스 변수와 객체를 연결하려면 각각의 유형이 동일해야 함
    1. 레퍼런스 유형과 객체 유형 동일한 경우 (#1)
    2. 클래스 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);
}

확장(상속) 불가능한 클래스

  1. 클래스를 public으로 선언하지 않은 경우
    • 해당 클래스와 같은 패키지 안에서만 하위 클래스 생성 가능 (패키지가 다르면 생성 불가)
  2. 클래스를 final로 지정한 경우
    • final 지정 시 해당 클래스는 상속 계층에서 가장 아래의 위치한 클래스가 됨
    • final 클래스는 절대 확장 불가
    • 일반적으로는 final로 지정하지 않지만, 보안상 오버라이딩을 금지하는 경우 지정 (ex. 클래스 String)
  3. 클래스의 생성자가 모두 private으로 지정된 경우

메소드 오버라이딩

  • 오버라이딩 (overriding)
    • 인자는 같아야 하고, 리턴 유형은 호환 가능해야 함
    • 오버라이딩 시 접근 단계는 유지하거나 완화시켜야 함 (publicprivate 불가)
  • 오버로딩 (overloading)
    • 다형성과 전혀 관계 없는 개념
    • 인자 목록과 리턴 유형 제한
      1. 인자 목록이 같은 경우
        • 리턴 유형이 달라야 함
      2. 인자 목록이 다른 경우
        • 리턴 유형이 달라도 됨 (같거나 다르거나 상관 X)
    • 오버로딩 시 접근 단계는 바뀌어도 됨
  • 하위 클래스에서 오버라이딩한 버전과 상위 클래스의 버전를 둘 다 사용할 경우
    • super 키워드를 사용하여 상위 클래스 버전의 메소드 호출
  • 특정 메소드만 오버라이딩을 금지하고 싶다면 해당 메소드에 final 지정