IT 개발노트

인터페이스란? 본문

기초튼튼/JAVA

인터페이스란?

limsungju 2019. 1. 28. 14:10

1. 인터페이스
1.1 인터페이스란?

- 인터페이스(interface)는 일종의 추상클래스이며 추상클래스보다 추상화 정    도가 더 높다.
- 추상클래스를 미완성 설계도로 비유한다면 인터페이스는 기본 설계도에 비    유할 수 있다.
- 인터페이스는 다른 클래스 작성에 도움을 주거나 서로 무관한 클래스들에게    관계를 맺어줄 목적으로 사용된다.

1.2 인터페이스의 특징
- class 키워드 대신 interface 키워드를 사용하여 정의
- 인스턴스 생성 불가
- 모든 멤버변수에는 public static final 제어자가 붙는다(생략 가능)
- 모든 메서드는 public abstract 제어자가 붙는다(생략 가능)
* 제어자 생략시 컴파일러가 자동으로 추가

1.3 인터페이스 생성

1
2
3
4
interface [인터페이스명] {
public static final 타입 상수명 = 값;
public abstract 메서드명(매개변수);
}


1.4 인터페이스의 상속
- 인터페이스는 인터페이스만 상속받을 수 있으며 추상클래스와는 달리 여러    개의 인터페이스에 대해 다중 상속이 가능하다.
- 인터페이스의 상속에는 extends 키워드를 사용한다.

예시 1

1
2
3
4
5
6
7
8
9
10
11
12
interface Movable {
    void move(int x, int y);
}
 
interface Attackable {
    void attack(Unit unit);
}
 
interface Fightable extends Movable, Attackable {
    int x = 10;
    int y = 20;
}


* 인터페이스는 Object클래스와 같은 최고 조상이 없다.
* 인터페이스는 다중 상속을 위한 기능이 아니므로 자바에서 인터페이스로 다    중 상속을 구현하는 경우는 거의 없다.

1.5 인터페이스의 구현
- 인터페이스는 추상클래스처럼 그 자체로 인스턴스 생성이 불가능하다.
  -> 추상메서드를 모두 구현하여 사용해야 한다.
- implements 키워드를 사용하여 인터페이스를 구현한다.

예시 2

1
2
3
class [클래스명] implements [인터페이스명] {
// 추상 메서드를 모두 구현.
}


* 인터페이스의 추상 메서드를 모두 구현하지 않은 경우, 해당 클래스에            abstract 키워드를 붙여서 추상클래스로 만들어야 한다.

예시 3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
interface Fightable {
    void move(int x, int y);
    void attack(Unit unit);
}
 
class Fighter implements Fightable {
    public void move(int x, int y) {
        // 내용
    }
 
    public void attack(Unit unit) {
        // 내용
    }
}


- 구현한 메서드에는 public제어자를 붙여줬는데 인터페이스의 추상 메서드      제어자가 public abstract이므로 이에 맞춰서 붙여준 것이다.

예시 4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
interface Movable {
    void move(int x, int y);
}
 
abstract class Attack {
    abstract public void attack(Unit unit);
}
 
class Fighter extends Attack implements Movable {
    public void move(int x, int y) {
        // 내용
    }
 
    public void attack(Unit unit) {
        // 내용
    }
}


- 예시 4처럼 상속과 구현을 동시에 하는 것도 가능하다.

1.6 인터페이스의 다형성
- 다형성의 특징처럼 부모타입의 참조변수로 자식 클래스의 인스턴스를 참조    하는 것이 인터페이스에서도 가능하다.

1.6.1 인터페이스 다형성의 특징
- 인터페이스 타입의 참조변수로 구현한 클래스의 인스턴스 참조 가능
- 인터페이스 타입으로 형변환 가능
- 인터페이스에도 매개변수의 다형성 특징이 적용
- 메서드의 리턴타입으로 인터페이스 타입 지정 가능

예시 5

1
Fightable fightable = (Fightable) new Fighter();


- 인터페이스 타입의 참조변수로 구현한 클래스의 인스턴스 참조가 가능하다.
- Fightable 타입의 참조변수로는 Fightable 인터페이스에 정의된 멤버만 호출    이 가능하다.

예시 6

1
2
3
4
Fightable method() {
Fighter fighter = new Fighter();
return fighter;
}


- 메서드의 리턴타입으로 인터페이스 타입을 지정하는 것이 가능하다.
- 예시 6의 경우 메서드의 리턴타입이 인터페이스이기 때문에 return문에서      인터페이스를 구현한 클래스의 인스턴스를 반환하는 것을 확인할 수 있다.
* 메서드의 리턴타입이 인터페이스인 경우, 해당 인터페이스를 구현한 클래스    의 인스턴스를 반환한다는 것을 의미한다.

1.7 인터페이스의 장점
- 개발시간 단축된다.
  -> 메서드 내용과 관계없이 선언부만 알면 개발이 가능하다.
  -> 양쪽에서 동시에 개발 진행이 가능하다.
- 표준화가 가능하다.
  -> 기본 틀을 인터페이스로 작성한다.
  -> 일관되고 정형화된 프로그램 개발이 가능하다.
- 서로 무관한 클래스들에게 관계를 맺어준다.
  -> 하나의 인터페이스를 공통으로 구현하도록 하여 관계를 맺어준다.
- 독립적인 프로그래밍이 가능
  -> 인터페이스를 이용하면 클래스 간의 관계를 간접적으로 구성하는 것이          가능하다.

1.8 인터페이스의 이해
- 클래스에 대해서 User(사용자)와 Provider(제공자)가 있다.
- User(사용자)에서는 Provider(제공자) 메서드의 선언부만 알면된다.
- 클래스간의 관계에서 직접적인 관계의 경우 한쪽이 변경되면 다른 한쪽도      변경되어야 하는 단점을 가지고 있다. 그러나 인터페이스를 매개체로 한 간    접적인 관계의 경우 한쪽이 변경되어도 다른 한쪽은 전혀 영향을 받지 않는    다.

예시 7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 클래스 B의 메서드를 추상 메서드로 정의한 인터페이스 I
interface I {
    public abstract void methodB();
}
 
// 클래스 B가 인터페이스 I를 구현
class B implements I {
    public void methodB() {
        System.out.println("methodB in B class");
    }
}
 
// 클래스 A는 인터페이스 I를 사용 가능
class A {
    public void methodA(I i) {
        i.methodB();
    }
}


- 예시 7은 'A-I-B'의 간접적인 관계로 구성되었으며 클래스 A는 인터페이스 I    하고만 직접적인 관계가 있기 때문에 클래스 B의 변경에 영향을 받지 않는      다.

- 클래스 A는 직접적인 관계의 인터페이스 I의 영향만 받기 때문에 실제로 사    용되는 클래스명을 몰라도 되고 구현된 클래스가 존재하지 않아도 문제가      되지 않는다.

- 인터페이스 I는 클래스 B를 감싸고 있는 껍데기이며 클래스 A는 인터페이스    I 안에 어떤 클래스가 구현되어 있는지 몰라도 되는 관계가 된다.

1.9 디포틀 메서드와 static 메서드
- 인터페이스는 원래 상수와 추상메서드만을 멤버로 가졌었는데 JDK1.8 이후    디폴트 메서드와 static 메서드도 추가할 수 있게 되었다.
- static 메서드는 인스턴스와 무관한 독립적인 메서드이기 때문에 인터페이스    에 추가 못할 이유가 없었지만, 자바의 규칙을 단순화하기 위해 인터페이스    의 모든 메서드를 추상 메서드로 제한하여 제외되었습니다.
- 인터페이스의 static 메서드는 접근제어자도 마찬가지로 항상 public이며 생    략이 가능하다.
- 디폴트 메서드는 추상 메서드와 static 메서드 외에 인터페이스에 추가할 수    있는 메서드이며, 인터페이스에 추가해도 구현한 클래스의 변경없이 사용이    가능하다.

예시 8

1
2
3
4
5
interface I {
    public abstract void abstractMethod();
    public default void defaultMethod() {
    }
}


- 예시 8과 같이 default 키워드를 앞에 붙여서 사용한다.
- 디폴트 메서드 역시 접근제어자가 public이며 생략이 가능하다.
- 디폴트 메서드의 경우 기존의 메서드와 메서드명이 중복되는 경우가 발생하는데, 이에 대한 규칙은 아래와 같다.
1. 여러 인터페이스 구현시 디폴트 메서드명이 같은 경우
-> 인터페이스를 구현한 클래스에서 디폴트 메서드를 오버라이딩 해야한다.
2. 부모 클래스의 메서드와 디폴트 메서드명이 같은 경우
-> 부모 클래스의 메서드가 상속되고 디폴트 메서드는 무시된다.

예제 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class DefaultMethodTest {
    public static void main(String[] args) {
        Child child = new Child();
        child.method1();
        child.method2();
        Interface1.staticMethod();
        Interface2.staticMethod();
    }
}
 
class Parent {
    // 인터페이스 Inteface1의 디폴트 메서드와 메서드명이 같으므로
    // 부모 클래스의 메서드가 상속됨.
    public void method2() {
        System.out.println("method2() in Parent");
    }
}
 
class Child extends Parent implements Interface1, Interface2{
    // 인터페이스 Interface1, Interface2의 디폴트 메서드명이 같으므로
    // 아래와 같이 구현한 클래스에서 오버라이딩 해줌.
    public void method1() {
        System.out.println("method1() in Child");      
    }
}
 
interface Interface1 {
    default void method1() {
        System.out.println("method1() in Interface1");     
    }
 
    default void method2() {
        System.out.println("method2() in Interface1");     
    }
 
    static void staticMethod() {
        System.out.println("staticMethod() in Interface1");    
    }
}
 
interface Interface2 {
    default void method1() {
        System.out.println("method1() in Interface2");     
    }
 
    static void staticMethod() {
        System.out.println("staticMethod() in Interface2");    
    }
}



'기초튼튼 > JAVA' 카테고리의 다른 글

예외처리  (0) 2019.01.30
내부 클래스란?  (0) 2019.01.29
추상클래스란?  (0) 2019.01.27
다형성이란?  (0) 2019.01.26
제어자란?  (0) 2019.01.25