자바의 정석 - 인터페이스와 다형성 (다형성 개념부터 다시)

Yohan·2024년 1월 25일
0

인터페이스와 다형성

  • 인터페이스도 구현 클래스의 부모? Yes
  • 인터페이스 타입의 매개변수는 인터페이스를 구현한 클래스의 객체(인스턴스)만 가능
interface Fightable {
	void move(int x, int y);
    void attack(Fightable f); // Fightable 인터페이스를 구현한 클래스의 인스턴스만 가능!
}

class Fighter extends Unit implements Fightable {
	public void move(int x, int y) { }
    public void attack(Fightable f) { }
}

Unit u = new Fighter(); // 조상 클래스 부모 ok (다형성 ok)
Fightable f = new Fighter(); // 인터페이스 부모 ok (다형성 ok)

// 
f.move(100, 200);
f.attack(new Fighter());

인터페이스를 이용한 다형성

  • 인터페이스를 메서드의 리턴타입으로 지정할 수 있다.
  • 인터페이스가 리턴타입으로 지정되면 인터페이스를 구현한 클래스의 인스턴스를 반환
Fightable method() { // 리턴타입 Fightable
	Fighter f = new Fighter(); // 인터페이스 구현
    return f; // 인터페이스를 구현한 객체 반환
}

abstract class Unit2 {
    int x, y;
    abstract void move(int x, int y);
    void stop() {
        System.out.println("멈춥니다.");
    }
}

interface Fightable { // 인터페이스의 모든메서드는 public abstract. 예외없이!
    void move(int x, int y);  // public abstract가 생략
    void attack(Fightable f); // public abstract가 생략
}

class Fighter extends Unit2 implements Fightable {
    // 오버라이딩 규칙 : 조상(public)보다 접근제어자가 범위가 좁으면 안된다.
    public void move(int x, int y) {
        System.out.println("["+x+","+y+"]로 이동");
    }
    public void attack(Fightable f) {
        System.out.println(f+"를 공격");
    }

    // 싸울 수 있는 상대를 불러옴
    Fightable getFightable() {
        Fightable f = new Fighter(); // Fighter를 생성(인터페이스를 구현한 객체)해서 반환
        return f;
    }
}

public class FighterTest {
    public static void main(String[] args) {
        Fighter f = new Fighter();
        Fightable f2 = f.getFightable(); // 메서드를 호출한 쪽에서는 반환타입이 일치하는 or 자동형변환이 가능한 타입의 변수에 결과를 저장!

    }
}

정리

  1. [인터페이스] 참조변수 = (인터페이스를 구현한 클래스)
    -> 리모콘이 인터페이스이기 때문에 인터페이스가 가지고 있는 멤버만 사용 가능!
  2. 매개변수가 인터페이스라면?
    -> 해당 인터페이스를 implements로 (상속/구현) 된 클래스 모두 쓸 수 있다!
  3. 반환/리턴타입이 인터페이스라면?
    -> 매개변수와 동일! (상속/구현된) 클래스가 반환타입이 되는 것! 인터페이스도 물론 가능.
    -> 반환타입이 인터페이스라는 것은 받는 쪽에서의 타입도 맞춰줘야한다.
profile
백엔드 개발자

0개의 댓글