1. 인터페이스(Interface)
1) 인터페이스란?
- 일종의 추상 클래스
- 추상클래스처럼 추상메서드를 갖지만 추상화 정도가 더 높음
- 오직 '추상메서드'와 '상수'만을 멤버로 가짐
2) 인터페이스의 작성
interface 인터페이스이름 {
public static final 타입 상수이름 = 값;
public abstract 메서드이름(매개변수목록);
}
- 모든 멤버변수는 public static final이어야 하며, 이를 생략할 수 있음
- 모든 메서드는 public abstract이어야 하며, 이를 생략할 수 있음
(단, static 메서드와 디폴트 메서드는 예외(JDK1.8부터))
interface PlayingCard {
// 생략 가능하기 때문에 모두 사용 가능
public static final int SPADE = 4;
final int DIAMOND = 3;
static int HEART = 2;
int CLOVER = 1;
// static메서드와 디폴트 메서드를 제외하고 생략 가능
public abstract String getCardNumber();
String getCardKind();
}
3) 인터페이스의 상속
- 인터페이스는 인터페이스로부터만 상속받을 수 있음
- 클래스와 달리 다중상속 가능
interface Movable {
void move(int x, int y);
}
interface Attackable {
void attack(Unit u);
}
interface Fightable extends Movable, Attackable { }
4) 인터페이스의 구현
- 자신의 정의된 추상메서드의 몸통을 만들어주는 클래스를 작성해야 함
- 추상클래스가 'extends'를 사용하는 반면, 인터페이스는 'implements'를 사용함
- 오버라이딩할 때는 조상의 메서드보다 넓은 범위의 접근 제어자를 지정해야 함
class 클래스이름 implements 인터페이스이름 {
// 인터페이스에 저장된 추상메서드 구현
}
class Fighter implementes Fightable {
public void move(int x, int y) { /* 구현 */ }
public void attack(int x, int y) { /* 구현 */ }
}
// 인터페이스의 메서드 중 일부만 구현한다면 abstract를 붙여 추상클래스로 구현해야 함
abstract class Fighter implementes Fightable {
public void move(int x, int y) { /* 구현 */ }
}
// 상속과 구현 동시에 가능
class Fighter extends Unit implementes Fightable {
public void move(int x, int y) { /* 구현 */ }
public void attack(int x, int y) { /* 구현 */ }
}
5) 인터페이스를 이용한 다중상속
- 두 개의 클래스로부터 상속받아야 할 경우
① 두 조상클래스 중 비중이 높은 쪽을 선택
② 다른 한쪽은 클래스 내부에 멤버로 포함 or 필요한 부분을 뽑아서 인터페이스로 만든 후 구현
6) 인터페이스를 이용한 다형성
- 인터페이스도 클래스와 같이 다형성을 가짐
- 인터페이스 타입의 참조변수로 이를 구현한 클래스의 인스턴스를 참조할 수 있음
- 인터페이스 타입의 형변환 가능
- 메서드의 매개변수 타입으로 인터페이스 사용 가능 (단, 호출 시 인터페이스를 구현한 클래스의 인스턴스를 넘겨줘야 함)
- 리턴타입으로 인터페이스 사용 가능 (메서드가 해당 인터페이스를 구현한 클래스의 인스턴스를 반환함)
interface Fightable { ... }
class Fighter implements Fightable { ... }
class Main {
...
Fightable f = (Fightable)new Fighter();
또는
Fightable f = new Fighter();
}
7) 인터페이스의 장점
① 개발시간 단축
- 인터페이스가 작성되면 이를 사용해서 프로그램을 작성 가능 (선언부만 알면 되기 때문)
② 표준화 가능
- 프로젝트에 사용되는 기본 틀을 인터페이스로 작성하여 일관되고 정형화된 개발 가능
③ 서로 관계없는 클래스에 관계를 맺어줄 수 있음
- 하나의 인터페이스를 공통적으로 구현하도록 함으로써 관계를 맺어줄 수 있음
④ 독립적인 프로그래밍
- 실제 구현에 독립적인 프로그램 작성 가능
- 한 클래스의 변경이 관련된 다른 클래스에 영향을 미치지 않음
8) 인터페이스의 이해
- 클래스 사용자(User) / 클래스 제공자(Provider)
- 메서드를 사용(호출)하는 쪽(User)에서는 사용하려는 메서드(Provider)의 선언부만 알면 됨
9) 디폴트 메서드, static 메서드
- JDK1.8부터 추상 메서드뿐만 아니라 디폴트 메서드와 static 메서드 추가 가능
① 디폴트 메서드(default method)
- 추상 메서드의 기본적인 구현을 제공하는 메서드
- 디폴트 메서드가 새로 추가되어도 해당 인터페이스를 구현한 클래스를 변경하지 않아도 됨
interface MyInterface {
void method();
default void newMethod();
}
- 여러 인터페이스의 디폴트 메서드 간의 충돌?
-> 인터페이스를 구현한 클래스에서 디폴트 메서드를 오버라이딩해야 함
- 디폴트 메서드와 조상 클래스의 메서드 간의 충돌?
-> 조상 클래스의 메서드가 상속되고, 디폴트 메서드는 무시됨
② static 메서드
- 접근 제어자가 항상 public임
- 생략할 수 있음
2. 내부 클래스(inner class)
1) 내부 클래스란?
- 클래스 내에 선언된 클래스
- 두 클래스는 서로 긴밀한 관계에 있음
내부 클래스의 장점
- 내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근할 수 있음
- 코드의 복잡성을 줄일 수 있음 (캡슐화)
class A { // 외부 클래스
...
class B { // 내부 클래스
...
}
}
2) 내부 클래스의 종류와 특징
- 내부 클래스는 선언위치에 따라 4가지로 구분됨 (변수의 선언위치에 따른 종류와 유사)
내부 클래스 | 특 징 |
인스턴스 클래스 (instance class) |
- 외부 클래스의 멤버변수 선언위치에 선언 - 외부 클래스의 인스턴스멤버처럼 다뤄짐 - 주로 외부 클래스의 인스턴스멤버들과 관련된 작업에 사용될 목적 |
스태틱 클래스 (static class) |
- 외부 클래스의 멤버변수 선언위치에 선언 - 외부 클래스의 static멤버처럼 다뤄짐 - 주로 외부 클래스의 static멤버(특히 static메서드)에서 사용될 목적 |
지역 클래스 (local class) |
- 외부 클래스의 메서드나 초기화블럭 안에 선언 - 선언된 영역 내부에서만 사용 가능 |
익명 클래스 (anonymous class) |
- 클래스의 선언과 객체의 생성을 동시에 하는 이름없는 클래스 (일회용) |
3) 내부 클래스의 선언
- 변수의 선언위치와 동일
- 각 내부 클래스의 선언위치에 따라 같은 선언위치의 변수와 동일한 유효범위(scope)와 접근성(accessibility)를 가짐
4) 내부 클래스의 제어자와 접근성
- 인스턴스 클래스(InstanceInner)와 스태틱 클래스(StaticInner)는 외부 클래스(Outer)의 멤버변수(인스턴스변수, 클래스변수)와 같은 위치에 선언되며 같은 성질을 가짐
- 내부 클래스가 외부 클래스의 멤버와 같이 간주됨
- 즉, 인스턴스멤버와 static멤버 간의 규칙이 내부 클래스에도 적용
- 클래스이므로 제어자(abstract, final 등)와 접근제어자(private, public 등) 사용 가능
- 컴파일 시 생성되는 파일명은 '외부 클래스명$내부 클래스명. class'
5) 익명 클래스(anonymous class)
- 이름이 없는 클래스
- 클래스의 선언과 객체의 생성을 동시에 함
- 단 한번만 사용될 수 있고 오직 하나의 객체만을 생성할 수 있는 일회용 클래스
- 오직 단 하나의 클래스를 상속받거나 단 하나의 인터페이스만 구현할 수 있음
- 이름이 없기 때문에 파일명은 '외부 클래스명$숫자.class'
class Ex {
Object iv = new Object() { void method() {} }; // 익명 클래스
static Object cv = new Object() { void method() {} }; // 익명 클래스
void myMethod() {
Object lv = new Object() { void method() {} }; // 익명 클래스
}
}
-> 컴파일하면 4개의 클래스 파일이 생성
Ex.class
Ex$1.class
Ex$2.class
Ex$3.class
참고 - Java의 정석 3rd Edition (저자 : 남궁성, 출판 : 도우출판)
'공부 > Java' 카테고리의 다른 글
[Java-09] java.lang패키지 - Object클래스 (0) | 2021.03.05 |
---|---|
[Java-08] 예외처리(Exception Handling) (0) | 2021.03.04 |
[Java-07] 객체지향프로그래밍Ⅱ - 다형성, 추상클래스 (0) | 2021.03.02 |
[Java-07] 객체지향프로그래밍Ⅱ - 패키지, import문, 제어자 (0) | 2021.02.24 |
[Java-07] 객체지향프로그래밍Ⅱ - 상속, 오버라이딩 (0) | 2021.02.22 |