티스토리 뷰

반응형

 

🤔 인터페이스를 이용한 다형성이란?

✔ 인터페이스 타입 매개변수는 인터페이스 구현한 클래스의 객체만 가능 ⭐⭐⭐

✔ 인터페이스를 메서드의 리턴타입으로 지정할 수 있다.

 

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 void move(int x, int y) {
//            void move(int x, int y) { // 에러남. 왜냐? 부모의 접근제어자 보다 넓어야 하는데, 부모에서 지금 public 생략됐는데, 자식에 선언안하면 default로 범위 더 좁기 때문
        System.out.println("[" + x + "," + y + "]로 이동");
    }

    public void attack(Fightable f) {
//            void attack(Fightable f) { // 에러남. 왜냐? 부모의 접근제어자 보다 넓어야 하는데, 부모에서 지금 public 생략됐는데, 자식에 선언안하면 default로 범위 더 좁기 때문
        System.out.println(f + " 를 공격");
    }

    // 싸울 수 있는 상대를 불러온다.
    Fightable getFightable() {
        Fightable f = new Fighter(); // Fighter 생성해서 반환
        return f;
        // Fightable 과 f 형 일치해야함.
        // 여기서는 생략 원래는 return (Fightable)f;
    }
}

public class P {
    public static void main(String[] args) {
        Fighter f = new Fighter();
        f.move(100, 200);
        f.attack(new Fighter());
        Fightable f24 = f.getFightable();

        Unit f2 = new Fighter();
        f2.move(100, 200);
//        f2.attack(new Fighter()); // Unit에는 attack() 없어서 호출불가


        Fightable f3 = new Fighter();
        f3.move(100, 200);
        f3.attack(new Fighter());
//        f3.stop(); // Fightable에는 stop()이 없어서 호출불가
    }
}

 

 

📢 형변환에만 주의해주면 된다!!

 

 


🤔 인터페이스의 장점

✔ 두 대상(객체) 간의 '연결, 대화, 소통'을 돕는 '중간 역할'

✔ 선언(설계)와 구현을 분리시킬 수 있게 한다. 

✔ 개발 시간을 단축할 수 있다.

✔ 변경에 유리한 유연한 설계가 가능하다.

✔ 표준화가 가능하다. 

✔ 서로 관계없는 클래스들을 관계를 맺어줄 수 있다.

 

 

interface I {
	public void method();
}

class B extends I {
	public void method() {
    	System.out.println("methodInB");
    }
}

인터페이스 덕분에 B가 변경되어도 A는 바꾸지 않아도 된다!! (느슨한 결합)

 

class A {
//    public void method(B b) { // 인터페이스 I를 구현한 놈들만 들어와라
    public void method(I i) { // 인터페이스 I를 구현한 놈놈만 들어와라
        i.method();
    }
}

// B클래스의 선언과 구현을 분리
interface I {
    public void method();
}

class B implements I {
    public void method() {
        System.out.println("B클래스의 메서드");
    }
}

class C {
    public void method() {
        System.out.println("C클래스의 메서드");
    }
}

public class P {
    public static void main(String[] args) {
        A a = new A();
        a.method(new B());
    }
}

 

 

✅ 직접적인 관계의 두 클래스(A-B)와 간접적인 관계의 두 클래스(A-I-B)

// 직접적인 관게의 두 클래스(A-B)
class A {
	public void methodA(B b) {
    	b.methodB();
    }
}

class B {
	public void methodB() {
    	System.out.println("methodB()");
    }
}

class InterfaceTest {
	public static void main(String[] args) {
    	A a = new A();
        a.methodA(new B());
    }
}

// 간접적인 관계의 두 클래스 (A-I-B)
class A {
	public void methodA(I i) {
    	i.methodB();
    }
}

interface I { void method(); }

class B implements I {
	public void methodB() {
    	System.out.println("methodB()");
    }
}

 

 


 

🤔 디폴트 메서드와 static 메서드란?

✔ 인터페이스에 디폴트 메서드, static 메서드 추가 가능하다. (JDK 1.8부터)

✔ 인터페이스에 새로운 메서드(추상 메서드)를 추가하기 어렵다.

(왜냐? 기존에 구현했던 메서드들이 다 구현해야하니까)

해결책 ==> 디폴트 메서드(default method)

디폴트 메서드는 인스턴스 메서드(인터페이스 원칙 위반)

 

✅ 디폴트 메서드가 기존의 메서드와 충돌할 때의 해결책

1. 여러 인터페이스의 디폴트 메서드 간의 충돌

✔ 인터페이스를 구현한 클래스에서 디폴트 메서드를 오버라이딩해야 한다.

 

2. 디폴트 메서드와 조상 클래스의 메서드 간의 충돌

✔ 조상 클래스의 메서드가 상속되고, 디폴트 메서드는 무시된다.

 

⭐ 그냥 직접 오버라이딩하면 해결됨!!

 

 

 


자바의 정석의 핵심 파트인 Ch6, 7을 완강했다.

 

내일은 Ch6,7 총 복습 및 앞으로의 진도에 대한 계획표를 올리겠다.

확실히 강의를 듣기 전보다 객체지향에 대해 많은 것을 알게된 시간이었다!!

이틀만에 정주행할 수 있었으면 진작 들을 것 그랬다!!

 

오늘도 열공하자 🔥 

반응형