public class Animal {
public void sound() {
System.out.println(" ");
}
}
public static void main(String[] args) {
Animal[] animals = {new Cat(), new Cow(), new Dog(), new Duck()};
for (Animal animal : animals) {
soundAnimal(animal);
}
}
private static void soundAnimal(Animal animal) {
System.out.println("==== 사운드 호출 ====");
animal.sound();
System.out.println("== 사운드 호출 완료 ==");
}
Animal 클래스를 부모로 하는 Cat, Cow, Dog, Duck 클래스가 있다. 다형성을 활용하기 위해 Animal 클래스를 만들었지만, 사실 Animal 클래스 자체는 실제로 생성되면 안 되는 추상 클래스인 상황이다. 실체인 인스턴스가 존재하지 않고 오직 상속을 목적으로 사용되기 때문이다.
추상 클래스
// 추상 클래스
abstract class Animal {
public void sound() {
System.out.println(" ");
}
}
클래스를 선언할 때 앞에 abstract 키워드를 붙인다. 추상 클래스는 기존 클래스와 완전히 같지만, new class()처럼 직접 인스턴스를 생성하지 못하는 제약이 추가된 것이다.
추상 메서드
abstract class Animal {
public abstract void sound(); // 추상 메서드
}
부모 클래스를 상속받는 자식 클래스가 반드시 오버라이딩 해야 하는 메서드를 부모 클래스에 정의한다. 따라서 실체가 없고 메서드 바디가 없다.
- 추상 메서드가 하나라도 있는 클래스는 추상 클래스로 선언해야 한다.
- 추상 메서드는 상속받는 자식 클래스가 반드시 오버라이딩 해서 사용해야 한다.
* 왜 그래야 하나요?
추상 메서드는 메서드 바디가 없는 불완전 메서드이다. 따라서 직접 생성하지 못하도록 추상 클래스로 선언해야 한다. 그렇지 않으면 컴파일 에러가 발생한다. (추상 메서드인데 메서드 바디가 존재해도 컴파일 에러가 발생한다.)
순수 추상 클래스
모든 메서드가 추상 클래스인 클래스를 순수 추상 클래스라고 한다. 특징은 다음과 같다.
- 인스턴스를 생성할 수 없다.
- 상속 시 모든 메서드를 오버라이딩 해야 한다.
- 주로 다형성을 위해 사용한다.
▶ 이러한 순수 추상 클래스는 인터페이스와 유사하다.
인터페이스
인터페이스는 순수 추상 클래스와 유사하지만 몇 가지 편의기능이 추가된다.
public interface Animal {
void sound();
void move();
}
- 인터페이스의 메서드는 모두 public, abstract이다.
- 메서드에 public abstract를 생략할 수 있으며, 오히려 생략을 권장한다.
- 인터페이스는 다중 구현을 지원한다. (다중 상속 지원)
public class Cat implements Animal {
@Override
public void sound() {
}
@Override
public void move() {
}
}
▶ 인터페이스는 extends가 아닌 implements 키워드를 사용한다. (상속이 아닌, 구현 개념)
▶ 자바에서는 순수 추상 클래스라는 개념이 공식적이지 않으며, 대신 인터페이스를 사용한다.
참고자료
훌륭한 프로그램은 적절한 제약이 있어야 한다.
인터페이스를 사용함으로써 인터페이스의 메서드를 반드시 구현하라는 제약을 준다. 즉, 구현되지 않으면 실행되지 않는다. 개발자가 의도한 방향으로 진행될 수 있도록 만든다는 이야기다. 뿐만 아니라, 클래스 상속에서는 불가능했던 다중 구현이 가능하다는 장점도 있다.
* default 메서드 또는 private 메서드를 사용하면 인터페이스에서도 메서드를 구현할 수 있다만, 이는 아주 예외적인 특별 케이스이므로 나중에 중급 이상의 실력이 갖추어졌을 때 다루도록 하겠다.
'프로그래밍 > 배웠어, 자바' 카테고리의 다른 글
[Java] OCP (Open-Closed Principle) / 개방-폐쇄 원칙 (1) | 2025.02.03 |
---|---|
[Java] 인터페이스의 다중 구현 (1) | 2025.01.30 |
[Java] 객체 지향 프로그램과 다형성 (1) | 2025.01.27 |
[Java] Getter, Setter 메서드 / 접근 제어자 (1) | 2025.01.24 |
[Java] super 키워드 / 상속과 메모리 구조 (2) | 2025.01.23 |