본문 바로가기

Programming/JAVA

상속(12) - 추상 클래스 2

java logo image

 

 

 

앞의 추상 클래스 아티클에서는 다소 길지만 추상 클래스의 개념과 관념적인 특성을 함께 살펴보았습니다. 추상 - 실체 클래스의 관계가 부모 - 자식 클래스의 기본 관계를 의미하며, 추상 클래스는 일반적인 부모 클래스처럼 인스턴스 생성이 불가능하고 오로지 실체 클래스들의 공통 성분을 상속하는 역할만을 한다고 했습니다. 이제, 이러한 추상 클래스의 기본 특성을 바탕으로 왜? 이러한 클래스를 사용하는지 살펴보겠습니다. 

 

 

 

상속(12) - 추상 클래스 1

추상 클래스는 이름만 보았을 때는 상속과 관계가 없어 보이지만, 사실 추상 클래스는 부모-자식 클래스의 사용의 응용된 버전입니다. 그래서 기본적인 클래스 상속 관계에 대한 이해도 뒷받침

nozeroslope.tistory.com

 

 

 


 

 

 

기본적으로 추상 클래스의 목적을 이해하기 위해서는, 클래스를 설계하는 사람과 각각의 실체(자식) 클래스를 작성하는 사람이 모두 다르다는 상황을 상정하면 좋습니다. 

 

1. 클래스의 공통 필드 / 메서드 이름의 통일

 

우선, CellPhone이 부모 클래스이고 이를 상속하는 GalaxyS23, GalaxyFold, GalaxyFlip이라는 자식 클래스가 있다고 가정하겠습니다. 기본적으로 전원을 켜는 메서드는 turnOn( ), 기기의 시리얼 넘버는 serialNumber라고 지정해 통일하려고 합니다. 그런데 각각의 자식 클래스가 powerOn( ), serial 이런 식으로 자신들이 멋대로 메서드와 필드 명을 지정하게 되면 혼란이 생기게 되겠죠? 

 

이러한 상황을 방지하기 위하여 클래스 설계를 담당하는 사람이 이러한 공통 요소를 미리 선언해둔 추상 클래스를 선언함으로써 공통으로 사용할 영역을 미리 정해두는 것입니다. 

 

 

2. 실체 클래스 작성 시간의 절약

 

비슷한 이야기이지만, 이도 역시 구조 설계의 관점에서 설명이 필요합니다. 즉, 미리 부모 클래스 역할을 하는 추상 클래스에 실체 클래스가 공통된 요소를 중복해서 구현하지 않도록 미리 규격화된 필드와 메서드 등을 작성해 두는 것입니다. 추상 클래스인 CellPhone을 미리 작성한 다음, GalaxyS23이나 GalaxyFold 실체 클래스를 만드는 사람들에게 이를 전달하면 실체 클래스를 작성할 때 미리 선언된 추상 클래스의 필드나 메서드를 사용하게 되는 것입니다. 

 

 


 

 

그럼 이제 추상 클래스의 선언과 사용 방법을 구체적으로 알아보겠습니다. 우선 접근 제한자 다음에 abstract 키워드를 추가하면 이는 곧 추상 클래스로 선언되며 단독으로 인스턴스를 생성할 수 없게 됩니다. 

 

public abstract class ClassName {
	// 필드
	// 생성자
	// 메서드
}

 

추상 클래스 역시 일반 클래스와 마찬가지로 필드, 생성자, 메서드를 선언하게 됩니다. 생성자의 경우 일반적인 부모-자식 클래스에서의 생성자 호출 원리와 마찬가지로 기본 생성자 호출 및 super( )를 사용한 추상 클래스의 생성자 호출이 가능하므로 상황에 맞는 생성자 선언과 호출이 필요합니다. 예를 들어, 추상 클래스에 파라미터가 있는 생성자가 선언된다면 반드시 실체 클래스는 super( )를 통한 생성자 선언이 필요하게 됩니다.

 

 

 

상속(2) - 부모 생성자의 호출(super)

자식 객체는 반드시 부모 객체가 있어야 생겨날 수 있는 존재입니다. 이 점은 이해가 가시죠? 너무나도 당연한 이야기이지만, 다시 이러한 내용을 상기하는 이유는 "부모 객체를 상속하는 자식

nozeroslope.tistory.com

 

그러면 이제 간단하게 SmartPhone과 GalaxyFold라는 추상 - 실체 클래스의 관계를 가정하고, 추상 클래스를 사용하는 예제를 만들어 보도록 하겠습니다. 

 

 


 

 

public abstract class SmartPhone {
	// 필드
	public String user;
	
	// 생성자
	public SmartPhone(String user) {
		this.user = user;
	}
	
	// 메서드
	public void powerOn() {
		System.out.println("Phone is starting...");
	}
	
	public void powerOff() {
		System.out.println("Power Off...");
	}
}

 

public class GalaxyFold extends SmartPhone {
	// 생성자
	public GalaxyFold(String user) {
		super(user);
	}
	
	// 메서드
	public void folding() {
		System.out.println("디바이스가 접혔습니다");
	}
}

 

public class ExampleMain {	
	public static void main(String[] args) {
		GalaxyFold galaxyFold = new GalaxyFold("ZICO");
		
		galaxyFold.powerOn();
		galaxyFold.folding();
		galaxyFold.powerOff();
	}
}

/* 출력
Phone is starting...
디바이스가 접혔습니다
Power Off...
*/

 

위 실행 클래스에서는 오직 GalaxyFold 클래스만을 인스턴스 생성하여 모든 메서드를 실행한 것을 확인할 수 있습니다.