개발저장소
[Java] 추상 클래스와 인터페이스 본문
abstract 제어자
'추상적인' 이라는 뜻. 추상 메서드나 추상 클래스에 사용된다.
구체적이지 않은 메서드를 추상 메서드라고 하며 이를 하나라도 포함하는 클래스를 추상 클래스라고 한다.
추상 메서드는 중괄호가 존재하지 않아 기능이 정의되지 않는다. 어떤 기능을 정의하지 않은 미완성 메서드라고 볼 수 있다.
abstract 리턴 타입 메서드명 (); 과 같은 구조를 가진다.
abstract를 사용하지 않더라고 충분히 상속과 오버라이딩을 사용할 수 있다. 하지만 추상 클래스를 상속 받은 자식 클래스는 반드시 추상 메서드를 오버라이딩 해야 한다는 특징이 있다. 자식 클래스로 하여금 확장을 유도하도록 하는 이점이 생긴다. abstract를 사용하면 자식 클래스에서 무조건 메서드를 오버라이딩해서 재정의해야하므로 오류를 찾기 용이하다.
1. 추상 클래스
추상 메서드는 메서드의 본체가 완성되지 않은 미완성 메서드이다. 추상 클래스는 추상 메서드를 1개 이상 포함하고 있는 클래스이다. 추상 클래스는 추상 메서드와 마찬가지로 abstract를 붙여 표현한다.
추상 클래스는 미완성 메서드 때문에 인스턴스를 직접 생성할 수 없다. 하지만 추상 클래스를 상속 받은 자식 클래스는 반드시 미완성 메서드를 오버라이딩해서 완성해야 한다. 이를 구현(implements)이라고 한다.
abstract class A {
abstract void abc();
}
class B extends A {
void abc() {
}
}
추상 클래스 타입의 인스턴스 생성 방법
추상 클래스 자체는 직접 인스턴스 생성이 불가능하지만, 자식 클래스를 통하여 추상 클래스의 타입으로 선언할 수 있다.
첫번째 방법은 추상 클래스를 일반 클래스로 상속해 인스턴스를 생성하는 것이다.
A a = new B(), B b = new B() 방법으로 선언할 수 있다.
두번째는 익명 이너 클래스를 사용하는 것이다.
A a = new A() {
void abc() {
...
}
};
2. 인터페이스
인터페이스는 모든 필드가 public static final, 그리고 static, default 이외의 모든 메서드가 public abstract로 정의된 프로그래밍 요소이다. class 대신 interface 키워드로 선언한다.
interface A {
public static final int a = 3;
public abstract void abc();
}
// 이렇게 생략할 수도 있다
interface A {
int a = 3;
void abc();
}
제어자를 생략하더라도 컴파일러가 자동으로 삽입한다. static이 붙은 필드는 A.a로 접근이 가능하지만 final이 붙어있기 때문이 수정은 불가능하다.
인터페이스의 구현
인터페이스의 가장 큰 특징은 다중 상속이 가능하다는 것이다.
interface A {}
interface B {}
class C implements A, B {}
클래스가 다중 상속이 불가능한 이유는 동일한 필드나 메서드의 충돌 때문이다. 하지만 인터페이스는 모든 필드가 public static final로 정의되어 있기 때문에 실제 데이터는 저장 공간이 분리되어 인터페이스 내부에 존재한다. 메서드도 모두 미완성이기 때문에 자식 클래스에서 완성해야 한다. 자식 클래스의 완성 메서드는 public만 가능하다. 인터페이스의 미완성 메서드는 public이고, 구현한 클래스에서 메서드는 좁은 범위로 선언할 수 없기 때문이다.
인터페이스의 필요성
인터페이스는 입출력의 호환성을 의미한다. 변경이 가능한 인스턴스는 인터페이스로 구현하고 업캐스팅을 사용하는 것이 좋다.
TV tv1 = new SamsungTV();
TV tv2 = new LGTV();
디폴트 메서드와 정적 메서드
Java 8버전 이후, 인터페이스 내에 완성된 디폴트 메서드가 포함될 수 있다. 디폴트 메서드는 마치 클래스의 메서드처럼 사용할 수 있다. 하지만 여전히 인터페이스 안에 있기 때문에 일단 구현할 클래스가 필요하다.
자식 클래스에서 부모 인터페이스의 디폴트 메서드를 호출하는 것도 가능하다.
interface A {
default void abc() {
System.out.println("A 인터페이스 abc()");
}
}
class B implements A {
@Override
public void abc() {
A.super.abc();
System.out.println("B 클래스 abc()");
}
}
다음과 같이 부모 인터페이스명.super.디폴트 메서드명 구조로 호출할 수 있다. 인터페이스는 다중 상속이 가능하므로 부모 인터페이스의 이름을 확실하게 호출하는 것이다.
마찬가지로 정적 메서드도 인터페이스명.메서드명 방식으로 사용한다.
추상 클래스와 인터페이스의 차이점
추상 클래스는 상속을 받아 기능을 확장하는 것에 목적이 있다.
인터페이스는 구현하는 클래스에 특정 메서드를 반드시 포함하도록 하는 것에 목적이 있다.
'Programming Language > Java' 카테고리의 다른 글
[Java] 예외 처리 (0) | 2024.05.10 |
---|---|
[Java] 이너 클래스와 이너 인터페이스 (0) | 2024.05.09 |
[Java] 상속 (0) | 2024.05.03 |
[Java] 클래스 - 2 (0) | 2024.04.30 |
[Java] 클래스 - 1 (0) | 2024.04.26 |