12. 상속 다루기

12.1 메서드 올리기#

  • 상속된 클래스에 따로 공통된 메서드가 포착된다면, 상위 클래스 해당 메서드를 올리는 개념
  • 중복 부분을 상위로 올려, 각 중복된 부분에서 업데이트가 누락됨을 방지할 수 잇는 전략
  • 완전 공통되어 있지않다면 공통된 부분과 차이점을 인식하고 공통된 부분만 올릴수 있도록 리팩터링 해야함

12.2 필드 올리기#

  • 하위 클래스의 중복된 필드를 보고 역할이 같다면, 상위 클래스로 필드를 올리는 개념
  • 두가지 중복을 줄일 수 있음
    • 하위 클래스 필드 중복 선언
    • 해당 필드를 사용하는 동작을 부모 클래스에 옮길 수 있음

12.3 생성자 본문 올리기#

// before
public class Party {...}
public class Employee extends Party {
public Employee(String name, long id) {
super();
this.name = name;
this.id = id
}
}
// after
public class Party {
public Party(String name) {
this.name = name;
}
}
public class Employee extends Party {
public Employee(String name, long id) {
super(name);
this.id = id;
}
}
  • 생성자는 하는 일에 제약이 있다 (유효성 검사 및 대입)
  • 간단히 리팩터링이 될 것 같지 않으면 생성자를 팩터리 함수 (11.8) 을 고려해볼 수 있다

12.4 메서드 내리기#

  • 12.1 메서드 올리기와 반대
  • 하위 타입에 있을 때 더 간결성을 갖출 경우 적용

12.5 필드 내리기#

  • 12.2 필드 올리기와 반대
  • 하위 타입에만 필요한 필드일 경우 적용

12.6 타입 코드를 서브클래스로 바꾸기#

// before
public static Employee createEmployee(String name, String type) {
return new Employee(name, type);
}
// after
public static Employee createEmployee(String name, String type) {
switch (type) { // type 을 enum으로 고쳐도 좋겠다 생각
case "engineer":
return new Engineer(name);
case "salesperson":
return new SalesPerson(name);
case "manager":
return new Manager(name);
}
}
  • 타입 코드외 그 이상의 기능이 각 타입마다 필요할 때 적용
    • 서브클래스로 나누었을 때 이점
      • 다형성 제공
      • 특정 타입에만 의미있는 필드나 메서드를 제공
  • 대상 클래스에 직접 적용할지, 타입 필드에만 적용할지도 고려대상
    • 업무 유형을 다른 역할로 쓰고싶다면 타입 필드에만 적용, 그렇지 않다면 대상 클래스에 직접 적용
    • 타입 필드로 변경 시, 타입 코드에 기본형 객체로 바꾸기 (7.3) 을 적용

12.7 서브클래스 제거하기#

  • 12.6 과 반대되는 내용
  • 서브 클래스의 가치가 없음이 확인되면 서브클래스를 제거하여 슈퍼클래스로 올리는 방법을 적용

12.8 슈퍼클래스 추출하기#

  • 어떤 클래스들이 공통된 것들을 가지고 있다면, 이를 슈퍼클래스로 만들어 상속구조를 가져가는 방법

12.9 계층 합치기#

  • 자식과 부모가 너무 비슷해지면 독립적으로 존재해야할 이유가 없으므로 계층구조를 해제하고 하나로 합친다
Last updated on