디자인 패턴/OOP

인터페이스와 다형성(polymorphism) 그리고 추상클래스

kimjingyu 2023. 6. 7. 19:16
728x90

✏️ 개요

  • 인터페이스
    • 사용하는 클래스가 사용되는 클래스의 종류와 상관없는 독립적인 클래스가 된다.
    • 인터페이스의 메서드는 반드시 구현해야 하는 강제성을 갖는다.
  • 추상클래스
    • 인터페이스의 역할도 하면서 클래스의 기능도 가지고 있는 자바의 돌연변이 같은 클래스이다.
  • 다형성
    • 객체가 한 개 이상의 자료형의 타입을 갖게되는 특성을 의미한다.
    • 부모 자식 상속 관계에 있으면 부모 타입으로 자식 클래스 타입을 받아 초기화할 수 있다.
    • 자바에선 대표적으로 Overloading, Overriding, UpCasting, DownCasting, Interface, 추상메서드, 추상클래스 방법이 모두 다형성에 속한다.

🔎 자료형 다형성

  • 다형성의 핵심은 '타입 묶음'이다.
  • 공통적인 상속 클래스의 특징을 이용해 각 자료형의 타입을 묶는 것.
  • 만일 각 자식 클래스에서 특수한 전용 메서드를 사용해야 하면, 메서드 오버라이딩 혹은 다운캐스팅을 통해 메서드를 실행시키면 된다.

🔎 매개변수 다형성

  • 다형성의 특성은 변수의 타입뿐만 아니라 인터페이스나 파라미터에서도 똑같이 적용된다.

🔎 메서드 다형성

  • 메서드를 확장하거나 재정의하는 overloading/ overriding 도 메서드가 다형해지기때문에 자바의 다형성 특징 중 하나에 속한다고 볼 수 있다.

📌 인터페이스

  • default 메서드
    • 디폴트 메서드를 사용하면 실제 구현된 형태의 메서드를 가질 수 있다.
    • 오버라이딩이 가능하다.
  • static 메서드
    • 인터페이스에 static 메서드를 구현하면 인터페이스명.static 메서드명 과 같이 사용하여 일반 클래스의 static method를 사용하는 것과 동일하게 사용할 수 있다.
  • interface 상수
    • 인터페이스에 정의한 상수는 public static final 이 자동으로 적용된다.
interface Predator {
    String getFood();

    default void printFood() {
        System.out.printf("my food is %s\n", getFood());
    }

    int LEG_COUNT = 4;  // 인터페이스 상수

    static int speed() {
        return LEG_COUNT * 30;
    }
}

📌 추상클래스

abstract class Predator extends Animal {
    abstract String getFood();

    void printFood() {  // default 를 제거한다.
        System.out.printf("my food is %s\n", getFood());
    }

    static int LEG_COUNT = 4;  // 추상 클래스의 상수는 static 선언이 필요하다.
    static int speed() {
        return LEG_COUNT * 30;
    }
}
  • 인터페이스에서 default 메서드로 사용했던 printFood가 추상 클래스의 실제 메서드에 해당된다.
  • 추상 클래스는 인터페이스와 달리 일반 클래스처럼 객체변수, 생성자, private 메서드를 가질 수 있다.

📌 다형성

  • 자식 클래스에 의해서 만들어진 객체는 언제나 부모 클래스의 자료형으로 사용할 수 있다.
  • 하나의 객체가 여러 개의 자료형 타입을 가질 수 있는 것을 객체지향 세계에서는 다형성이라고 한다.
interface Predator {
    String getFood();

    default void printFood() {
        System.out.printf("my food is %s\n", getFood());
    }

    int LEG_COUNT = 4;  // 인터페이스 상수

    static int speed() {
        return LEG_COUNT * 30;
    }
}

interface Barkable {
    void bark();
}

interface BarkablePredator extends Predator, Barkable {
}

class Animal {
    String name;

    void setName(String name) {
        this.name = name;
    }
}

class Tiger extends Animal implements Predator, Barkable {
    public String getFood() {
        return "apple";
    }

    public void bark() {
        System.out.println("어흥");
    }
}

class Lion extends Animal implements BarkablePredator {
    public String getFood() {
        return "banana";
    }

    public void bark() {
        System.out.println("으르렁");
    }
}

class ZooKeeper {
    void feed(Predator predator) {
        System.out.println("feed " + predator.getFood());
    }
}

class Bouncer {
    void barkAnimal(Barkable animal) {
        animal.bark();
    }
}

public class Sample {
    public static void main(String[] args) {
        Tiger tiger = new Tiger();
        Lion lion = new Lion();

        Bouncer bouncer = new Bouncer();
        bouncer.barkAnimal(tiger);
        bouncer.barkAnimal(lion);
    }
}
  • Bouncer 클래스의 barkAnimal 메서드의 입력 자료형이 Barkable이라도 BarkablePredator를 구현한 lion 객체를 전달할 수 있다.
  • 그 이유는 BarkablePredator는 Barkable 인터페이스를 상속받은 자식 인터페이스이기 때문이다.
  • 즉, 자식 인터페이스로 생성한 객체의 자료형은 부모 인터페이스로 사용하는 것이 가능하다.
인용

https://wikidocs.net/269

 

05-08 다형성

객체지향 프로그래밍의 특징 중에는 **다형성**(폴리모피즘, Polymorphism)이 있다. 도대체 다형성은 무엇이고 이게 왜 필요한 걸까? 예제를 통해 차근차근 알아보자. …

wikidocs.net

https://inpa.tistory.com/entry/OOP-JAVA%EC%9D%98-%EB%8B%A4%ED%98%95%EC%84%B1Polymorphism-%EC%99%84%EB%B2%BD-%EC%9D%B4%ED%95%B4

 

💠 자바의 다형성(Polymorphism) 완벽 이해하기

다형성 (Polymorphism) 다형성(多形性) 이란, 그 자체의 의미를 표준 국어사전에서 찾아보면, '같은 종의 생물이면서도 어떤 형태나 형질이 다양하게 나타나는 현상' 이라 정의되어 있다. 이를 프로

inpa.tistory.com

 

728x90