추상 클래스(Abstract Class)는 추상 메소드를 선언해 놓고 상속을 통해 자식 클래스에서 메소드를 완성하도록 유도하는 클래스이다. 이러한 특성 탓에 미완성 설계도라고 표현하기도 한다. 추상클래스는 상속을 위한 클래스이기 때문에 따로 인스턴스를 생성할 수 없다.
객체를 직접 생성할 수 있는 클래스를 실체 클래스라고 한다면
이 클래스들의 공통적인 특성(필드, 메소드)을 추출해서 선언한 클래스
를 추상클래스하고 한다.
- 공통된 필드와 메소드를 통일할 목적
실체 클래스를 설계하는 사람이 여러 사람일 경우, 실체 클래스마다 필드와 메소드가 제각기 다른 이름을 가질 수 있다. 따라서, 필드와 메서드 이름을 통일하여 유지보수성을 높이고 통일성을 유지
할 수 있다.
상위 클래스의 특징을 하위클래스에서 그대로 물려 받아 사용할 수 있는 상속 특징을 이용하여 코드의 중복 제거, 코드 재사용성 증대 효과
를 누릴 수 있게 된다. 즉, 자주 사용될 것이 예상되는 기능을 모아놓은 추상 클래스를 한번 만들어 놓으면 편하게 재사용을 함으로써 유지보수 효율화를 추구할 수 있는 것
- 실체클래스 구현시, 시간절약 및 규격에 맞는 구현
공통적인 필드와 메소드는 추상클래스에 구현해두고 실체클래스에서는 다른 점만 선언하면 클래스를 작성하는 데 시간을 절약할 수 있다. 일반적으로 개발프로젝트에서 설계자가 코더에게 클래스는 어떤 구조로 작성해야 한다는 것을 알려 준다.
💡 TIP
사실 공통된 필드와 메서드를 통일하는 목적으로는 일반 클래스로도 가능하여 꼭 추상 클래스만의 고유 용도라고는 보기에는 힘들다. 하지만 이 부분을 추상 클래스 활용 예제로 넣은 이유는 인터페이스(Interface)와의 차이점을 위해서 이다.
Java8의 인터페이스도 똑같이 안에 필드를 선언해 줄 수 있지만, 자동으로 public static final 처리가 되기 때문에 이른바 공통 상수가 되어 버린다.
따라서 자식 클래스에서 중복되는 변수들을 상속으로 묶어 통합 시켜주는 기능 자체는 인터페이스로 구현할 수 없고 오로지 추상 클래스 로만 가능하다는 소리이다
추상 클래스(abstract class)란, 하나 이상의 추상 메소드를 포함한 클래스
단 하나 이상의 추상 메소드만 포함하면 되며 생성자, 일반 메서드도 포함 가능
합니다.
추상클래스와 인터페이스의 다른 점은 인터페이스는 추상메소드"만" 포함하나, 추상 클래스는 일반메소드도 포함할 수 있다.
public abstract class 클래스명{
//필드
//생성자
//메소드
//추상메소드
}
추상 메소드(abstract method)란 자식 클래스에서 반드시 오버라이딩해야만 사용할 수 있는 메소드를 의미합니다.
자바에서 추상 메소드를 선언하여 사용하는 목적은 추상 메소드가 포함된 클래스를 상속받는 자식 클래스가 반드시 추상 메소드를 구현하도록 강제하기 위함입니다.
예를 들면 모듈처럼 중복되는 부분이나 공통적인 부분은 미리 다 만들어진 것을 사용하고, 이를 받아 사용하는 쪽에서는
자신에게 필요한 부분만을 재정의하여 사용함으로써 생산성이 향상되고 배포 등이 쉬워지기 때문입니다.
이러한 추상 메소드는 선언부만이 존재하며, 구현부는 작성되어 있지 않습니다.
바로 이 작성되어 있지 않은 구현부를 자식 클래스에서 오버라이딩하여 사용하는 것입니다.
[ public | protected ] abstract 리턴타입 메소드명(매개변수1, 매개변수2, ... );
추상 메서드의 경우, 자식 클래스에서 구현이 반드시 이뤄줘야 하기때문에 private 접근제어자는 사용할 수 없다.
abstract class Animal {
// 필드
protected String kind;
//메소드
protected void breath() {
System.out.println("숨을 쉽니다.");
}
protected abstract void sound();
}
public class Cat extends Animal{
//생성자
Cat(){
this.kind = "포유류";
}
@Override
protected void sound() {
System.out.println("야옹");
}
}
class Dog extends Animal{
//생성자
Dog(){
this.kind = "포유류";
}
@Override
protected void sound() {
System.out.println("멍멍");
}
}
public class Example {
public static void main(String[] args) {
// Animal animal = new Animal(); // 추상 클래스는 인스턴스를 생성할 수 없음
Cat cat = new Cat();
Dog dog = new Dog();
cat.sound();
dog.sound();
System.out.println("ㅡㅡㅡㅡㅡㅡ");
// 변수의 자동 타입 변환
Animal animal = null;
animal = new Cat();
animal.sound();
animal = new Dog();
animal.sound();
System.out.println("ㅡㅡㅡㅡㅡㅡ");
// 메소드의 다형성
animalSound(new Cat());
animalSound(new Dog());
}
// 매개변수가 부모클래스일 경우 자식클래스도 매개값으로 사용가능
// 추상클래스 타입 변수는 추상클래스를 상속받은 실체클래스의 타입으로 자동 타입변환이 된다.
private static void animalSound(Animal animal) {
animal.sound();
}
}
야옹
멍멍
ㅡㅡㅡㅡㅡㅡ
야옹
멍멍
ㅡㅡㅡㅡㅡㅡ
야옹
멍멍