공통된 필드와 메소드를 통일할 목적으로 사용한다.
실체클래스 구현시, 시간 절약이 가능하다.
규격에 맞는 실체 클래스 구현
abstract class AbstractFoo{
int x, y;
public void method(){
System.out.println("method");
}
//세미콜론을 잊지 말아야 합니다.
public abstract void abstractMethod();
// 선언만 하고 구현하지 않음. Virtual method call이여서 부모메소드는 비어있음.
}
class Foo extends AbstractFoo{
@Override
public void abstractMethod() {
System.out.println("implemented abstractMethod");
}
}
public class AbstractClass {
public static void main(String[] args) {
// AbstractFoo afoo = new AbstractFoo()
//추상 클래스는 객체 생성이 불가합니다. 구현이 안되있으니 인스턴스화가 안된다.
Foo foo = new Foo();
foo.abstractMethod();
AbstractFoo afoo = (AbstractFoo)foo;
afoo.abstractMethod(); // virtual method call
//추상클래스는 객체 생성은 불가하지만, 구현된 자식클래스의 객체는 받을 수 있다.
}
}
public abstract class Car {
public abstract void drive();
public abstract void stop();
public void startCar(){
System.out.println("시동을 켭니다.");
}
public void turnOff(){
System.out.println("시동을 끕니다.");
}
public void washCar(){ }
//아무 기능이 없어 여기서는 수행을 하지 않고 하위 클래스에서 재정의해서 사용.
// 모든 하위클래스에서 구현을해야하는 거라면 abstract를 사용하지만
// 모든 하위클래에서 사용하지 않으면 이렇게 사용한다.
// 기능의 확장이 가능함
//템플릿 메소드
final public void run(){ //재정의할 수 없게 final 키워드 사용.
startCar();
drive();
stop();
turnOff();
washCar();
}
}
public class AICar extends Car {
@Override
public void drive() {
System.out.println("자율 주행합니다.");
System.out.println("자동차가 스스로 방향을 바꿉니다.");
}
@Override
public void stop() {
System.out.println("스스로 멈춥니다.");
}
@Override
public void washCar(){
System.out.println("자동 세차합니다.");
}
}
public class ManualCar extends Car {
@Override
public void drive() {
System.out.println("운전자가 주행합니다..");
System.out.println("운전자가 방향을 바꿉니다.");
}
@Override
public void stop() {
System.out.println("운전자가 멈춥니다.");
}
}
public class CarTest {
public static void main(String[] args) {
Car aiCar = new AICar();
aiCar.run();
System.out.println("============");
Car manualCarnuCar = new ManualCar();
manualCarnuCar.run();
}
}