추상클래스는 무엇인가?
지구상의 생물중에 추상성을 직접 사용하는 것은 인간밖에 없을 것이다. 이 세계가 추상적인 원리에 기초하고 있다고 하더라도 그것을 사용할 수 있는 특권은 인간에게 밖에 없다.
예를 들어 1이라는 숫자가 대표적이다. 1을 직접 본 사람은 없다. 하지만 모든 사람은 1이 뭔지 알고 있다. 사람이 1명있고, 커피가 1잔있다. 숫자 1은 모든 사물에 대응하는 것이다.
클래스도 클래스만 있을때 실체가 없다. 실체화 시키는 것은 인스턴스를 생성했을 때 이루어진다. 클래스라는 것은 인스턴스를 만들기 전에 사용할 수 없다. 추상클래스는 abstract 키워드를 사용해서 만들 수 있다. 자바의 추상클래스는 인스턴스를 만들 수 없다. 상속을 통해서 자손클래스에서 인스턴스화 할 수 있다.
아래의 예제에서 확인할 수 있다.
클래스 A는 추상클래스이다. 추상클래스는 추상메소드를 가질 수 있다. 추상메소드는 선언만 하고 구현은 하지 않는다.
public abstract void a( );
는 a메소드의 선언만 한다. 이를 추상 메소드라 한다.
한편 추상클래스의 메소드는 구현을 할 수도 있다. 클래스 A는 선언만 한 추상메소드 2개와 구현한 메소드 2개가 있다.
클래스 B에서는 A를 상속한다. 클래스 B에서 A 추상클래스에서 선언한 메소드 2개를 구현한다. 그럼으로 B클래스는 인스턴스를 만들수 있다.
클래스 C는 A추상클래스의 선언한 메소드 2개중에 1개만 구현한다. 1개는 구현이 안되있다. 이는 그냥 클래스로 사용이 불가능하다. 그런 경우 abstract 키워드를 붙여서 추상클래스로 만들어야 한다.
클래스 D는 그런 클래스 C를 상속하여 나머지 1개의 추상메소드를 구현한다. 클래스 D에는 abtract 메소드가 없으니까 인스턴스를 만들 수 있다. 클래스 D는
추상클래스 A 상속 >> 추상클래스 C 상속 >> 클래스 D 인스턴스
와 같다.
마지막으로 추상클래스 E는 모든 메소드를 구현했다. 모든 메소드가 구현되 있어도 추상클래스로 만들 수 있다. 단지 인스턴스를 생성할 수 없다. 이것은 상속을 받아 구현가능하다.
public class AbstractC {
public static void main(String[] args) {
//A a1 = new A();
B b1 = new B();
//C c1 = new C();
D d1 = new D();
//E e1 = new E();
b1.c();
d1.b();
}
}
abstract class A{
public abstract void a();
public abstract void b();
public void c() {
System.out.println("c called");
}
public void d() {
System.out.println("d called");
}
}
class B extends A{
@Override
public void a() {
System.out.println("a called");
}
@Override
public void b() {
System.out.println("b called");
}
}
abstract class C extends A{
@Override
public void a() {
System.out.println("a overrided");
}
}
class D extends C{
@Override
public void b() {
System.out.println("b overried");
}
}
abstract class E {
public void a1() {
System.out.println("a1 called");
}
public void b1() {
System.out.println("b1 called");
}
}
*추상클래스를 사용하는 이유는 상속을 하기 위해서이다. 추상클래스 자체를 사용하려는게 아니라 하위클래스에서 공통되는 분모들을 뽑아서 선언 혹은 구현을 해놓는 것이다. 상속을 받는 하위클래스는 여러개 일 것이다. 하위클래스를 구현할때 이미 부모의 추상클래스에서 공통되는 기능을 사용할 수 있고, 또 선언만 된 메소드들을 보면 구현해야할 내용들이 뭔지 알 수 있다.
*추상클래스는 많은 프레임워크에서 사용하고 있다. 예를 들어 안드로이드 프레임워크에는 공통된 부분을 구현해 놓고 선언만 해놓은 메소드는 실제 안드로이드앱에서 각자 다르게 구현하도록 한 것이다. 추상메소드 중에 하나라도 구현이 안되었다면 인스턴스를 생성할 수 없다. 그러므로 프레임워크에서 선언한 추상 메소드들을 유심히 볼 필요가 있다. 개발자들이 프레임워크를 작동시키기 위해 꼭 필요할 것이라고 예상한 메소드들이기 때문이다.