1. 인터페이스
1.1 인터페이스의 필요성
- 메인 메서드가 각 클래스를 호출 할때, 호출메서드명이 상이하다.
BlueWorker w1 = new BlueWorker();
WhiteWorker w2 = new WhiteWorker();
JubuWorker w3 = new JubuWorker();
// 각 노동자에게 일을 시키는 방법이 다르다.
// 왜?
// => 메서드 호출 방법이 다르기 때문에
w1.doFight();
w2.doZingZing();
w3.doSsingSsing();
1.2 인터페이스의 적용
- 동일한 호출명으로 메서드를 호출 할 수 있다.
public interface Worker {
// 호출 규칙?
// => 메서드 형식을 의미한다.
// => 메서드의 몸체는 정의하지 않는다.
// => 메서드의 몸체는 이 규칙에 따라 만드는 클래스에서 정의하는 것이다.
//
// 문법
// => public abstract 리턴타입 메서드명(파라미터,...);
// => public과 abstract는 모두 생략 가능.
// => public 외에 다른 접근 범위는 사용할 수 없다.
// (규칙은 공개되어야 하니까!)
//
void execute();
//=> public abstract void execute();
}
class WhiteWorker implements Worker {
@Override
public void execute() {
System.out.println("사무직 노동자가 일을 합니다.");
}
}
Worker w1 = new BlueWorker();
Worker w2 = new WhiteWorker();
Worker w3 = new JubuWorker();
w1.execute();
w2.execute();
w3.execute();
1.3 인터페이스의 관계
- 호출자 : 클라이언트로 구현체를 호출 하는 클래스
- 피호출자 : 구현체로 인터페이스의 규칙을 적용받아 메소드를 생성
2. 인터페이스 구성요소
2.1 인터페이스 기본요소
- 인터페이스 기본형은 public abstract 이다.
interface MyInterface {
// 규칙1) 인터페이스에 선언되는 모든 메서드는 public 이다.
// - 인터페이스에 정의하는 메서드는 호출 규칙이다.
// - 규칙은 공개되어야 한다.
// 규칙2) 인터페이스에 선언되는 모든 메서드는 추상 메서드로 선언한다.
// - 인터페이스에 선언하는 메서드는 호출 규칙을 정의한 것이다.
// - 규칙은 클래스가 따라야 한다.
// - 그래서 인터페이스에 선언되는 모든 메서드는 몸체를 구현하지 않는다.
public abstract void m1();
// public 을 생략할 수 있다.
abstract void m2(); // public 이 생략된 것이다. (default) 아니다!
// abstract 를 생략할 수 있다.
public void m3();
// public, abstract 모두 생략할 수 있다.
void m4();
// => private, protected, (default)는 없다.
// private void m5(); // 컴파일 오류!
// protected void m6(); // 컴파일 오류!
void m7(); // 이건 (default) 아니라, public 이 생략된 것이다.
}
- 구현부의 형식은 다음과 같다.
// 2) 인터페이스 구현
abstract class MyInterfaceImpl implements MyInterface {
@Override
public void m1() {}
// public 보다 접근 범위를 좁힐 수는 없다.
@Override
// private void m2() {} // 컴파일 오류!
// protected void m2() {} // 컴파일 오류!
// void m2() {} // 컴파일 오류!
public void m2() {} // OK!
// 인터페이스의 모든 메서드를 구현해야 한다.
// 한 개라도 빠뜨린다면 concrete 클래스가 될 수 없다.
// 추상 클래스로 선언해야 한다.
}
- 메인클래스에서 인터페이스의 사용은 다음과 같다.
public class Exam01 {
public static void main(String[] args) {
// 인터페이스 레퍼런스 선언
MyInterface obj = null;
// 인터페이스의 구현체 생성
// - 인터페이스를 구현한 클래스의 객체라면
// 언제든 해당 인터페이스의 레퍼런스에 담을 수 있다.
obj = new MyInterfaceImpl2();
// 인터페이스는 규칙이기 때문에
// 구체적인 구현 내용이 없다.
// 그래서 인스턴스를 생성할 수 없다.
//
// obj = new MyInterface(); // 컴파일 오류!
}
}
2.2 디폴트메서드
- 디폴트 메서드는 인터페이스에서 미리 구현하는 메서드이다.
- 인터페이스 받는 클래스에서 구현메서드를 재정의 하지 않아도 된다.
- 하지만, 클래스에서 구현을 강제할 수 없다.
// 인터페이스 - private 메서드
package com.eomcs.oop.ex09.b;
interface MyInterface4 {
void m1();
default void m2() {
System.out.println("MyInterface4.m2()");
x();
};
default void m3() {
System.out.println("MyInterface4.m3()");
x();
};
}
// 2) 인터페이스 구현
class MyInterface4Impl implements MyInterface4 {
@Override
public void m1() {
// 인터페이스에 선언된 오버라이딩 전의 default 메서드를 호출하고 싶다면,
// super.m2(); // 수퍼 클래스(Object)에서 m2()를 찾아 올라간다. Object에는 m2()가 없기 때문에 컴파일 오류!
// MyInterface4.m2(); // m2()는 인스턴스(non-static) 메서드이기 때문에 인터페이스 이름으로 직접 호출 불가!
MyInterface4.super.m2();
System.out.println("MyInterface4Impl.m1()");
}
@Override
public void m2() {
System.out.println("MyInterface4Impl.m2()");
}
}
public class Exam04 {
public static void main(String[] args) {
MyInterface4 obj = new MyInterface4Impl();
obj.m1();
System.out.println("-----------------------------");
obj.m2();
System.out.println("-----------------------------");
obj.m3();
System.out.println("-----------------------------");
}
}
2.3 기타 메서드
- 인터페이스 필드
- 인터페이스의 필드는 public static final이다.
- 인스턴스를 생성 할 수 없기 때문에 무조건 상수만 사용 가능이다.
- private 메서드
- 인터페이스 내부에서 사용할 매서드고 private로 정의한다.
interface MyInterface4 {
void m1();
default void m2() {
System.out.println("MyInterface4.m2()");
x();
};
default void m3() {
System.out.println("MyInterface4.m3()");
x();
};
// 인터페이스 내부에서 사용할 메서드라면
// private 접근 범위를 갖는
// 구현 메서드를 정의할 수 있다.
// 언제?
// - 해당 기능을 m2()와 m3() 처럼 여러 메서드에서 사용해야 할 경우
// 그 공통 코드를 다음과 같이 private 구현 메서드로 정의하면 될 것이다.
//
private void x() {
System.out.println("MyInterface4.x()");
}
}
3. 인터페이스의 활용
3.1 인터페이스의 상속
상속, 인터페이스 관계 | case 1. | case 2. | case 3. |
My obj = new My(); obj.m1(); obj.m2(); obj.X(); |
B obj = new My(); obj.m1(); obj.m2(); |
A obj = new My(); obj.m1(); |
3.2 인터페이스의 다중상속
- 여러개의 인터페이스를 상속 받아 인터페이스를 만들수 있다.
- 상속받는 인터페이스에서 리턴타입이 같은 메소드명을 상속 받을 수 있다.
- 리턴타입이 같은 메소드명을 받을 수 있는 이유는 상속받는 메소드가 추상메서드 이기 때문에 가능하다.
- 반대로 리턴 타입이 다르면 컴파일러는 두 메소드를 구분 할 수 없어 상속이 불가능하다.
3.3 인터페이스의 다중구현
- 같은 원리로 구현부 역시 여러개의 인터페이스를 받을 수 있다.
'개발자 꿈나무의 하루 > 01_Boot Camp' 카테고리의 다른 글
(네이버클라우드 부트캠프) 30일차 - 실습프로젝트(리팩토링) (0) | 2024.07.08 |
---|---|
(네이버클라우드 부트캠프) 30일차 - 토이프로젝트(ToDoList만들기) (0) | 2024.07.05 |
(네이버클라우드 부트캠프) 28일차 - Java프로그래밍 기초(추상클래스, 인터페이스,캡슐화) (0) | 2024.07.03 |
(네이버클라우드 부트캠프) 26일차 - Java프로그래밍 기초(상속) (0) | 2024.07.01 |
(네이버클라우드 부트캠프) 24_25일차 - 미니프로젝트 가계부만들기 (0) | 2024.07.01 |