인터페이스 원리
인터페이스의 기본 골격은 클래스와 동일하다. 대신 class 대신 interface라 선언 되어있고, 메소드는 몸체없이 마무리된다.
interface interF{
public void print(String dog);
}
메소드의 몸체가 비어있는 메소드를 가리켜 추상 메소드(Abstract Methods)라 하며 인스턴스 대상으로는 인스턴스 생성이 불가능하다. 다만 클래스에 implements 키워드가 사용되어 상속이 아닌 '구현'의 대상이 된다.
- 구현할 인터페이스를 명시할 떄는 implements를 사용
- 한 클래스는 둘 이상의 인터페이스를 구현 가능
- 상속과 구현은 동시에 가능
두 인터페이스를 선언
package interFaces;
public interface Printer{
public void Printer();
}
package interFaces;
public interface Phone {
public void Phone();
}
프린터와 폰의 인터페이스 선언
class Samsung implements Printer, Phone{
@Override
public void Printer() {
System.out.println("나는 삼성프린터");
}
@Override
public void Phone() {
System.out.println("나는 삼성폰");
}
}
class LG implements Printer, Phone{
@Override
public void Printer() {
System.out.println("나는 LG프린터");
}
@Override
public void Phone() {
System.out.println("나는 LG폰");
}
}
class print{
public static void main(String[] args) {
LG lg = new LG();
Samsung ss = new Samsung();
lg.Printer();
ss.Printer();
lg.Phone();
ss.Phone();
}
}
인터페이스를 implements 한 클래스는 반드시 인터페이스에 있는 추상 메소드를 구현해야만 한다.
참조변수의 선언은 물론 가능하며 인터페이스의 추상 메소드와 이를 구현하는 메소드 사이에 오버라이딩 관계가 성립되어 어노테이션 @Override의 선언이 가능하다.
인터페이스간의 상속도 가능하다.
package interFaces;
interface InterExtends{
public void print();
}
interface ChildInter extends InterExtends{
@Override
public void print(); // Override
public void print(String doc); // Overrode
}
public class inter2 implements ChildInter {
@Override
public void print() {
System.out.println("Override");
}
public void print(String doc) {
System.out.println(doc);
}
public static void main(String[] args) {
inter2 a = new inter2();
a.print();
a.print("Overrode");
}
}
디폴트 메소드
자바 8부터 Default Method가 소개 되었다.
만약 삼성과 LG 인터페이스가 있다고 가정해보자. B라는 사람은 삼성과 LG의 공통 기술이 필요하고, C라는 LG만 가지고 있는 기능 두가지 기술이 모두 필요하다. 그러면 C라는 사람은 두 인터페이스를 implements 해야한다.
package interFaces;
interface SamsungFunction {
//중략
}
------------------------
interface LGFunction {
//중략
}
class B implements Samsung{
//중략
}
class C implements Samsung, LG{
//중략
}
이해하기 쉽게 큰 구현체 두개로 예시를 들었다. (LG폰과 Samsung폰을 구현하려면 원래는 복잡하다 :( ..) 다양한 프로젝트에 사용 중인 수십 개의 인터페이스가 있다고 생각해보면 복잡할 것이다. 한 인터페이스에 최소 한 개 이상의 추상 메소드를 추가해야한다. 이 문제를 인터페이스를 extends로 이용하여도 인터페이스의 수가 늘어난다. 디자인적으로 설계가 복잡해지며 가독성과 코드낭비이다.
해결책으로 default Method가 사용되는데, 삼성과 LG의 공통만 필요하면 defalut Method로 선언한 LG의 기능은 구현하지 않아도 된다. 그리고 이미 구현된 프로젝트에서 인터페이스를 implements한 class들이 영향을 받지 않게 새로운 메소드가 필요한 클래스들에 사용하면 좋을 것 같다.
package interFaces;
interface SamsungAndLGFunction {
public void SamsungAndLG(); //삼성과 LG의 공통기능
default void LG(); //LG의 기능
}
class B implements SamsungAndLGFunction{
@Override
public void SamsungAndLG(){
System.out.println("공통기능만 필요해");
};
}
class C implements SamsungAndLGFunction{
@Override
public void SamsungAndLG(){
System.out.println("공통기능만 필요해");
};
@Override
public void LG() {
System.out.println("LG 기능도 필요해");
};
}
인터페이스의 static
인터페이스에서도 static 메소드를 사용할 수 있다. 클래스에서 정의하는 static 메소드와 유사하다.
package interFaces;
interface staticInter {
static void printStatic(){
System.out.println("나는 인터페이스에서 구현이 미리 가능해~");
}
};
class test implements staticInter{
public static void main(String[] args) {
staticInter.printStatic(); // 인터페이스로 바로 호출 static 영역으로 저장 되기에 구현할 필요없음
}
}
class test2 {
public static void main(String[] args) {
staticInter.printStatic(); // 인터페이스를 implements 하지않아도 메소드호출이 가능하다.
}
}
인터페이스 안에 static 메소드를 구현하면 static영역에 메소드가 저장되기 때문에 implements한 클래스에서 구현할 필요가 없으며 implements를 하지 않은 클래스에서도 바로 호출이 가능하다.
인터페이스 2편에서 계속!
https://chaehun97.tistory.com/entry/Java-Interface-2
'Language > Java' 카테고리의 다른 글
[Java] Collection Framework 총 정리 (1) | 2023.12.26 |
---|---|
[Java] Interface 정리(2) (0) | 2023.07.18 |
[Java] 자바 상속 정리 (0) | 2023.07.14 |
[Java] foreach문 사용하기 (0) | 2023.07.12 |
[Java] 접근 수준 지시자(Access-level Modifiers) (0) | 2023.07.03 |