클래스, 추상클래스, 그리고 인터페이스
일반 클래스와 추상 클래스 차이
일반 클래스 | 추상 클래스 | |
클래스 앞에 | abstract 명령어가 안붙음 | abstract 명령어가 붙음 |
클래스 내부에 | abstract 함수 생성 불가능 | abstract 함수 생성 가능 |
객체 생성이 | 가능 | 불가능 |
공통적으로 | 부모를 1개만 둘 수 있다. |
[일반 클래스]
class A {
public A () { } // 생성자 메소드
abstract public void f_a() { } // 에러 발생
public void f_b() {
System.out.println("class A f_a");
}
}
[추상 클래스]
abstract class B {
public B () { } // 생성자 메소드
abstract void f_a(); // 추상메소드 사용 가능 > 자식클래스에서 무조건 구현해 주어야 함
public void f_b() {
System.out.println("abstract class B f_b");
}
}
추상 클래스와 일반 클래스는 큰 차이가 없다.
단, 추상 클래스에서는 추상 메소드를 선언하여 상속을 통해 자식 클래스에서 완성하도록 유도한다.
그래서 미완성 설계도라고도 표현한다. 또한, 상속을 위한 클래스이기 때문에 객체를 생성할 수 없다.
인터페이스란?
추상클래스가 미완성 설계도라면 인터페이스는 기본 설계도라고 할 수 있다.
자바에서 일반적으로 할 수 있는 기능들을 인퍼테이스로 구현하여 상속관계를 유지한다.
인터페이스도 추상 클래스처럼 다른 클래스를 작성하는데 도움을 주는 목적으로 작성하고, 클래스와는 다르게 다중 상속(구현)이 가능하다.
인터페이스 | 추상 클래스 | |
근본적으로 | 기본 설계도 | 미완성 설계도 |
사용 의도 | Has something (~을 할 수 있다) |
Is A (~이다) |
공통점 | 선언만하고 구현 내용은 없음 | |
차이점 | 다중 상속 가능 | 다중 상속 불가능 (자식의 부모는 1개만 존재) |
차이점 2 | 상속받은 자식은 부모의 메소드를 모두 선언해야함 |
상속받은 자식은 부모의 메소드 중 필요한 것만 선언 가능함 |
[다중상속이 가능한 인터페이스]
public interface Movable {
void move(int x, int y);
}
interface Attackable {
void attack(Unit u);
}
interface Fightable extends Movable, Attackable {
}
인터페이스를 사용하면 공통으로 필요한 기능들도 모든 클래스에서 오버라이딩을 하여 재정의를 해야한다는 번거로움이 있다.
이렇게 공통된 기능이 필요하다면, 그냥 추상클래스를 이용해서 일반 메소드를 작성하여 자식 클래스에서 사용할 수 있도록 하면 된다.
하지만 위의 도표에서 나와있듯이, 하나의 클래스만 상속이 가능하다.
때문에 각각 다른 추상클래스를 상속하는데 공통된 기능이 필요하다면, 해당 기능을 인터페이스로 작성하여 구현하는 것이 편리하다.
참고 사이트
일반클래스와 추상클래스의 상속 차이 : https://mozi.tistory.com/555
추상클래스와 인터페이스의 차이 : https://velog.io/@new_wisdom/Java-추상-클래스와-인터페이스의-차이
[JAVA] 추상클래스 VS 인터페이스 왜 사용할까? : https://myjamong.tistory.com/150