✔️ 인터페이스 vs 추상 클래스
인터페이스란?
- 인스턴스를 구현하는 모든 클래스에 대해 특정 메소드가 반드시 존재하도록 강제화하여 구현 객체가 같은 동작을 하도록 보장함
- 추상 클래스를 부분적으로 완성된 미완성 설계도라고 한다면
인터페이스는 구현된 것이 아무것도 없는 기본 설계도라고 할 수 있음
- 일종의 추상 클래스이지만 추상화 클래스보다 추상화 정보가 높아서
추상 메소드 이외의 일반 메소드나 멤버 변수를 구성원으로 가질 수 없으며 오직 추상 메소드와 상수만 멤버로 가질 수 있음
- 클래스 앞에 interface 키워드를 붙이게 됨
- 모든 멤버 변수는 public static final이어야 하며 모든 메소드는 public abstract이어야 했지만
JDK 1.8부터 인터페이스에 static 메소드와 디폴트 메소드의 추가를 허용하게 됨
- 인터페이스는 인터페이스로부터만 상속 받을 수 있으며, 클래스와 달리 다중 상속이 가능하며
클래스에서 여러 인터페이스를 다중 구현하는 것 또한 가능함
- 인터페이스는 동작이 정의되어 있지 않으므로 자신이 직접 인스턴스를 생성할 수 없으므로
인터페이스가 포함하고 있는 메소드를 구현해줄 클래스를 작성해야 함
- 만약 모든 추상 메소드의 구현을 원하지 않는다면 abstract 키워드를 붙여 추상 클래스로 선언해야 함
- 인터페이스도 인터페이스를 구현한 클래스의 조상이라고 할 수 있으므로
해당 인터페이스 타입의 참조 변수로 이를 구현한 클래스의 인스턴스를 참조할 수 있으며,
자손 클래스의 인스턴스를 조상 타입의 참조 변수로 참조하는 것도 가능함
- 인터페이스를 이용하면 대규모 프로젝트 개발 시 일관되고 정형화된 개발을 위한 표준화가 가능하며
클래스의 작성과 인터페이스의 구현을 동시에 진행할 수 있으므로 개발 시간을 단축할 수 있음
또한 클래스와 클래스 간의 관계를 인터페이스로 연결하면 클래스마다 독립적인 프로그래밍이 가능하게 됨
- 예) can do this - Flyable : Plane, Bird
/* 인터페이스 Animal */
interface Animal {
void cry();
}
/* 인터페이스인 Animal을 상속받는 인터페이스인 Cat */
interface Cat extends Animal {
void cry();
}
/* 인터페이스인 Animal을 상속받는 인터페이스인 Dog */
interface Dog extends Animal {
void cry();
}
/* 인터페이스인 Cat, Dog를 다중 구현하는 클래스인 Pet */
class Pet implements Cat, Dog {
// 다중 상속인 경우 메소드 출처의 모호성을 방지하기 위해 다중 구현 클래스에만 메소드를 정의
@Override
public void cry(){
System.out.println("멍멍 냐옹냐옹")
}
}
public class Test{
public static void main(String[] args){
Pet pet = new Pet();
pet.cry();
}
}
추상 클래스란?
- 미완성된 클래스로, 미완성된 메소드인 추상 메소드를 포함하고 있음
- 추상 클래스는 혼자로는 클래스의 역할을 다 못하지만,
새로운 클래스를 작성하는데 있어 그 바탕이 되는 부모 클래스인 베이스 클래스로 중요한 의미를 가짐
- 그러므로 클래스를 작성함에 있어서 어느정도 작성된 상태에서 시작할 수 있음
- 기존 클래스에서 공통된 부분을 추상화하여 상속하는 클래스에게 구현을 강제화하며
메소드의 동작은 구현하는 자식 클래스에게 위임하게 되어 기능을 확장하도록 함
- 클래스 앞에 abstract 키워드를 붙이게 됨
- abstract 키워드가 있는 클래스라고 모두 구현해야 하는 것은 아니며, 단지 공유의 목적으로 만드는 경우도 있음
- 추상 메소드가 아닌 일반 메소드, 멤버도 포함될 수 있지만 추상 메소드를 하나라도 포함하고 있다면 추상 클래스로 선언해야 함
- 추상 클래스는 동작이 정의되어 있지 않은 추상 메소드를 포함하고 있으므로 인스턴스를 생성할 수 없음
- 한 개의 클래스가 여러 개의 클래스를 상속 받는 다중 상속이 불가능함
- 예) is a kind of - Appliances : TV, Refrigerator
/* 추상 클래스 Animal */
abstract class Animal {
// 추상 메소드 cry()
abstract void cry();
}
/* 추상 클래스인 Animal을 상속받는 자식 클래스인 Cat 클래스 */
class Cat extends Animal {
// 추상 클래스의 추상 메소드인 cry() 메소드를 오버라이딩해야만 인스턴스를 생성할 수 있음
@Override
void cry(){
System.out.println("냐옹냐옹");
}
}
/* 추상 클래스인 Animal을 상속받는 자식 클래스인 Dog 클래스 */
class Dog extends Animal {
// 추상 클래스의 추상 메소드인 cry() 메소드를 오버라이딩해야만 인스턴스를 생성할 수 있음
@Override
void cry(){
System.out.println("멍멍");
}
}
public class Test{
public static void main(String[] args){
// 추상 클래스는 불완전하므로 자체적으로 인스턴스를 생성할 수 없음
// Animal animal = new Animal();
Cat cat = new Cat();
Dog dog = new Dog();
cat.cry();
dog.cry();
}
}