- 인터페이스 정의하는 방법
- 인터페이스 구현하는 방법
- 인터페이스 레퍼런스를 통해 구현체를 사용하는 방법
- 인터페이스 상속
- 인터페이스 기본 메서드(Default Method), 자바8
- 인터페이스 static 메서드, 자바8
- 인터페이스의 private 메소드, 자바9
인터페이스는 추상클래스보다 추상화 정도가 높은 개념. (추상 클래스의 일종)
-
멤버변수는 모두
상수형(public static final)으로 선언되어야 한다. -
메서드는 모두
추상 메서드(public abstract)로 선언되어야 한다. -
하지만, Java8이후 부터
default Method와static Method가 추가 되었다.- default method와 static method는
구현부가 존재한다.
public interface Flyable { //상수(public static final) 타입 상수명 = 값; //추상 메서드 (pulbic abstract) 타입 메서드명(매개변수, ...); //default 메서드 (구현부가 있다!) default 타입 메서드명(매개변수, ..) {} //정적 메서드 (구현부가 있다!) static 타입 메서드명(매개변수, ...) {} }
- 상수(절대적) : 인터페이스에 값을 정해줄테니 제공해주는 값만 참조하라.
- 추상 메서드(강제적) : 가이드를 제공할테니 구현해서 사용하라.
- 디폴드 메서드(선택적) : 메서드를 선택해서 사용해서 된다. (맘에 들지 않으면 재정의(Override)하면 된다.)
- 스태틱 메서드(절대적) : 인터페이스에서 제공해주는 것으로 무조건 사용
- default method와 static method는
- 추상(abstract) :
is-a관계- 클래스 계층구조에서
안정성제공 - 클래스의 상속 관계에서 결합도가 높다.
- 부모 클래스의 명세 변경 시, 코드 손상될 우려가 있다.
- 클래스 계층구조에서
-
인터페이스(interface) :
has-a관계-
생성된 클래스 간 결합도가 낮다.
-
상속에 비해 명세 변경시, 구성 요소를 쉽게 변경할 수 있다.(유연성 제공)
-
-
ex) Cooper는 Person(사람)이면서 개발할 수 있다.(Developable)
class Cooper extends Person implements Developable {}
- 인터페이스는
implements라는 키워드를 통해서 구현한다. - 하나의 클래스(추상 클래스)는 여러 개의 인터페이스로부터 상속을 받는 것이 가능하다. 즉,
다중 상속이 가능하다.
public interface Animal {
void sound();
public void sleep() {
System.out.println("잠을 잔다...");
}
}
public class Dog implements Animal {
@Override
public void sound() {
System.out.println("멍멍");
}
}
public class Cat implements Animal {
@Override
public void. sound() {
System.out.println("야옹");
}
}
public class AnimalTest {
public static void main(String[] args) {
Animal dog = new Dog();
dog.sound();
dog.sleep();
//멍멍
//잔다...
}
}-
interface의 변수는
static final을 암묵적으로 표시하고 있다. -
interface를 사용하는 목적은 규약을 정의하기 위해 입력한 것이다.
-
만약 상수를 모아두고 싶다면
class로 선언하자.public class Constants { public static final int NUMBER = 100; public static final String NAME = "keesun"; //private default constructor를 이용해서 인스턴스화 차단 private Constants() {} }
- 인터페이스 레퍼런스을 통해서 객체를 담을 수 있는 방식이다.
- 인터페이스 레퍼런스를 통해 구현체를 만들면
약한 결합이 가능하다.
-
의존성(dependency) : A가 변경하고자 할 때, B를 변경 여부. (true, false)
-
결합도(coupling) : A를 변경할 때, B를 변경해야하는 정도.(높다/낮다)
-
강한 결합: A를 변경할 때, B를 변경해야 하는 요소가 많은 형태.(B는 A에게 강한 의존성을 가지고 있다)
-
약한 결합: A를 변경할 때, B를 변경해야하는 요소가 적은 형태.(B는 A에게 약한 의존성을 가지고 있다)
-
-
강한 결합 예시
class Person {
private Chicken chicken; //chicken->pizza로 변경 시, 변경
public Person() {
this.chicken = new Chicken(); //chicken->pizza로 변경 시, 변경
}
public void eatFood() {
chicken.eat();//chicken->pizza로 변경 시, 변경
}
}
class Chicken {
void eat() {
System.out.println("eat chicken");
}
}- 약한 결합 예시
interface Food {
void eat();
}
//chicken class
class Chicken imiplements Food {
@Override
public void eat() {
System.out.println("치킨를 먹는다");
}
}
//pizza class
class Pizza implements Food {
@Override
public vod eat() {
System.out.println("피자를 먹는다")
}
}class Person {
private Food food; //변경할 필요X
public Person(Food food) {//변경할 필요X (파라미터만 입력하면 됨)
this.food = food;
}
public void eatFood() {
food.eat();//변경할 필요X
}
}- 인터페이스는 오직
인터페이스로 부터다중 상속(확장)이 가능하다.- 다중 상속 의미는 상위로 여러 인터페이스 받아 확장할 수 있다는 의미(extends, implements 둘다)
- 서브 인터페이스는 슈퍼 인터페이스의 메서드(abstract)까지 모두 구현해야 한다.
- 인터페이스 레퍼런스는 인터페이스를 구현한 클래스의 인스턴스를 가리킬 수 있고 해당 인터페이스에 선언된 메서드만 호출할 수 있다.
public interface Movable {
void move();
}
public interface Sleepable {
void sleep();
}
public interface Animal extends Movable, Sleepable {
}
public class Dog implements Animal {
@Override
public void move() {
System.out.println("네발로 움직임");
}
@Override
public void sleep() {
System.out.println("꿀잠zzzzZ");
}
}-
인터페이스는 메서드 선언이 아니라
구현부(body)를 제공하는 방법 -
과거 인터페이스에 기본 메서드가 제공되지 않았을 때,
-
중간에 추상 클래스를 만들어서, 추상 클래스를 확장하는 구현체에서는 필요한 메서드만 구현할 수 있도록 하였다.
-
기본메서드가 도입된 이후, 별도의 추상 클래스가 필요없이도 구현이 가능하게 되었다.
- 과거 방식에서는 추상 클래스를 상속받기 때문에
상속에 자유롭지 못했다. - 각 구현체는 interface를 구현한 것임으로
상속에 유리하다.
- 과거 방식에서는 추상 클래스를 상속받기 때문에
-
예시 : HandlerInterceptor(In Spring)
public interface HandlerInterceptor { default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { } }
public interface JoinGroup {
default void preJoin() {
System.out.println();
}
}
public interface joinMember {
default void preJoin() {
System.out.println();
}
default void afterJoin() {
System.out.println("after join group");
}
}
public class HelloJoinMember implements JoinMember, JoinGroup {
@Override
public void preJoin() {
joinMember.super.preJoin(); //상위 메서드 선택
joinGroup.super.preJoin();
}
}interface Dancable {
void fly() ;
}
interface Flyable {
default void fly() {}
}
interface Child extends Dancable,Flyable {
// 시그니처 중복이기 때문에 추가적으로 Overriding이 필요하다.
@Override
default void fly() {
Flyable.super.fly();
}
}-
인스턴스 없이
인스턴스 타입으로만 메서드 선언이 가능한 메서드. -
형태
static 타입 메서드명(매개변수, ...) {}
-
예제1. static과 default의 메서드명이 같은 경우?
interface grandFatherI { static void methodCall () { System.out.println("static method!!"); } } interface fatherI extends grandFatherI { default void methodCall() { System.out.println("defualt method!!"); } } class childC implement fatherI { } class Test { public static void main(String[] args) { new childC().methodCall(); // default method!! childC.methodCall(); // static method!! } }
- 자바9 이전에는 모든 메서드들은 무조건
public이어야 했다. - 자바9 이후부터, 접근 제이자
private method,private static method키워드 추가. - private : class 내부에서만 사용가능한 접근 제어자.
interface Operator {
private int add (int a, int b) {
return a + b; //구현부가 존재!
}
private static int multiply(int a, int b) {
return a * b;//구현부가 존재!
}
}

