minghxx.blog
  • 자바의 정석 89~92강 인터페이스, 인터페이스와 다형성, 장점, 디폴트 메서드, static메서드
    2023년 08월 07일 04시 17분 02초에 업로드 된 글입니다.
    작성자: 민발자
    728x90

    ch 7-35~37 인터페이스의 선언, 상속, 구현

    1. 인터페이스

    추상 메서드 집합

    구현된 것이 전혀없는 설계도로 모든 멤버가 public

    interface 이름 {
    	// 변수, iv, cv 불가 상수만 가능
    	public static final 타입 상수이름 = 값;
    	public abstract 메서드이름(매개변수 목록);
    }
    
    // public static final, public abstract 생략 가능

     

    2. 추상클래스와 인터페이스 차이?

    추상 클래스

    추상 메서드를 가지고 있는 클래스. 인스턴스 변수, 생성자, 인스턴스 메서드가 있음

    상속을 통해 하위 클래스에서 구련하도록 강제하는 클래스

    상속을 위한 클래스로 객체 생성 불가

    단일 상속만 지원

     

    인터페이스

    추상 메서드의 집합. 일반 인스턴스 변수, 생성자 멤버변수를 가질 수 없음

    '~할 수 있는' 특징으로 ~able 네이밍 규칙

    다중 상속 지원

    인스턴스가 존재할 수 없기 때문에 상속받은 구현 객체에서 같은 상태를 보장하기 public static final 사용

     

    3. 인터페이스의 상속

    인터페이스의 조상은 인터페이스만 가능

    다중 상속 가능(추상 메서드 충돌 문제 없음)

     

    4. 인터페이스 구현

    인터페이스에서 정의된 추상 메서드를 완성하는 것

    일부만 구현하는 경우 abstract 붙여야함

    class 클래스 이름 implements 인터페이스 이름 {
    	// 인터페이스에 정의된 추상 메서드 모두 구현
    }

    ch 7-38 인터페이스와 다형성

    1. 인터페이스의 다형성

    부모 타입 참조변수로 구현체 다루기 가능

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

    interface Fightable{
    	public void move();
    	public void attack(Fightable f);
    	//Fightable 인터페이스로 구현한 클래스의 인스턴스만 가능
    }
    
    class Fighter extends Unit implements Fightable {
    	public void move() {}
    	public void attack(Fightable f) {}
    }
    
    // 상속처럼 인터페이스도 부모 타입 참조변수로 다루기 가능
    Unit u = new Fighter();
    Fightable f = new Fighter();
    
    // 인터페이스 부모 타입으로 다루면 인터페이스에 있는 2가지 메서드만 사용가능
    f.move();
    f.attack(new Fighter());
    // attack의 매개변수는 인터페이스 구현한 클래스의 객체가 들어올 수 있음

    메서드의 리턴타입으로 인터페이스를 지정 가능

    // 메서드의 리턴타입을 인터페이스로 지정
    // 다형성에 의해 인터페이스 구현한 객체 Fighter 반환
    Fightable method(){
    	return new Figther();
    }
    
    Fightable f = method();
    // 리턴 값을 받는 참조변수는 타입 일치되거나 형변환 가능한 타입으로 받음

    ch 7-39 인터페이스의 장점

    1. 두 대상(객체) 간의 연결을 돕는 중간 역할

    2. 선언(설계)와 구현을 분리해 변경에 유리하게 만듦

    A가 B를 사용→C로 변경

    이때 인터페이스를 사용하면  A를 바꾸는게 아닌 알맹이(구현)인 C만 변경

    class A {
    	// public void method(B b) {
    	// public void method(C c) {
    	// B에서 C로 변경할 때 A를 직접 수정해야함
    	public void method(I i) { // I 구현한 객체만 매개변수 가능
    		i.method();
    	}
    	// 인터페이스 사용하면 A를 직접 수정할 필요 없음
    }
    
    class B implements I{
    	public void method() {
    		System.out.println("B method");
    	}
    }
    
    class C  implements I{
    	public void method() {
    		System.out.println("C method");
    	}
    }
    
    interface I {
    	public void method();
    }
    
    public class InterfaceTest {
    	public static void main(String[] args) {
    		A a = new A();
    		a.method(new B()); // A가 B를 사용 강한 결합, A가 B에 의존
    		a.method(new C()); 
    		// 인터페이스 사용 후 C로 변경할 떄 A 수정불필요 간단하게 매개변수만 변경
    	}
    }

    3. 개발 시간 단축

    4. 변경에 유리한 유연한 설계 가능

    5. 표준화 가능

    6. 서로 관계없는 클래스들 관계를 맺어줄 수 있음

     


    ch 7-40~41 디폴트 메서드, static 메서드

    1. 인터페이스에 디폴트 메서드, static메서드 추가 가능

    JDK 1.8부터 가능

     

    2. 인터페이스에 새로운 추상 메서드를 추가하기 어려움

    인터페이스를 구현했던 모든 클래스에서 새로 추가된 추상 메서드를 구현 해야함

    해결책 → 디폴트 메서드

    디폴트 메서드는 인스턴스 메서드(인퍼테이스 원칙 위반이나 예외로 둔다)

    interface I {
    	void method();
        
    	// 새로 추가된 메서드 구현부 존재
    	default void newMethod() {}
    }

     

    3. 디폴트 메서드 기존 메서드와 충돌

    • 여러 인터페이스의 디폴트 메서드 간의 충돌
      • → 인터페이스 구현한 클래스에서 디폴트 메서드 오버라이딩
    • 디폴트 메서드와 조상 클래스의 메서드 간의 충돌
      • 조상 클래스의 메서드가 상속되고 디폴트 메서드는 무시
    728x90
    댓글