추상 클래스 (abstract class)
간단히 말하자면 추상 메서드를 가지고 있는 클래스이다.
일반적으로 생각하는 클래스는, 해당 클래스를 사용해 객체를 직접 생성할 수 있다. 그리고 이러한 클래스를 실체 클래스라고 말한다. 추상 클래스는 실체 클래스와는 달리 클래스의 공통적인 특성을 추출해서 선언하는 것이다.
따라서 추상 클래스는 인스턴스를 생성할 수 없다. 즉 객체를 직접 생성할 수 없다. new가 불가능한 것이다.
추상 클래스는 선언할 때 abstract 키워드를 반드시 써주어야 한다.
추상 클래스와 실체 클래스는 상속의 관계를 가진다. 추상 클래스가 부모이고 실체 클래스가 자식으로 구현된다. 추상 클래스를 상속받는 자식 클래스에 반드시 구현해야 할 메서드가 있는 경우, 그 메서드를 추상 메서드로 만들어서 반드시 override 하도록 하기 위해 추상 클래스를 사용한다.
추상 클래스의 용도
추상 클래스는 대게 실체 클래스들의 공통된 필드와 메서드이 이름을 통일할 목적으로 사용한다.
실체 클래스를 설계하는 사람이 여러 명인 경우 클래스마다 필드명이나 메서드명이 다른 경우가 발생할 수 있기 때문에 이를 방지하기 위함이다.
또한 추상 클래스를 사용하면 실체 클래스 작성 시 시간을 절약할 수 있다.
프로젝트 설계자가 실체 클래스에 사용되는 공통적인 필드와 메서드를 추상 클래스에 모두 선언해놓고 추상 클래스로 설계 규격을 작성한다. 프로그래머들은 추상 클래스를 토대로 실체 클래스를 작성한다.
추상 메서드 (abstract method)
모든 실체 클래스가 가지고 있는 메서드 내용이 동일하다면 추상 클래스에 일반 메서드를 작성해도 괜찮지만, 메서드의 선언만 동일하고 실행 내용이 달라야하는 경우가 많다. 이때 추상 클래스 내에 추상 메서드를 선언하여 사용한다. (추상 메서드는 오로지 추상 클래스 내에서만 선언될 수 있다.)
메서드 본체가 정의되지 않은 메서드로, 본체가 없기 때문에 {} 부분이 없다. 오로지 메서드의 선언만이 가능하다.
메서드 원형 끝이 ; (세미콜론)으로 끝난다.
메서드 이름 앞에 abstract 키워드를 반드시 써주어야 한다.
💻 예제
📝 소스 코드
public class Main {
public static void main(String[] args) {
// TestAbstract test = new TestAbstarct();
TestClass1 test1 = new TestClass1();
test1.test = 100;
System.out.println(test2.testMethod());
}
}
abstract class TestAbstract {
int test;
public int getTest() { // 메소드
return test;
}
public abstract int testMethod(); // 추상 메소드
}
class TestClass1 extends TestAbstract {
@Override
public int testMethod() { // 추상 메소드
return test;
}
}
// 추상 클래스를 상속받은 추상 클래스
abstract class TestAbstract2 extends TestAbstract {
int number;
public abstract int testMethod2();
}
class TestClass2 extends TestAbstract2 {
@Override
public int testMethod() {
return 0;
}
@Override
public int testMethod2() {
return 0;
}
}
TestAbstract 클래스는 추상 클래스이므로 인스턴스 생성이 안된다.
따라서 new TestAbstract() 작성 시 TestAbstract cannot be resolved to a type 오류가 발생한다.
TestAbstract 클래스의 getTest() 메서드는 추상 메서드가 아니다
그래서 상속받은 클래스가 무조건 구현해야 할 필요는 없다.
그러나 testMethod() 메서드는 추상 메서드임으로 TestAbstract 클래스를 상속받은 클래스에서는 무조건 구현해야 한다.
TestClass 클래스는 TestAbstract 클래스를 상속받았으므로 testMethod()를 구현해주었다.
구현하지 않으면 The type TestClass must implement the inherited abstract method TestAbstract.testMethod() 라는 오류 문구가 뜬다.
TestAbstract 추상 클래스를 상속 받은 TestAbstract2 추상 클래스를 만들었다.
TestAbstract2 또한 추상 클래스이므로 TestAbstract 클래스 내에 있는 추상 메서드를 구현하지 않아도 된다.
그러나 TestAbstract2를 상속받은 일반 클래스는 TestAbstract 클래스 내 추상 메서드와 TestAbstract2 클래스 내 추상 메서드를 모두 구현해야 한다.
TestAbstract2 추상 클래스를 상속받은 TestClass2는 TestAbstract 추상 클래스에 있는 testMethod() 추상 메서드를 구현하였고, TestAbstract2 추상 클래스 내에 있는 testMethod2() 추상 메서드 또한 구현하였다.
수정(내용 추가) 2022-06-09