이펙티브자바 아이템 20

존스노우·2024년 2월 19일
0

독서모임

목록 보기
7/9

추상 클래스보다는 인터페이스를 우선하라

대략적인 이유

  • 자바는 다중 상속을 지원 안하기 때문. 너무 뻔하다.
  • 유연성 확장성 다중 구현 이점 이라고 책에 나와있긴함.

추상클래스 : 복지

  • 컨셉: 추상 클래스는 "무엇인가(정체성)"에 초점
  • 추상 클래스는 상속을 통해 클래스의 기본적인 형태나 공통적인 기능을 제공
  • 비슷한 집을? 여러개 복제해 엔터티를 통해서 여러개 집을만드는?
  • 뼈대를 만들고 복제를 한다.

인터페이스 : 계약서 , 설계도

  • 컨셉: 인터페이스는 "할 수 있는 것(능력)"에 초점

  • 수행 , 기능 , 동작 (같은말) 정의 구현은 알아서

  • EX) 어떤문을 사용해야될까? 파란문 빨간문? ,도어락 달린문 ?

  • 왜? 만들어 졌지? 다중상속 문제 해결 , 타입 사용 유연하게!

  • 집을 복제해서 만들 때 ? 각 각의 집에 문을 설치할 때 어떤 인터페이스를 사용 할까 선택

  • 추상 클래스로 비슷한걸 복제하고
  • 복제된 부품안에 바꿔 끼울 수 있는걸 인터페이스로 정의
  • 위에나온 골격 클래스가 아닌가?
package com.dev.study.item20.youtube;

abstract public class House {
    
    private String roof = "house roof";
    private String wall = "house wall";
    private Door door;
    
    
    void setDoor(Door door){
        this.door = door;
    }

    Door getDoor(){
        return door;
    }

    void openDoor(){
        System.out.println("Basic door opend");
    }

    void closeDoor(){
        System.out.println("Basic door closed");
    }
}

interface Door{
    void openDoor();
    void closeDoor();
}

class BasicHouse extends House{

}

class MyHouse extends  House{
    @Override
     void openDoor(){
        getDoor().openDoor();
    }

    @Override
    void closeDoor(){
        getDoor().closeDoor();
    }
}

class myDoor implements Door{

    @Override
    public void openDoor() {
        System.out.println("my door opend");
    }

    @Override
    public void closeDoor() {
        System.out.println("my door closed");
    }
}

class Abstract{
    public static void main(String[] args){
        House basicHouse = new BasicHouse();

        basicHouse.openDoor();
        basicHouse.closeDoor();

        House myHouse = new MyHouse();
        Door myDoor = new myDoor();
        myHouse.setDoor(myDoor);

        myHouse.openDoor();
        myHouse.closeDoor();

    }
}

인터페이스

  • 상수만 가질 수 있음 인스턴스 x
  • 추상메서드 스태틱 메서드 가질 수 있음
interface Door{

    String test = "test";

    default void defaultMethod(){
        System.out.println("defaul method");
    }
    // 추상메서드
    void openDoor();
    void closeDoor();
}
class myDoor implements Door{


    @Override
    public void defaultMethod() {
        Door.super.defaultMethod();
    }

    @Override
    public void openDoor() {
        
        System.out.println(test);
        System.out.println("my door opend");
    }

    @Override
    public void closeDoor() {
        System.out.println("my door closed");
    }
}
  • 디폴트 메서드 : 인터페이스에서 메서드 body 가지는 메서드
  • 반드시 override 할 필요는 없다. 접근 제어자는 public
  • 이것저것 만져보니 디폴트 메서드도 override 할수 있지만 반드시는 no!

왜 만들 었지?

  • 이미 작성된 인터페이스에서 기능을 추가하려 할때
  • 디폴트 메서드 없이는 구현체 클래스들이 전부 오버라이드 해야하지만
  • 디폴트 메서드 없이는 작업 업이 하위 호환가능 (컴파일 에러부분)


  • 다중상속이 안돼는 문제점
  • 설명을 듣다보면 "기능" 에대해 계속 설명하고있다
  • 기능이 추가 될 때마다 강력한 결합 때문에 제한이 되는 느낌

  • 이정도로 많이 필요하다니
  • 이러니 인터페이스가 필요한 부분을 강조.

추상메서드 다이아몬드 문제


  • 추상클래스는 어떤것을 상속받아야 될지 모호해짐
  • 위에는 오타 인터페이스로 수정해야됨.

다른 설명

  • 인터페이스를 사용하면 유연한 다형성 제공

언제? 추상 ? 언제 ? 인터페이스

  • 굉장히 밀접? 애매한대

  • 이것도 설명이 잘 되있지만 와닿지가 않는다

둘다 쓰면 ?

  • 중복을 크게 줄일 수 있따

  • 내가 이해한 바로는 공통된기능 은 추상으로 서로 다른 기능은 인터페이스로

  • 디폴트 메서드는 public만 되기 때문에..


profile
어제의 나보다 한걸음 더

0개의 댓글