Java/java study
Java - 인터페이스(interface)
jddng
2022. 2. 6. 20:21
728x90
반응형
- 인터페이스 정의하는 방법
- 인터페이스 구현하는 방법
- 인터페이스 레퍼런스를 통해 구현체를 사용하는 방법
- 인터페이스 상속
- 인터페이스의 기본 메서드 (Default Method), 자바 8
- 인터페이스의 static 메서드, 자바 8
- 인터페이스의 private 메서드, 자바 9
인터페이스
- 추상 메서드와 상수 필드만 가질 수 있는 클래스의 변형체
- 필요한 기능을 공통화하여 강제성을 부여
- 다중 상속 가능
구분 | 추상 클래스 | 인터페이스 |
상속 | 단일 상속 | 다중 상속 |
구현 | extends 사용 | implements 사용 |
추상 메서드 | abstract 메소드 0개 이상 | 모든 메서드는 abstract |
abstract | 명시적 사용 | 묵시적으로 abstract 사용 |
객체 | 객체 생성 불가 | 객체 생성 불가 |
용도 | 참조 타입 | 참조 타입 |
인터페이스 정의
- 필드
- public static final 필드로 구성
- public static final 생략 시 컴파일러가 자동으로 추가해준다. - 메서드
- public abstract 메서드로 구성
- public abstract 생략 시 컴파일러가 자동으로 추가해준다.
public interface 인터페이스명{
public static final 필드명 = 필드값;
public abstract 메서드명(매개변수);
}
ex)
public interface testInterface{
int testField = 10;
void testMethod();
]
인터페이스 구현
- implements 키워드를 통해 클래스 구현이 가능
- 구현 클래스는 interface에서 선언한 메서드를 반드시 구현해야 하는 강제성이 있다.
- 오버라이딩 할 때는 부모의 메서드보다 넓은 범위의 접근 제어자를 사용해야 한다.
public interface Animal{
void sound();
}
public class cat implements Animal{
@Override
void sound(){
System.out.println("야옹~");
}
}
public class dog implements Animal{
@Override
void sound(){
System.out.println("멍!멍!");
}
}
인터페이스 레퍼런스를 통해 구현체를 사용하는 방법
- 인터페이스를 구현한 클래스들은 인터페이스 참조 변수로 구현 클래스를 참조할 수 있다.
- 참조된 구현 클래스들은 자동으로 업 캐스팅된다.
public class Main { public static void main(String[] args) {
Animal cat = new Cat();
Animal dog = new Dog();
cat.sound();
dog.sound();
}
참고 구현 클래스에서 @Override하지 않은 메서드는
명시적으로 다운 캐스팅을 해줘야 사용할 수 있다.
인터페이스 상속
- 클래스는 다중 상속이 불가능하지만 인터페이스는 다중 상속을 허용한다.
- 인터페이스만 상속받을 수 있다.
public interface SuperInterface1{
void SuperPrint1();
}
public interface SuperInterface2 {
void SuperPrint2();
}
public interface SubInterface extends SuperInterface1, SuperInterface2{
void SubPrint2();
}
public class TestClass implements SubInterface{
@Override
public void SuperPrint1(){
System.out.println("Super 인터페이스1 오버라이드 메서드")
}
@Override
public void SuperPrint2(){
System.out.println("Super 인터페이스2 오버라이드 메서드")
}
@Override
public void SubPrint(){
System.out.println("Sub 인터페이스2 오버라이드 메서드")
}
}
인터페이스의 기본 메서드 (Default Method), 자바 8
자바의 A 라이브러리가 있고, A 라이브러리에 중 B 인터페이스가 존재하는데 B 인터페이스는 이미 사람들이 많이 사용하고 있다고 가정해보자. 만약 A 인터페이스에 추가 기능을 넣기 위해 추상 메서드를 추가한다면 무슨 일이 벌어질까? B 인터페이스를 사용하는 모든 사람들이 수정해야 하는 일이 발생한다.
인터페이스가 변경되지 않는 것이 제일 좋지만, 더 좋은 기술과 로직 등을 위해 어쩔 수 없이 변경이 발생하게 된다. 때문에 자바 8부터 인터페이스의 기본 메서드라는 것이 고안되었다. 디폴트 메서드는 일반 메서드처럼 구현부가 존재하며 일반 메서드의 기능을 하기 때문에 디폴트 메서드는 오버라이드를 하지 않아도 된다.
- 접근 제어자가 public이며 생략 가능
- 디폴트 메서드는 이미 구현되어 있으므로 상속받은 클래스에서 코드를 구현할 필요는 없다
- 단, 구현 클래스에서 오버라이딩해서 재정의 할 수 있다.
public interface Animal{
void sound();
default void ultrasound(){
System.out.println("삐~~~~익");
}
}
public class cat implements Animal{
@Override
void sound(){
System.out.println("야옹~");
}
}
public class dog implements Animal{
@Override
void sound(){
System.out.println("멍!멍!");
}
}
디폴트 메서드 충돌 규칙
참고 사이트
Java 8 디폴트 메서드(Default Method) : 다이아몬드 문제(=다중 상속) 해결하기 (goodgid.github.io)
Java 8 디폴트 메서드(Default Method) : 다이아몬드 문제(=다중 상속) 해결하기
Index
goodgid.github.io
인터페이스의 static 메서드, 자바 8
- 구현 클래스에서 오버라이딩이 불가하다
- 인터페이스로 직접 메서드 호출을 해야 한다. ( 인터페이스명.static메서드명 )
- 인터페이스를 구현한 클래스의 모든 인스턴스에 관련 있는 유틸리티, 헬퍼 메서드를 제공할 때 사용
public interface ICalculator {
int add(int x, int y);
int sub(int x, int y);
default int mul(int x, int y) {
return x * y;
}
static void print(int value) {
System.out.println(value);
}
}
public class CalcTest {
public static void main(String[] args) {
ICalculator cal = new Calculator();
// 오류 발생
cal.print(100);
// interface의 static 메소드는 반드시 interface명.메소드 형식으로 호출
ICalculator.print(100);
}
}
인터페이스의 private 메서드, 자바 9
- 코드의 중복을 피하고 interface에 대한 캡슐화 유지
- rpivate 메서드는 구현부를 가져야 한다.
- 오직 인터페이스 내부에서만 사용할 수 있다.
728x90
반응형