본문 바로가기

Java/OOP

[Java | OOP] 7-38. 인터페이스와 다형성

📌 학습 목차

38. 인터페이스와 다형성

38. 인터페이스와 다형성

•인터페이스는 인터페이스를 구현하는 클래스(구현 클래스)의 조상과도 같은 역할에 해당하므로

   다형성에 의해 인터페이스 타입의 참조 변수로 구현 클래스의 객체를 참조할 수 있음

   이때 인터페이스 타입의 참조 변수는 구현 클래스의 객체 멤버 중 인터페이스에 정의된 멤버만 사용할 수 있음

•인터페이스는 메서드의 매개 변수나 반환 타입으로 사용될 수 있으며,

   이는 구현 클래스의 객체를 매개 변수로 받거나 구현 클래스의 객체를 반환하는 것을 의미함

•인터페이스가 메서드의 반환 타입으로 사용될 경우,

   메서드의 반환 타입, 반환된 구현 클래스의 객체 타입, 반환된 구현 클래스의 객체를 저장할 참조 변수의 타입은

   서로 일치하거나 자동 형변환이 가능해야 함

 

package chap_07;

// 1) 추상 클래스
abstract class Player4 {
    int x, y;
    abstract void move(int x, int y);
    abstract void stop();
}

// 2) 인터페이스
interface Kickable2 {
    📌 // 2-1) 인터페이스가 매개 변수인 메서드 정의
    public abstract void kick(Kickable2 k);
    void cornerKick(Kickable2 k);
    void penaltyKick(Kickable2 k);
}

// 3) 추상 클래스의 자손 클래스 및 인터페이스의 구현 클래스
class Footballer4 extends Player4 implements Kickable2 {
    @Override
    void move(int x, int y) { System.out.println("(" + x + ", " + y + ")" + "로 이동합니다."); }
    @Override
    void stop() {}
    📌 // 3-1) 인터페이스 구현
    @Override
    public void kick(Kickable2 k) { System.out.println( k + "가 킥을 찹니다."); }
    @Override
    public void cornerKick(Kickable2 k) { System.out.println( k + "가 코너킥을 찹니다."); }
    @Override
    public void penaltyKick(Kickable2 k) { System.out.println( k + "가 패널티킥을 찹니다."); }

    📌 // 3-2) 인터페이스가 반환 타입인 메서드 정의
    Kickable2 getFootballer() {
        return new Footballer4(); // return (Kickable2)new Footballer4();
    }
}

public class _38_Example {
    public static void main(String[] args) {
        📌 // 4-1) 인터페이스의 다형성
        Footballer4 f = new Footballer4();
        f.move(100, 200); // (100, 200)로 이동합니다.
        f.kick(new Footballer4()); // chap_07.Footballer4@75b84c92가 킥을 찹니다.

        Kickable2 k1 = new Footballer4();
        // k1.move(10, 20); -> 에러 발생
        k1.kick(new Footballer4()); // chap_07.Footballer4@6bc7c054가 킥을 찹니다.

        📌 // 4-2) 인터페이스가 반환 타입인 메서드 호출
        Kickable2 k2 = f.getFootballer(); // Kickable2 k2 = new Footballer4();
        System.out.println(k2 + "가 선발로 참여합니다."); // chap_07.Footballer4@232204a1가 선발로 참여합니다.
    }
}

 

2-1) 인터페이스가 매개 변수인 메서드 정의

Kickable2 인터페이스가 매개 변수인 kick, cornerKick, penaltyKick 메서드를 정의했으며,

   이는 Kickable2 인터페이스의 구현 클래스인 Footballer4 클래스의 인스턴스를 매개 변수로 받는다는 것을 의미함

3-1) 인터페이스 구현

오버라이딩은 조상 클래스의 메서드보다 좁은 범위의 접근 제어자로 변경할 수 없음

   이에 모든 멤버가 public인 Kickable2 인터페이스를 오버라이딩으로 구현할 경우, 접근 제어자로 default가 아닌 public을 사용함

3-2) 인터페이스가 반환 타입인 메서드 정의

Kickable2 인터페이스가 반환 타입인 getFootballer 메서드를 정의했으며,

   이는 Kickable2 인터페이스의 구현 클래스인 Footballer4 클래스의 인스턴스를 반환하는 것을 의미함

   이때 getFootballer 메서드의 반환 타입(Kickable2)과 반환된 Footballer4 인스턴스 타입(Footballer4)이 서로 일치하지 않으나,

   Kickable2 타입으로 자동 형변환이 가능하므로 에러가 발생하지 않음

4-1) 인터페이스의 다형성

•다형성에 의해 조상에 해당하는 Kickable2 인터페이스 타입의 참조 변수 k1으로 Footballer4 인스턴스를 참조할 수 있음

   이때 참조 변수 k1은 Footballer4 인스턴스 멤버 중 Kickable2 인터페이스에 정의된 kick 메서드는 호출할 수 있으나,

   추상 클래스인 Player 클래스에 정의된 move 메서드는 호출할 수 없음

4-2) 인터페이스가 반환 타입인 메서드 호출

Kickable2 인터페이스가 반환 타입인 getFootballer 메서드를 호출할 경우,

   Kickable2 인터페이스의 구현 클래스인 Footballer4 클래스의 인스턴스가 반환됨

   이때 getFootballer 메서드의 반환 타입(Kickable2), 반환된 Footballer4 인스턴스 타입(Footballer4), 

   반환된 Footballer4 인스턴스를 저장할 참조 변수 k2의 타입(Kickable2)이 서로 일치하지 않으나,

   Kickable2 타입으로 자동 형변환이 가능하므로 에러가 발생하지 않음

 


Reference

[남궁성의 정석코딩] Java의 정석 기초편 강의

[도우출판] Java의 정석 기초편 / 기본편