Interface와 Abstract class

이성준·2022년 5월 10일
0

JAVA

목록 보기
1/2

Abstract class란?

추상클래스란 뼈대(공통기능)를 만들어놓고 복제를 하는것, 마을에 집객체을 여러채 지어야한다. 집은 아파트객체을 지어도 되고, 초가집객체을 지어도 된다. 하지만 집객체을 만들때 일일히 처음부터 설계하고
할 필요없이 집의 공통기능 즉 지붕이있고 벽이 있는건 똑같기 때문에 집 추상클래스를 만들어서 공통된 뼈대를 만들어준다

abstract class House{
    private String roof = "House roof";
    private String wall = "House wall";
    private Door door;
    
    abstract void 난방();

    void setDoor(Door door){
        this.door=door;
    }

    Door getDoor(){
        return door;
    }
    void openDoor(){
        System.out.println("Basic door opened");

    }

    void closeDoor() {
        System.out.println("Basic door closed");
    }
}
  • 인스턴스 생성불가 :그래서 이렇게 뼈대를 만들어봤는데 이 뼈대를 무슨 실체화 시킨게 아니기 때문에 인스턴스는 생성할수가 없다. 인스턴스를 생성할려면 아파트나 초갓집같은 구체적인 클래스로 만들어 주어야한다.
  • 다형성 :그럼 extends를 통해서 집 객체를 만들때에는 저 공통기능 그대로 사용할수있게 된다 그럼 다형성에 의해서 집이 복제가 된다.
  • abstract 메소드 강제 구현 : 근데 집마다 난방기능이 있어야하는데 어떻게 난방하는지는 다 다르다 그래서 객체를 만들때 강제로 그 메소드를 구현하게 만들어야 한다.
  • is a 관계 : 초갓집이라는 객체를 만들었을때 초갓집은 집이다. 라고 is a 관계가 만들어진다. 즉 집의 기능은 모두 초갓집이 가지고있다.

class 초갓집 extends House{
    @Override
    void 난방() {
        System.out.println("아궁이");
    }

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

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

}

초갓집 객체를 만들때 난방을 구현하지않으면 오류가 생긴다. 그래서 초갓집은 아궁이로 강제 구현해주었다.

Interface란?

우리가 설계도만 있으면 어떤것도 만들수있듯이 인터페이스는 설계도를 만들어주는것이다. 만약 문 인터페이스가 있으면 집객체에 창문이라는 인터페이스를 콱 박아놓고 규격에만 맞게 나무문을 쓰든 철문을 쓰든 갈아 끼우기만 하면된다.

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

class 철문 implements Door{

    @Override
    public void openDoor() {
        System.out.println("철문 열었음");
    }

    @Override
    public void closeDoor() {
        System.out.println("철문 닫음");
    }
}

문 설계도에 문은 열고 닫는게 있어야된다고 나와있다. implements 키워드를 통해 철문클래스에서 구현을 해준다.

  • 인스턴스로 만들수없음 : 추상클래스와 마찬가지로 실체가 없다.
  • 다중상속가능 : 인터페이스는 다중상속이 가능하다 예를들자면 문에 잠그는 기능이랑 초인종 기능을 extends키워드로 추가해준다
interface Lockable {
    void Lock();
}

interface Bellable{
    void Bell();
}

interface Door extends Lock,Bell{
    void openDoor();
    void closeDoor();
}

잠그는 기능이랑 초인종을 추가해주었으니 다시 구현해주자

class 철문 implements Door{
    @Override
    public void Lock() {
        System.out.println("도어락으로 잠금");
    }

    @Override
    public void Bell() {
        System.out.println("딩동");

    }

    @Override
    public void openDoor() {
        System.out.println("철문 열었음");
    }

    @Override
    public void closeDoor() {
        System.out.println("철문 닫음");
    }
}

다중상속이 가능한 이유: 클래스를 다중상속하면 상속받은 입장에서 누구의 메소드를 써야할지 모르는데 인터페이스는 설계도이기때문에 다시 구현하면 끝이다.

  • has - a 관계 : 철문은 문이다. is a 라고 말할수 있지만 실제 개발에서 인터페이스는 ~를 할수 있는 즉 지금은 도어니까 문을 열고닫을수있는? 정도로 봐야될거같다.

둘의차이

  • 추상클래스
    여러개의 가까운 클래스들 (is-a 관계가 형성될) 사이에 동일한 코드를 공유해서 사용하고 싶을때.
    추상클래스를 상속한 클래스들이 많은 공통 메소드들과 필드와 public 보다 다양한 접근 제어자에 의해 사용하고 싶을때.
    non-static 과 non-final 필드를 선언하고 싶을때. 결과적으로 객체들의 상태를 메소드에서 접근하고 수정 할 수 있게 되겠지.
  • 인터페이스
    크게 상관없는(is-a 정도는 아닌 has-a 정도인) 클래스들이 너의 인터페이스를 구현( java8 부터는 구현된 것을 사용도 포함)해야 할 필요가 있을때. 예를들어 Comparable and Cloneable
    특정 데이터타입의 행위를 특별하게 구현하길 원할때 그러나 누가 그것의 행위를 구현 했는지에 대한 관심은 없을때
    다중 구현상속의 이점을 누려야 할때

0개의 댓글