하나 이상의 추상 메소드를 포함하는 클래스를 가리켜서 추상 클래스라고 한다.
그리고 추상 메소드는 서브 클래스에서 반드시 오버라이딩해야만 사용할 수 있는 메소드다. 추상 메소드는 선언부만 존재하고, 구현부는 없다. 구현부는 서브 클래스에서 오버라이딩 한 뒤에 사용하게 된다.
abstract 반환타입 메소드이름();
다시 추상 클래스로 돌아와서, 추상 클래스는 다형성을 갖는 메소드 집합을 정의할 수 있게 해준다. 즉, 반드시 사용해야 하는 메소드를 추상 메소드로 선언해놓으면,
추상 클래스를 상속받는 모든 서브 클래스는 그 추상 메소드를 반드시 재정의해서(오버라이딩) 사용해야 한다.
추상 클래스를 사용하는 이유는 공통적인 메서드나 변수등을 추출해서 어느정도 규격을 잡아놓기 위함이다. 하지만 메서드와 내용이 추상적이기 때문에 아직 인스턴스화는(객체를 생성) 할 수 없다.
이렇게 미리 규격이 생기면,
1.공통된 필드와 메서드가 생겨 통일성을 유지할 수 있고, 유지보수도 쉬워진다.
2.추상 클래스를 상속받아 실체 클래스를 작성할 때 시간이 절약된다. (이미 추상화된 메소드, 변수들이 있기 때문!)
abstract class 클래스이름 {
...
abstract 반환타입 메소드이름();
...
}
예제
abstract class Animal {
abstract void cry();
}
class Cat extends Animal {
void cry() {
System.out.println("냐옹냐옹!");
}
}
class Dog extends Animal {
void cry() {
System.out.println("멍멍!");
}
}
public class Polymorphism02 {
public static void main(String[] args) {
// Animal a = new Animal(); // 추상 클래스는 인스턴스를 생성할 수 없음.
Cat c = new Cat();
Dog d = new Dog();
c.cry();
d.cry();
}
}
//결과
냐옹냐옹!
멍멍!
import java.util.*;
abstract class Book{
String title;
abstract void setTitle(String s);
String getTitle(){
return title;
}
}
//Write MyBook class here
class MyBook extends Book{ //추상 클래스 Book을 상속받는 MyBook 클래스 생성
void setTitle(String s){ // setTitle 메소드를 구현해준다. title 설정을 위한 setter 사용. 파라미터와 멤버변수 이름이 같으므로
this.title = s; // this를 사용해 필드에 있는 String title을 가리킴
}
}
public class JavaAbstractClass{
public static void main(String []args){
//Book new_novel=new Book(); This line prHMain.java:25: error: Book is abstract; cannot be instantiated
Scanner sc=new Scanner(System.in);
String title=sc.nextLine();
MyBook new_novel=new MyBook();
new_novel.setTitle(title);
System.out.println("The title is: "+new_novel.getTitle());
sc.close();
}
}