자바의 중요한 개념인 OOP의 특징에서 추상화에 대해 알아보기 위해 남궁성님의 자바의 정석 중 객체지향에 대해 학습하고 정리해보겠습니다.
추상화란 공통적으로 사용되는 속성과 기능을 추출하여 정의하는 것입니다.
참새와 독수리는 둘다 날개를 가지고 있고 날 수 있습니다. 하지만 참새는 노래를 부를수 있고, 독수리는 사냥을 할수 있는 차이가 있습니다.
참새와 독수리의 공통 속성인 날개와 비행을 추출하여 새라고 추상화
할 수 있습니다.
추상화한 새를 기준으로 보았을때 참새와 독수리는 각각 구체화
하였다고 할 수 있습니다.
public class Pengine extends Bird{
@Override
public void fly(){
System.out.println("펭귄은 못 날아ㅠ");
}
}
class Zoo{
List<Bird> cage = new ArrayList<>();
void goHome(){
Tiger tiger = new Tiger();
Bird sparrow = new Sparrow();
Bird egle = new Egle();
goCage(sparrow);
goCage(egle);
goCage(tiger); //(에러)호랑이는 새장에 못들어갑니다.
}
void goCage(Bird bird){
cage.add(bird):
}
}
그렇다면 추상화를 하기 위해 알아야할 추상클래스와 인터페이스에서 대해 알아보겠습니다.
추상 클래스
란, 일반 클래스에 추상 메서드를 가지고 있는 클래스입니다.
추상 클래스는 추상메서드를 구현해야하는 것도 있지만, 상속을 통해 구체화 하고 추상 클래스를 통해 일반화 하여 다형성을 제공하기 위한 목적으로 사용됩니다.
추상 메서드란, 정의만 되어있고 구현이 되어있지 않은 메서드를 말합니다.
클래스에서 추상 클래스를 나타낼때는 접근 제어자 앞에 abstract
로 나타냅니다.
추상 메서드를 나타낼때도 접근 제어자 앞에 abstract
로 나타냅니다.
추상 클래스는 단 하나의 추상 메서드를 가지고 있다면 추상 클래스가 됩니다.
//추상 클래스
abstract public class Bird{
Wing wing;
//추상 메서드
abstract void fly();
public Bird(Wing wing){
this.wing = wing;
}
}
다이아몬드 문제
라고 해서 다중 상속시 동일한 메서드를 부모 클래스에서 가지고 있다면, 어떤 메서드를 호출해야하는지 모르기 때문에 문제가 발생합니다.인터페이스
란, 공통으로 구현해야하는 기능을 정의한 추상 메서드의 집합입니다.
인터페이스를 구현체가 인터페이스에 정의되어있는 추상 메서드의 구현을 강제하여 동일한 동작을 수행하기 위한 목적으로 사용됩니다.
인터페이스는 interface
로 정의하고 추상메서드와 상수만 사용이 가능합니다.
(default method
, static method
도 사용가능하지만, 인터페이스와 추상클래스 차이를 중점으로 하기 위해 논외로 하겠습니다.)
인터페이스의 추상메서드를 구현하기 위해서는 implements
를 선언하여 인터페이스의 추상 메서드를 구현해줍니다. (강제, 필수)
interface Flyable{
void goHigh();
}
class Sparrow extends Bird implements Flyable{
@Override
public void fly(){
System.out.println("푸드덕 푸드덕");
}
@Override
public void goHigh(){
System.out.println("난다 날아~");
}
}
//선언부
interface Food{
void tasty();
}
//구현부
class Noodle implements Food{
@Override
void tasty(){
System.out.println("맛있다!");
}
}
interface Cookable{
void cook();
}
public class Chef{
void cook(Cookable cookable){
Food food = cookable.cook();
...
}
}
//나중에 구현
public class Pasta implements Cookable{
@Override
public void cook(){
...
}
}
추상클래스와 인터페이스 둘 다 추상 메서드를 포함하고 있어 추상 메서드 구현을 강제하게됩니다.
추상 클래스와 인터페이스는 추상 메서드 구현이라는 공통점을 가지고 있고 추상 클래스는 다중 상속이 불가능하고, 인터페이스는 다중상속이 가능하다는 차이점으로 인해 인터페이스가 다중 상속을 못하는 추상 클래스의 해결책이라고 오해할 수도 있습니다.
하지만 추상 클래스와 인터페이스는 뚜렷한 목적을 가지고 사용되기 때문에 사용의 목적과 용도에 따라 사용됩니다.
추상클래스는 일반 클래스에서 추상 메서드를 포함하고 있는 클래스로써, 상속을 통해 구체화하여 확장하는것을 목적으로 사용됩니다.
인터페이스는 상수와 추상 메서드를 포함하고 있어 공통된 기능을 수행하여 표준화를 만들기 위한 목적으로 사용됩니다.
클래스는 캡슐화된 클래스를 상속함으로써, 클래스의 의미를 더 구체화하고 확장합니다. 추상 클래스는 이 클래스의 확장을 위해 자식 클래스들이 가지는 공통된 속성을 추출하여 정의함으로써 코드의 중복을 줄이고 공통된 특성을 쉽게 파악할 수 있게 해줍니다.
Animal은 Bird와 Mammal로 구체화하여 확장할 수 있습니다. 또 Bird는 Sparrow, Egle, Penguin으로 더 구체화하여 확장할 수 있습니다. 마찬가지로 Mammal도 더 구체화하여 Human, Dog, Cat등으로 확장해 나갈 수 있습니다.
인터페이스는 특정 클래스들의 공통된 속성을 표준화함으로써, 각 클래스들의 공통점을 만들어 주고 동일한 행동을 하게 만들어 줄 수 있습니다.
https://www.youtube.com/watch?v=CXuA31XcBZ0&list=PLW2UjW795-f5JPTsYHGAawAck9cQRw5TD