디폴트 메서드와 Static 메서드
인터페이스가 변경되지 않으면 제일 좋겠지만, 아무리 설계를 잘해도 언젠가 변경은 발생하기 마련이다.
JDK 설계자들은 고심 끝에 디폴트 메서드(default method)라는 것을 고안해내었다. 디폴트 메서드는 추상 메서드의 기본적인 구현을 제공하는 메서드로, 추상 메서드가 아니기 때문에 디폴트 메서드가 새로 추가되어도 해당 인터페이스를 구현한 클래스를 변경하지 않아도 된다.
위의 왼쪽과 같이 newMethod()라는 추상 메서드를 추가하는 대신, 오른쪽과 같이 디폴트 메서드를 추가하면, 기존의 MyInterface를 구현한 클래스를 변경하지 않아도 된다.
1. 여러 인터페이스의 디폴트 메서드 간의 충돌
- 인터페이스를 구현한 클래스에서 디폴트 메서드를 오버라이딩해야 한다.
2. 디폴트 메서드와 조상 클래스의 메서드 간의 충돌
- 조상 클래스의 메서드가 상속되고, 디폴트 메서드는 무시 된다.
내부 클래스(Inner Class)
내부 클래스는 클래스 내에 선언된 클래스이다. 클래스에 다른 클래스를 선언하는 이유는 두 클래스가 서로 긴밀한 관계에 있기 때문이다.
내부 클래스의 장점
- 내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근할 수 있다.
- 코드의 복잡성을 줄일 수 있다(캡슐화)
아래 왼쪽의 A와 B 두 개의 독립적인 클래스를 오른쪽과 같이 바꾸면 B는 A의 내부 클래스(inner class)가 되고 A는 B를 감싸고 있는 외부 클래스(outer class)가 된다.
이때 내부 클래스인 B는 외부 클래스인 A를 제외하고 다른 클래스에서 잘 사용되지 않는 것이어야 한다.
내부 클래스 종류와 특징
내부 클래스의 종류는 변수의 선언 위치에 따른 종류와 같다.
내부 클래스 특징
내부 클래스 | 특징 |
인스턴스 클래스 (instance class) |
외부 클래스의 멤버변수 선언 위치에 선언하며, 외부 클래스의 인스턴스 멤버처럼 다루어진다. 주로 외부 클래스의 인스턴스멤버들과 관련된 작업에 사용될 목적으로 선언된다. |
스태틱 클래스 (static class) |
외부 클래스의 멤버변수 선언위치에 선언하며, 외부 클래스의 static멤버처럼 다루어 진다. 주로 외부 클래스의 static멤버, 특히 static 메서드에서 사용될 목적으로 선언된다. |
지역 클래스 (local class) |
외부 클래스의 메서드나 초기화 블럭 안에 선언하며, 선언된 영역 내부에서만 사용될 수 있다. |
익명 클래스 (anonymous class) |
클래스의 선언과 객체의 생성을 동시에 하는 이름 없는 클래스(일회용) |
내부 클래스의 선언
아래의 오른쪽 코드에는 외부 클래스(Outer)에 3개의 서로 다른 종류의 내부 클래스가 선언되어 있다. 양쪽의 코드를 비교해 보면 내부 클래스의 선언 위치가 변수의 선언 위치와 동일함을 알 수 있다.
각 내부 클래스의 선언 위치에 따라 같은 선언 위치의 변수와 동일한 유효 범위(scope)와 접근성(accessibility)을 갖는다
내부 클래스의 제어자와 접근성
아래 코드에서 인스턴스 클래스(InstanceInner)와 스태틱 클래스(StaticInner)는 외부 클래스(Outer)의 멤버 변수(인스턴스 변수와 클래스 변수)와 같은 위치에 선언되며, 또한 멤버 변수와 같은 성질을 갖는다. 따라서 내부 클래스가 외부 클래스의 멤버와 같이 간주되고, 인스턴스 멤버와 static멤버 간의 규칙이 내부 클래스에도 똑같이 적용된다.
내부 클래스도 클래스이기 때문에 abstract나 final과 같은 제어자를 사용할 수 있을 뿐만 아니라, 멤버 변수들처럼 private, protected과 접근 제어자도 사용이 가능하다.
익명 클래스(Anonymous Class)
익명 클래스는 특이하게도 다른 내부 클래스들과는 달리 이름이 없다. 클래스의 선언과 객체의 생성을 동시에 하기 때문에 단 한 번만 사용될 수 있고 오직 하나의 객체만을 생성할 수 있는 일회용 클래스이다.
new 조상클래스이름() {
// 멤버 선언
}
또는
new 구현인터페이스이름() {
// 멤버 선언
}
이름이 없기 때문에 생성자도 가질 수 없으며, 조상 클래스의 이름이나 구현하고자 하는 인터페이스의 이름을 사용해서 정의하기 때문에 하나의 클래스로 상속받는 동시에 인터페이스를 구현하거나 둘 이상의 인터페이스를 구현할 수 없다. 오로지 단 하나의 클래스를 상속받거나 단 하나의 인터페이스만을 구현할 수 있다.
class Ex7_17 {
Object iv = new Object(){ void method(){} }; // 익명 클래스
static Object cv = new Object(){ void method(){} }; // 익명 클래스
void myMethod() {
Object lv = new Object(){ void method(){} }; // 익명 클래스
}
}
'Server > 자바의정석' 카테고리의 다른 글
[Java 입문] try - catch - finally (0) | 2022.09.30 |
---|---|
[Java 입문] 오류 & 예외 (4) | 2022.09.29 |
[Java 입문] 추상(abstract) & 인터페이스(Interface) (0) | 2022.09.28 |
[Java 입문] 다형성(polymorphism) (0) | 2022.09.28 |
[Java 입문] 제어자(modifier), 캡슐화 (0) | 2022.09.28 |