인터페이스(Interface)
- 클래스가 아니므로 선언 시 class 키워드를 사용하지 않고 interface 키워드를 사용하여 정의
- 인터페이스는 상수와 추상메서드만 가질 수 있다. => 모든 멤버변수는 public static final이 붙은 상수로 취급됨 (public static final 생략 가능)
- public으로 인해 누구나 접근 가능
- static으로 인해 클래스명만으로 접근 가능
- final로 인해 값 변경 불가
- 메서드 바디를 가질 수 없음
- public으로 인해 누구나 접근 가능)
- 추상클래스와 마찬가지로 추상메서드를 포함하므로 객체 생성 불가능 => 단, 참조변수 타입으로는 사용 가능(=다형성을 활용한 업캐스팅 가능)
- 서브클래스(구현클래스)에서 인터페이스를 상속받아 구현해야 하는 경우 extends 키워드 대신 implements 키워드를 사용 => 클래스는 상속받아 확장(extends)의 개념이 강하지만, 인터페이스는 상속받아 추상메서드를 구현(implements)의 개념이 강함
- 클래스는 서브클래스에서 다중 상속이 불가능 하지만, 인터페이스는 서브클래스에서 다중 상속(구현)이 가능하다! => implements 키워드 뒤에 복수개의 인터페이스 지정 가능
- 인터페이스끼리 상속받을 경우 implements가 아닌 extends로 상속 => 추상메서드는 구현(implements)하지 못하기 때문!
인터페이스 정의 기본문법
[접근제한자] interface 인터페이스명 {
// 상수
// 추상메서드
}
인터페이스를 상속받은(=구현하는) 서브클래스(구현클래스) 정의 문법
[접근제한자] class 클래스명 implements 인터페이스명 {}
package interface_;
public class Ex {
public static void main(String[] args) {
// 인터페이스 정의
// => class 키워드 대신 interface 키워드를 사용하여 정의
interface MyExInterface {
// 인터페이스 내의 모든 멤버변수는 상수(public static final) 이다!
public static final int NUM1 = 10; // 상수
int NUM2 = 20; // 상수(public static final 생략되어 있음)
// 인터페이스는 생성자를 가질 수 없다!
// public MyExInterface() {} // 컴파일 에러 발생!
// => Interfaces cannot have constructors
// 인터페이스 내의 모든 메서드는 추상메서드(public abstract) 이다!
public abstract void method1(); // 추상메서드
// public void method2() {} // 일반메서드(컴파일 에러 발생!)
// => Abstract methods do not specify a body
// => 추상메서드여야 하므로 메서드 바디{} 를 가질 수 없다!
public void method2(); // 추상메서드(abstract 생략되어 있음)
void method3(); // 추상메서드(public abstract 생략되어 있음)
}
// 인터페이스를 상속받아 구현하는 서브클래스(구현클래스) MySubClass 정의
// => 서브클래스 정의 시 클래스명 뒤에 implements 키워드를 쓰고 인터페이스명 지정
class MySubClass implements MyExInterface {
@Override
public void method1() {
System.out.println("서브클래스에서 구현한 추상메서드 method1()!");
}
@Override
public void method2() {
System.out.println("서브클래스에서 구현한 추상메서드 method2()!");
}
@Override
public void method3() {
// 인터페이스(MyExInterface)에서 method3() 메서드 정의 시 접근제한자를
// 생략했지만 인터페이스 내의 모든 메서드는 public 접근제한을 가지므로
// 오버라이딩을 통한 구현 시 무조건 public 접근제한자만 사용 가능!
System.out.println("서브클래스에서 구현한 추상메서드 method3()!");
}
}
abstract class MyClass {
// 클래스 내의 모든 멤버변수는 상수가 아니며, 선언 방법에 따라 달라짐
public static final int NUM1 = 10; // 상수
int NUM2 = 20; // 인스턴스 멤버변수(상수 X)
public MyClass() {} // 생성자
// => 추상클래스는 생성자를 가질 수 있다!
public abstract void method1(); // 추상메서드
// => 추상메서드를 갖는 클래스는 반드시 추상클래스로 선언해야 한다!
public void method2() {} // 일반메서드
// => 추상클래스는 일반메서드도 가질 수 있다!
}
고래와 상어의 특징을 추상화하여 동물 인터페이스로 정의
interface 동물 {
// 인터페이스 내의 모든 메서드는 추상메서드
public abstract void 번식();
}
헤엄칠 수 있는 특징을 갖는 인터페이스 '헤엄칠수있는' 정의
interface 헤엄칠수있는 {}
동물 인터페이스를 상속받는 서브인터페이스 고래, 상어 정의
➡️인터페이스끼리 상속은 implementds가 아닌 extends 사용
➡️인터페이스끼리 상속은 다중 상속도 가능
interface 고래 extends 동물, 헤엄칠수있는 {}
interface 상어 extends 동물, 헤엄칠수있는 {}
고래와 상어 인터페이스를 동시에 상속받아 구현하는 서브클래스 고래상어 정의
➡️클래스에서 인터페이스 상속(구현) 받을 경우 implements 키워드 사용하며 반드시 인터페이스가 가진 추상메서드를 오버라이딩하여 구현해야 한다!
➡️또한, 복수개의 인터페이스를 상속받을 수 있다.
class 고래상어 implements 고래, 상어 {
@Override
public void 번식() {
System.out.println("알을 낳아 번식!");
}
✔️인터페이스 내에서는 슈퍼클래스(인터페이스) 모든 메서드가 추상메서드이므로 중복되는 메서드에 대한 구별없이 직접 구현하면 되기 때문에 중복된 메서드로 인한 혼란이 없음(=다이아몬드 상속에서의 문제점이 사라짐)
'JAVA' 카테고리의 다른 글
[JAVA] 인터페이스 ③ - 인터페이스의 필요성 (1) | 2023.10.10 |
---|---|
[JAVA] 인터페이스 ② 다이아몬드 상속에서의 문제점(이슈)와 예제 (0) | 2023.10.10 |
[JAVA] 레퍼런스 형변환에 대해 알아보자 (0) | 2023.09.26 |
[JAVA] final 키워드 (0) | 2023.09.26 |
[JAVA] 상속에서의 상속자 (0) | 2023.09.19 |