[자바 문법 #6] 인터페이스

김지현·2023년 10월 30일
0

JAVA

목록 보기
6/14

1. 인터페이스

역할
두 객체를 연결해주는 다리 역할

상속 관계가 없는 다른 클래스들이 서로 동일한 메서드를 구현해야 할 때, 인터페이스는 구현 클래스들의 동일한 사용 방법과 행위를 보장해 줄 수 있음

인터페이스는 스펙이 정의된 메서드들의 집합
인터페이스 구현 클래스들은 반드시 정의된 메서드를 구현해야함
➡️ 구현 클래스들의 동일한 사용 방법과 행위 보장
➡️ 인터페이스에 다형성 적용 가능

선언
interface 키워드 사용
public, default 접그 제어자 지정 가능

구성
모든 멤버 변수 : pulblic static final
모든 메서드 : public abstract
(제어자 생략 가능)

public interface 인터페이스명 { 
	public static final char A = 'A';
    char D = 'D';		// = public static final char
    void turnOn(); 		// = public abstract void turnOn();
}

구현
직접 인스턴스 생성 불가 ➡️ 클래스에 구현되어 생성
implements 키워드 사용

  • 인터페이스의 추상 메서드는 구현될 때 반드시 오버라이딩 되어야함
  • 인터페이스의 추상 메서드를 일부만 구현해야 한다면 해당 클래스를 추상 클래스로 변경
public class 클래스명 implements 인터페이스명 { 
		@Override
	    public 리턴타입 메서드이름(매개변수) {		// 추상 메서드 오버라이딩
			 // 실행문
	    }
}

상속
인터페이스간의 상속은 extends 키워드 사용
다중 상속 가능

interface A {
    void a();
}
interface B {
    void b();
}
interface C extends A, B { }		// 다중 상속

public class Main implements C {	// 구현시 a, b 추상 메서드 오버라이딩

    @Override
    public void a() {
        System.out.println("A");
    }

    @Override
    public void b() {
		System.out.println("B");
    }
}

인터페이스 구현과 상속 함께 사용 가능

class D {
    void d() {
        System.out.println("D");
    }
}

public class Main extends D implements C {
}

2. 메서드

디폴트 메서드

추상 메서드의 기본적인 구현을 제공하는 메서드
메서드 앞에 default 키워드를 붙이며 블럭{}이 존재해야함
추상 메서드가 아니므로 구현체에서 필수로 재정의 할 필요 없음

public class Main implements A {
    public static void main(String[] args) {
        Main main = new Main();      
        main.aa();			// 디폴트 메서드 재정의 없이 바로 사용가능
    }
}

interface A {
    default void aa() {
        System.out.println("AA");
    }
}

static 메서드

인터페이스의 static 메서드 또한 객체 없이 호출 가능

public class Main implements A {
    public static void main(String[] args) {        
        A.aaa();		// static 메서드 호출
    }
}

interface A {
    static void aaa() {
        System.out.println("static method");
    }
}

3. 다형성

여러 가지 형태를 가질 수 있는 능력
사용 방법은 동일하지만 다양한 특징과 결과를 가질 수 있음

자동 타입 변환
인터페이스 변수 = 구현객체 : 자동으로 타입 변환이 일어남

public class Main {
    public static void main(String[] args) {   
        A a1 = new B();		// A 인터페이스에 구현체 B 대입
        A a2 = new C();		// A 인터페이스에 구편체 B를 상속받은 C 대입 
    }
}

interface A { }
class B implements A {}
class C extends B {}

강제 타입 변환
구현객체타입 변수 = (구현객체타입) 인터페이스변수 : 이미 자동 타입 변환된 인터페이스 변수를 다시 객체 타입으로 강제 변환

public class Main {
    public static void main(String[] args) {
        A a1 = new B(); // A 인터페이스에 구현체 B 대입
        a1.a();
        // a1.b(); 	// B의 메서드 사용 불가

        System.out.println("\nB 강제 타입변환");
        B b = (B) a1;
        b.a();
        b.b(); 	// 강제 타입변환으로 사용 가능
        System.out.println();

        A a2 = new C(); // A 인터페이스에 구편체 B를 상속받은 C 대입
        a2.a();
        //a2.b(); // 불가능
        //a2.c(); // 불가능

        System.out.println("\nC 강제 타입변환");
        C c = (C) a2;
        c.a();
        c.b(); // 강제 타입변환으로 사용 가능
        c.c(); // 강제 타입변환으로 사용 가능
    }
}

interface A {
    void a();
}
class B implements A {
    @Override
    public void a() {
        System.out.println("B.a()");
    }
    public void b() {
        System.out.println("B.b()");
    }
}
class C extends B {
    public void c() {
        System.out.println("C.c()");
    }
}
profile
Server Developer

0개의 댓글