minOS

자바의 정석 ch7-38인터페이스와 다형성 본문

TIL/남궁성의 자바의 정석

자바의 정석 ch7-38인터페이스와 다형성

minOE 2024. 1. 4. 20:36
728x90

ch7-38인터페이스와 다형성(1)

- 인터페이스도 구현 클래스의 부모
- 인터페이스 타입 매개변수는 인터페이스 구현한 클래스의 객체만 가능
class Fighter extends Unit implements Fightable{

    public void move(int x, int y) {
        System.out.println("move");
    }
    public void attack(Fightable f) {
        System.out.println("attack");
    }
}​

인터페이스는 구현부가 없어서 Unit과 Fightable의 선언부가 같아도 문제가 없다. 다중 상속 가능
 Unit u = new Fighter(); // 조상 타입의 참조변수로 자손 객체 가르킴
 Fightable f= new Fighter();​
참조변수 f 는 Fighter 클래스 멤버 중 move와 attack만 사용 가능하다.

interface Fightable{
    void move(int x, int y);
    void attack(Fightable f); 
}​
attack은 인터페이스 타입 매개변수를 받기 때문에 인터페이스를 구현한 클래스의 객체만 매개변수로 받을 수 있다.
f.attack(new Fighter());​



정리

interface Fightable{
    void move(int x, int y);
    void attack(Fightable f); // 인터페이스 타입 매개변수는 인터페이스르 구현한 클래스의 객체만 가능 즉, Fighter만 가능
}

class Unit{
    // 생략
}

class Fighter extends Unit implements Fightable{

    public void move(int x, int y) {
        System.out.println("move");
    }
    public void attack(Fightable f) {
        System.out.println("attack");
    }
}

public class Main {
    public static void main(String[] args) {
        Unit u = new Fighter();
        Fightable f= new Fighter(); //인터페이스형 참조변수 f는 Fighter 클래스멤버 중 move,attack만 사용가능
        f.move(100,200);
        f.attack(new Fighter());

    }
}
출력

 

ch7-38인터페이스와 다형성(2)

- 인터페이스를 메서드의 리턴타입으로 지정할 수 있다.
Fightable method(){
    Fighter f = new Fighter();
    return f        //return new Fighter();와 같음
        }​

어떤 메서드의 반환타입이 인터페이스면,  아래 코드와 같이 반환타입 받는 변수도 타입이 일치 또는 자동형 변환 가능해야한다.

Fightable f = method();

 

 

실습1

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

interface Fightable{
    void move(int x, int y); //public abstract 생략됨
    void attack(Fightable f); //public abstract 생략됨
}


class Fighter extends Unit implements Fightable {
    //오버라이딩 규칙 : 조상(public)보다 접근제어자 범위가 좁으면 안된다. 따라서 public이어야한다.
    public void move(int x, int y) {
        System.out.println("(" + x + "," + y + ")로 이동");
    }

    public void attack(Fightable f) {
        System.out.println(f + "를 공격");
    }
    @Override
    public String toString() {
        return "Fighter";
    }
}
public class Main {
    public static void main(String[] args) {
        Unit u = new Fighter();
        u.move(10,20);
        u.stop();
    //  u.attack(new Fighter()); Unit에는 attack 없어서 호출 불가능
        System.out.println("--------");
        Fightable fightable = new Fighter();
        fightable.move(100,200);
        fightable.attack(new Fighter());
    //  fightable.stop() fightable에는 stop 없어서 호출 불가능
        System.out.println("--------");
        Fighter fighter = new Fighter();
        fighter.move(300,500);
        fighter.attack(new Fighter());
        fighter.stop();


    }
}

출력

 

 

실습2

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

interface Fightable{
    void move(int x, int y); //public abstract 생략됨
    void attack(Fightable f); //public abstract 생략됨
}


class Fighter extends Unit implements Fightable {
    //오버라이딩 규칙 : 조상(public)보다 접근제어자 범위가 좁으면 안된다. 따라서 public이어야한다.
    public void move(int x, int y) {
        System.out.println("(" + x + "," + y + ")로 이동");
    }

    public void attack(Fightable f) {
        System.out.println(f + "를 공격");
    }
    @Override
    public String toString() {
        return "Fighter";
    }
    //싸울 수 있는 상대를 불러온다.
    Fightable getFightable(){
        Fighter f = new Fighter();
        return (Fightable) f; //형변환가능하기때문에
    }
}
public class Main {
    public static void main(String[] args) {
       Fighter fighter = new Fighter();
        Fightable fightable = fighter.getFightable(); //Fightable 타입임
        System.out.println(fightable);
    }
}

 

출력

 

 

728x90