추상 메서드
란 자식 클래스에서 구현할 의무를 부여하도록 지정 된 부모 클래스에서의 특정 메서드 인데요. 자식 클래스에게 메서드를 넘겨주기 위해 부모 클래스가 억지로 그 메서드와 관련된 값들을 억지로 갖고 있을 필요가 없으니, 부모에서는 자식을 위해 그냥 추상적으로만 갖고만 있는 메서드라고 보시면 되는데요.
abstract public void move();
그리고 추상 클래스
란 앞서 소개한 추상 메서드를 갖고 있는 클래스로서 해당 추상 클래스를 통한 인스턴스 객체 생성이 불가능합니다. 그래서 오직 자식들을 위해 존재하는? 클래스라고 생각 하시면 편하죠.
abstract class Phone
부모로부터 자식이 일반 클래스를 상속 받을때는 어노테이션으로 해당 메서드를 재정의 할 수 있었는데요. 추상 클래스로부터 추상 메서드를 상속받을 경우 어노테이션 필요 없이 정해지지 않은 상속 메서드를 각 클래스에 맞춰 코드를 재정의 할 수 있는 것이죠.
물론 이 추상 클래스에서 추상 메서드를 하나라도 상속 받게 될 경우, 이를 물려받는 하위 클래스에서는 상속 받은 추상 메서드를 무조건 구현해 주어야 하는 단점도 존재하지만 코드 구현부를 비워두고 작성하면 단점이 어느정도 상쇄되기 때문에 자식 클래스에게 강제성을 부여하되 이름과 매개변수의 통일성을 부여할 수 있는 장점 또한 존재하는 것이죠.
// 추상 클래스: 핸드폰 abstract class Phone { // 추상 메서드: 전화 걸기 abstract void makeCall(); // 추상 메서드: 문자 보내기 abstract void sendMessage(); // 일반 메서드: 전원 켜기 void powerOn() { System.out.println("Phone is powering on"); } // 일반 메서드: 전원 끄기 void powerOff() { System.out.println("Phone is powering off"); } } // 하위 클래스: 폴더블폰 class FlipPhone extends Phone { // 전화 걸기 메서드 구현 : 추상 메서드를 상속 받을 경우 어노테이션을 적어줘도 됩니다. @Override void makeCall(String number) { System.out.println("Calling " + number + " from Flip Phone"); } // 문자 보내기 메서드 구현 : 추상 메서드를 상속 받을 때에는 어노테이션을 안적어줘도 됩니다. void sendMessage(String message) { System.out.println("Sending message: " + message + " from Flip Phone"); } } // 하위 클래스: 스마트폰 class Smartphone extends Phone { // 전화 걸기 메서드 구현 @Override void makeCall(String number) { System.out.println("Calling " + number + " from Smartphone"); } // 문자 보내기 메서드 구현 void sendMessage(String message) { System.out.println("Sending message: " + message + " from Smartphone"); } // 추가 기능: 인터넷 사용 void browseInternet() { System.out.println("Browsing the internet from Smartphone"); } } public class Main { public static void main(String[] args) { // 폴더블폰 객체 생성 및 사용 FlipPhone flipPhone = new FlipPhone(); flipPhone.powerOn(); flipPhone.makeCall("123-4567"); flipPhone.sendMessage("Hello!"); System.out.println(); // 스마트폰 객체 생성 및 사용 Smartphone smartphone = new Smartphone(); smartphone.powerOn(); smartphone.makeCall("987-6543"); smartphone.sendMessage("Hi!"); smartphone.browseInternet(); } }
이렇게 작성하면, 추상 클래스에서는 공통되는 추상 메서드만 구현해 놓고, 상속을 받는 각 클래스에서 요건에 맞는 매개변수 및 코드 구현부를 독립적으로 재정의 하여 사용이 가능해집니다. "기본 틀은 이건데, 나머지는 너희들이 알아서 써" 와 같은거죠.
특히 인터페이스에서는 기본적으로 추상 클래스이며, 해당 클래스 내에 선언되는 메서드는 abstract 키워드를 사용하지 않아도 암묵적으로 추상 메서드로 선언되는데요. 그래서 이를 구현하는 클래스는 해당 메서드를 반드시 구현해야 하며,
자바에서의 추상적 개념은 키워드에 의한 사용보다 거의 인터페이스에서 자동적으로 사용되는 개념이라고 생각하셔도 무방합니다.