개발계발
추상 클래스와 봉인 클래스 본문
추상 클래스란?
객체를 생성할 수 있는 클래스를 실체 클래스라고 했을 때, 이 클래스들의 공통적인 필드와 메소드를 추출해서 선언한 클래스를 추상 클래스라고 한다.
추상 클래스는 실체 클래스의 부모 역할을 한다.
예를 들어 새, 강아지, 고양이라는 실체 클래스가 있을 때 동물이라는 추상 클래스를 만들어 부모 역할을 하도록 할 수 있다.
주의 사항
- 추상 클래스는 new 연산자를 이용해 객체를 직접 생성할 수 없고, 실체 클래스를 만들기 위한 부모 클래스로만 사용된다.(extends 뒤에만 올 수 있음)
추상 클래스 선언
클래스 선언 시 abstarct 키워드를 붙이면 추상 클래스가 된다.
위에서 작성했듯이, 객체를 직접 만들지 못하고 상속을 받은 자식클래스만 만들 수 있다.(생성자가 없는 것은 아님)
추상 클래스 예시
public abstract class Phone {
// 필드
String owner;
// 생성자
Phone(String owner) {
this.owner = owner;
}
// 메소드
void turnOn() {
System.out.println("전원을 켭니다");
}
void turnOff() {
System.out.println("전원을 끕니다");
}
}
위의 추상 클래스를 상속받은 자식 클래스 예시
public class SmartPhone extends Phone {
// 생성자
SmartPhone(String owner) {
super(owner);
}
// 메소드
void userInternet() {
System.out.println("인터넷 연결")
}
}
위 두 코드를 보면 Phone이라는 추상클래스를 SmartPhone이라는 실체 클래스가 상속받아 부모 클래스의 생성자를 사용하는 걸 볼 수 있다.
SmartPhone 클래스를 이용해 객체를 생성하는 코드는 아래와 같다.
public class PhoneExample {
public static void main(String[] args) {
// Phone phone = new Phone(); <- 추상클래스는 new연산자 사용 불가능
SmartPhone newPhone = new SmartPhone("한국인");
smartPhone.turnOn(); // 추상클래스 Phone의 메소드 사용
}
}
추상 메소드
메소드도 추상 클래스처럼 추상 메소드를 선언할 수 있다.(실체 클래스에서는 불가능)
주의 사항
- abstract 키워드를 붙여야하며, 메소드 실행내용(중괄호)를 작성하면 안된다.
예를 들어, 모든 동물은 소리를 내지만 각자의 소리는 다르다.
아래 코드를 보자.
public abstract class Animal {
// 일반 메소드
public void breathe() {
System.out.println("모든 동물은 숨을 쉰다");
}
// 추상 메소드
public abstract void sound(); // 동물마다 울음소리는 다르다.
}
위와 같이 Animal 추상 클래스와 sound() 추상 클래스를 작성한 후 실체 클래스에서는 아래와 같이 사용가능하다.
public class Dog extends Animal { // Animal 추상 클래스를 상속 받음
// 추상 메소드 정의
@Override
public void sound() {
System.out.println("개는 멍멍");
}
}
public class Cat extends Animal { // Animal 추상 클래스를 상속 받음
// 추상 메소드 정의
@Override
public void sound() {
System.out.println("고양이는 야옹");
}
}
봉인된 클래스
이전 포스팅부터 부모클래스와 상속 그리고 추상클래스 대해 알아봤는데, 무분별한 자식 클래스 생성을 방지하는 봉인된 클래스가 존재한다.
sealed와 permits키워드를 이용해 상속받을 수 있는 클래스를 제한할 수 있다.
public sealed class Person permits Employee, Manager { ... }
위와 같이 작성하면 Person이란 클래스는 Emloyee와 Manager 클래스만이 상속 받을 수 있고, 다른 클래스는 Person을 상속받을 수 없다.
그럼 Person을 상속받은 Employee와 Manager 클래스는 아래와 같이 사용해야 한다.
public final class Employee extends Person {...}
public non-sealed class Manager extends Person {...}
- final은 이전에 학습했듯이, 더 이상 상속이 불가능하도록 막는 것이고,
- non-sealed는 봉인을 해제한다는 뜻이다. (다른 클래스가 Manager를 상속받을 수 있음)