추상 클래스
각각의 동물들을 객체로 만든다고 생각해보자. 사자 객체 하나, 토끼 객체 하나, 여우 객체 하나 이런 식으로 수 많은 동물들을 하나하나 만들 생각을 하니 벌써부터 머리가 아프다.
이럴 때는 각각 동물들의 공통된 필드와 메소드를 가지고 있는 추상 클래스를 만들고, 각각의 객체들이 추상 클래스를 상속받도록 하면 중복된 코드를 줄일 수 있다.
abstract class Animal {
int age;
public void breathe() {
System.out.println("들이쉽니다.");
System.out.println("내쉽니다.");
}
public void eat() {
System.out.println("먹습니다.");
}
}
나이나 숨쉬기, 먹기 등은 어떤 동물이든 상관없이 공통으로 가지고 있는 부분이다. 이러한 공통점들을 모아 추상 메소드로 선언해준다.
class Lion extends Animal {
Lion(int age) {
this.age = age;
}
public void hunt() {
System.out.println("먹잇감을 사냥합니다.");
}
}
Animal 클래스를 상속받아 Lion이라는 객체를 생성해주면 Animal 클래스가 가지고 있는 나이와 숨쉬기, 먹기를 따로 선언하지 않아도 사용할 수 있게 된다. 그리고 사자에게 필요한 hunt() 메소드만 선언해주면 간단하게 Lion 클래스를 만들 수 있다.
인터페이스
사자와 버스를 비교해보자. 사자와 버스는 서로 관련이 많지 않다. 따라서 사자와 버스의 부모 클래스가 될 추상클래스를 만들기는 적절하지 않다. 하지만 사자와 버스는 모두 공통된 기능인 "이동" 기능을 가지고 있다. 이때 인터페이스를 활용하면 구현 객체가 move라는 같은 동작을 한다는 것을 보장해줄 수 있다.
interface movable {
void move();
}
class Lion implements movable{
// 사자가 가지고 있는 멤버
public void breathe() {
System.out.println("들이쉽니다.");
System.out.println("내쉽니다.");
}
// movable 인터페이스 구현
@Override
public void move() {
System.out.println("네 발로 이동합니다.");
}
}
class Bus implements movable{
// 버스가 가지고 있는 멤버
public void charge() {
System.out.println("요금을 받습니다.");
}
// movable 인터페이스 구현
@Override
public void move() {
System.out.println("바퀴로 이동합니다.");
}
}
추상클래스와 인터페이스 비교
추상 클래스 | 인터페이스 | |
공통점 | 공통 기능을 상속(extends)받거나 구현(implement)할 수 있음 | |
목적 | 자식 클래스들의 공통된 필드와 메소드를 공유하도록 함 | 서로 다른 클래스들이 공통적으로 구현해야 하는 동작을 정의 |
구현 | 추상메소드 뿐만 아니라 일반 메소드와 멤버 변수를 가질 수 있음 | 추상메소드 + 상수 (final) (java 8부터는 defalut 메소드 사용 가능) |
다중 상속 / 다중 구현 | X | O |
'Backend > Java-Spring' 카테고리의 다른 글
[Java] ArrayList와 LinkedList의 구현을 통한 성능 비교 (2) | 2023.11.25 |
---|---|
[알고리즘] 알고리즘 성능을 분석하는 상환 분석 (Amortized Analysis) (1) | 2023.11.22 |
[Java] 연속된 부분 배열의 최대 합 구하기 (1) | 2023.10.08 |
[Java] 자식클래스 생성자에서 super()의 필요성 (2) | 2023.09.13 |
[Java] public static void main(String[] args) {} 에 대한 분석 (0) | 2023.09.08 |