바디( { }
)가 존재하지 않는 메서드 (미완성 메서드)
-> 실행 코드가 없으므로 실행X
메서드 선언부 접근제한자 뒤 abstract
키워드 붙여서 선언
-> 바디가 없으므로 ;
으로 마무리
메서드 실행 코드가 없으므로 외부에서 호출X
< 추상메서드 정의 기본 문법 >
[접근제한자] abstract 리턴타입 메서드명([매개변수...]);
abstract
생략 가능
인스턴스 생성이 불가능한 미완성 클래스
-> 내부에 추상메서드를 가지고 있을 경우, 추상메서드 호출이 불가능하므로 인스턴스 생성 차단함
추상메서드를 가지고 있을 경우 클래스는 무조건 추상클래스로 정의되어야 함
클래스 키워드 앞 abstract 키워드 붙여서 정의
추상메서드뿐 아니라 일반메서드, 멤버변수, 생성자 가질 수 있음
상속을 통한 슈퍼클래스로 사용, 다형성 활용을 위한 참조변수 타입으로 사용 가능
-> 추상메서드를 포함하는 추상클래스 상속받는 서브클래스는 오버라이딩을 통해 추상메서드의 바디를 구현해야 한다
추상메서드에 대한 구현을 강제함으로써 코드의 강제성 및 통일성 향상
< 추상클래스 정의 기본 문법 >
[접근제한자] abstract calss 클래스명 {
[멤버변수...
생성자...
일반메서드...
추상메서드...]
}
public static void main(String[] args) {
AbstractClass a = new AbstractClass(); // 오류 발생
// 추상클래스는 인스턴스 생성 불가!
SubClass s = new SubClass();
s.abstractMethod();
s.normalMethod();
s.subClassMethod();
// 상속 받았기 때문에 추상클래스의 메서드와
// 서브클래스의 메서드 모두 접근 가능
AbstractClass ab = new SubClass();
// 참조변수 타입으로 활용 가능!!
ab.abstractMethod();
ab.normalMethod();
// 참조 영역이 축소되었기 때문에
// 서브클래스의 메서드는 접근 불가능해졌음
}
abstract class AbstractClass { // 추상클래스 정의
public abstract void abstractMethod();
// 추상메서드 정의
// 중괄호 제외!
// 중괄호 있으면 오류 발생!!!
public void normalMethod() {
// 일반메서드 정의 가능
}
public AbstactClass() {
// 기본생성자 정의 가능
}
String member; // 멤버변수 가능!
}
class SubClass extends AbstractClass {
// 추상클래스를 상속받는 서브클래스
@Override
public void abstractMethod() {
// 추상메서드 오버라이딩 필수!
// 바디를 갖지 않는 추상메서드의 바디를 구현하는 작업
}
public void subClassMethod() {
// 서브클래스에서 정의한 메서드
}
}
추상클래스를 이용하여 다형성 활용하기
public static void main(String[] args) {
Flyer f = new SuperMan();
// 참조변수 타입으로 접근
f.takeoff();
f.fly();
f.land();
Flyer f = new Bird();
f.takeoff();
f.fly();
f.land();
// 위와 코드는 똑같지만 출력되는 문장은 다름!!
}
abstract class Flyer {
public abstract void takeoff();
public abstract void fly();
public abstract void land();
// 추상클래스 내에 추상메서드 정의
}
class SuperMan extends Flyer {
// 추상클래스를 상속받는 서브클래스 정의
@Override
public void takeoff() {
System.out.println("슈퍼맨 이륙");
}
@Override
public void fly() {
System.out.println("슈퍼맨 비행");
}
@Override
public void land() {
System.out.println("슈퍼맨 착륙");
}
// 추상클래스의 추상메서드를 오버라이딩
}
class Bird extends Flyer {
@Override
public void takeoff() {
System.out.println("새 이륙");
}
@Override
public void fly() {
System.out.println("새 비행");
}
@Override
public void land() {
System.out.println("새 착륙");
}
}
추상메서드 2개를 가지고 있는 추상클래스를 상속받는 서브클래스 정의
abstract class AbstractClass {
public abstract void method1();
public abstract void method1();
// 추상메서드 2개 선언
}
abstract class MiddleClass extends AbstractClass {
// 추상메서드2는 오버라이딩 하지 않았으므로 추상클래스로 정의
// abstract 빠지면 오류 발생!
@Override
public void method1() {
// 추상클래스의 추상메서드1 오버라이딩
}
}
class Subclass extends MiddleClass {
// 추상클래스를 상속받았지만
// 추상메서드는 모두 구현하지 않은 추상클래스를 다시 상속...
@Override
public void method2() {
// 위에서 method1은 구현되었기 때문에 강제성이 없지만
// method2는 구현되지 않았기 때문에
// 여기서 오버라이딩해서 반드시 구현해야함!
}
}
자동차 연료공급 방법이 달라지는 추상메서드 정의
⭐ 입력
public static void main(String[] args) {
Vehicle v = new ElectricCar();
v.addFuel();
Vehicle v = new Disel();
v.addFuel();
// 다형성 활용하기
}
abstract class Vehicle {
int curX;
int curY;
// 위치 좌표를 저장하는 멤버변수
public void reportPosition() {
// 현재 위치를 출력하는 일반 메서드 정의
System.out.println("현재 위치 : " + curX + ", " + curY);
}
public abstract void addFuel();
// 일반메서드가 아닌 추상메서드로 정의한 이유는
// 오버라이딩에 강제성을 부여하기 위해서임!!!
}
class ElectricCar extends Vehicle {
@Override
public void addFuel() {
// 추상메서드 오버라이딩
System.out.println("전기차 충전소에서 배터리 충전!");
}
}
class Disel extends Vehicle {
@Override
public void addFuel() {
// 추상메서드 오버라이딩
System.out.println("주유소에서 디젤 연료 공급!");
}
}
📌 출력
전기차 충전소에서 배터리 충전!
주유소에서 디젤 연료 공급!