JAVA - 추상 클래스/추상 메서드

추상 클래스란, 미완성 클래스를 의미한다. 일단 선언은 했지만, 완성되지 않아서 오버라이딩을 통해 기능을 작성해야 한다. 아래 코드를 통해 확인해보자.

1
2
3
4
5
6
7
8
9
package devandy.java.abstraction;

public abstract class Bird {
public abstract void sing();

public void fly() {
System.out.println("날다.");
}
}

fly()는 정의했지만, sing()은 새의 종류에 따라 달라지므로 따로 정의하지 않았다. 이렇게 미완성된 메서드를 추상 메서드라고 한다. 그리고 단 하나의 추상 메서드라도 보유하고 있다면, 해당 클래스는 추상 클래스가 된다. 따라서 추상 메서드를 작성했다면, 클래스의 접근제한자 뒤에도 abstract 키워드를 작성해야 한다.

추상 클래스를 사용하는 방법은 위에서도 언급했듯 오버라이딩을 해야한다. 그러려면 추상 클래스를 상속받는 클래스부터 생성해야한다.

1
2
3
4
5
6
7
8
9
package devandy.java.abstraction;

public class Duck extends Bird {

@Override
public void sing() {
System.out.println("꽥꽥!");
}
}

Bird 클래스를 상속받는 Duck 클래스를 생성했다. Duck 클래스에서 sing()을 오버라이딩하는 메서드를 생성까지 한 코드이다. 여기서 @Override라는 어노테이션을 사용했지만, 사실 작성하지 않아도 컴파일 에러가 발생하지는 않는다. 가독성을 위해 자동으로 생성된게 아닐까 싶다.

위의 코드들을 컴파일해서 콘솔에 출력해보겠다.

Bird.java

1
2
3
4
5
6
7
8
9
10
11
package devandy.java.abstraction;

public abstract class Bird {
String bird;

public abstract void sing();

public void fly() {
System.out.println(bird+"날다.");
}
}

fly()에 어떤 새가 나는지를 함께 출력하기 위해 Bird 객체에 String형 멤버 필드를 추가하고, print문에도 멤버 필드를 추가해주었다.

Duck.java

1
2
3
4
5
6
7
8
9
10
11
12
13
package devandy.java.abstraction;

public class Duck extends Bird {

@Override
public void sing(){
System.out.println("꽥꽥");
}

public Duck(String duck){
this.bird = duck;
}
}

수퍼 클래스에서 상속받는 멤버 필드에 값을 주입하는 생성자를 추가했다.

DuckExam.java

1
2
3
4
5
6
7
8
9
10
package devandy.java.abstraction;

public class DuckExam {
public static void main(String[] args) {
Duck duck = new Duck("오리");

duck.sing();
duck.fly();
}
}

Duck 클래스 타입의 인스턴스 duck을 선언할 때 “오리”라는 String형 값을 인자값으로 넣어서 선언한다. 그럼 Duck 클래스에서 생성한 생성자에 의해 Bird 멤버필드에 값이 주입되고, 그 값이 출력될거다.

실행결과는 다음과 같다.

1
2
꽥꽥
오리 날다.