Day 15(21.09.27) - Gomserker/Java-101 GitHub Wiki

22. 좔상 클래슀(Abstract Class)

(1) 좔상 ν΄λž˜μŠ€λž€ 무엇인가?

좔상 ν΄λž˜μŠ€λž€ 무엇인가λ₯Ό μ–˜κΈ°ν•˜κΈ° 전에 이 μ§ˆλ¬Έμ— λŒ€ν•΄ 생각해 보자. "μžλ™μ°¨λž€ 무엇인가?". ꡉμž₯히 "좔상적"이지 μ•Šμ€κ°€? μš°λ¦¬κ°€ ν”νžˆ μžλ™μ°¨λΌκ³  λΆ€λ₯΄λŠ” κ²ƒμ—λŠ” 세단, 트럭, 컨버터블 λ“±μ˜ 차쒅이 μžˆλ‹€. μ—¬κΈ°μ„œ μ΄λŸ¬ν•œ 차쒅듀은 μžλ™μ°¨λΌλŠ” κ°œλ…μ΄ μ§€λ‹Œ 곡톡적인 νŠΉμ„±μ„ κ°€μ§€κ³  ꡬ체적인 ν˜•νƒœλ‘œ λ“œλŸ¬λ‚˜κ²Œ 된 것이닀.
이와 λ§ˆμ°¬κ°€μ§€λ‘œ λ§ˆμ°¬κ°€μ§€λ‘œ 객체 μ§€ν–₯ κ°œλ°œμ—μ„œμ˜ ν΄λž˜μŠ€μ—μ„œλ„ 좔상 ν΄λž˜μŠ€λΌλŠ” 것이 μ‘΄μž¬ν•œλ‹€. 객체λ₯Ό 직접 생성할 수 μžˆλŠ” 클래슀λ₯Ό 싀체 클래슀라고 ν•œλ‹€λ©΄ μ΄λ“€μ˜ κ³΅ν†΅λ˜λŠ” νŠΉμ„±μ„ μΆ”μΆœν•΄μ„œ μ„ μ–Έν•œ 클래슀λ₯Ό 좔상(Abstract) 클래슀라고 ν•œλ‹€. 논리적 관계λ₯Ό μƒκ°ν–ˆμ„λ•Œ, μ΄λŸ¬ν•œ 좔상 ν΄λž˜μŠ€μ™€ 싀체 ν΄λž˜μŠ€λŠ” 상속 관계λ₯Ό κ°€μ§€κ³  μžˆλ‹€λŠ” 것을 μ•Œ 수 μžˆλ‹€. 즉, 싀체 ν΄λž˜μŠ€κ°€ 좔상 클래슀λ₯Ό 상속 λ°›μ•„, 좔상 클래슀의 λͺ¨λ“  νŠΉμ„±μ„ λ¬Όλ €λ°›κ³ (상속), 좔가적인 νŠΉμ„±μ„ κ°€μ§ˆ 수 있게 λ˜λŠ” 것이닀.(μ˜€λ²„λΌμ΄λ“œ). μœ„μ˜ μžλ™μ°¨ μ΄μ•ΌκΈ°λ‘œ 생각을 해보면, 슀포츠카, 트럭, νƒμ‹œ 등이 싀체 클래슀이고, μžλ™μ°¨λΌλŠ” 포괄적인 κ°œλ…μ΄ 좔상 ν΄λž˜μŠ€κ°€ 되며, 싀체 ν΄λž˜μŠ€κ°€ μ§€λ‹Œ 곡톡적인 μš”μ†Œλ₯Ό 좔상 ν΄λž˜μŠ€μ—μ„œ 상속받아 μ‚¬μš©ν•  수 있게 λ˜λŠ” 것이라고 보면 λœλ‹€.
λ¬Όλ‘  좔상 ν΄λž˜μŠ€μ™€ 기본적인 λΆ€λͺ¨ 클래슀 μ—­ν• μ˜ μ°¨μ΄λŠ”, 좔상 ν΄λž˜μŠ€λŠ” 문자 κ·ΈλŒ€λ‘œ 좔상적인 κ°œλ…μ„ λ‹΄κ³  있기 λ•Œλ¬Έμ— κ·Έ 싀체가 담겨 μžˆμ§€ μ•Šλ‹€. λ‹€μ‹œ λ§ν•΄μ„œ, 싀체가 λ˜λŠ” 객체λ₯Ό 생성할 수 μ—†κ²Œλ˜λ©°, new μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•œ μΈμŠ€ν„΄μŠ€ 생성이 λΆˆκ°€λŠ₯ν•˜λ‹€. λ•Œλ¬Έμ— 좔상 ν΄λž˜μŠ€λŠ” 싀체 클래슀λ₯Ό λ§Œλ“€κΈ° μœ„ν•œ λΆ€λͺ¨ 클래슀의 μ—­ν•  μ™Έμ—λŠ” ν•  수 μ—†λ‹€. 상속 관계 μ„ μ–Έ μ½”λ“œλ‘œ μ‚΄νŽ΄λ³΄μžλ©΄ ~ extends λ’€μ—λ§Œ 올 수 μžˆλŠ” ν΄λž˜μŠ€λΌλŠ” λœ»μ΄λ‹€.

class Taxi extends Car (O)
class Cat extends Pet (O)
class Rifle extends Weapon (O)

μœ„ μ˜ˆμ‹œμ—μ„  Car와 Pet, Weapon이 ν•΄λ‹Ήλ˜κ² λ‹€.

(2) 좔상 클래슀λ₯Ό μ‚¬μš©ν•˜λŠ” 이유

싀체 ν΄λž˜μŠ€λ“€μ˜ κ³΅ν†΅λœ ν•„λ“œμ™€ λ©”μ†Œλ“œμ˜ 이름을 ν†΅μΌν•˜λ €κ³ 

싀체 ν΄λž˜μŠ€λ“€μ˜ 곡톡적인 νŠΉμ„±(ν•„λ“œ, λ©”μ†Œλ“œ)을 뽑아내어 좔상 클래슀둜 λ§Œλ“œλŠ” μ΄μœ λŠ” 크게 두 κ°€μ§€ μ΄μœ κ°€ μžˆλ‹€. 그쀑 ν•˜λ‚˜λŠ” λ°”λ‘œ κ³΅ν†΅λœ ν•„λ“œμ™€ λ©”μ†Œλ“œμ˜ 이름을 ν†΅μΌν•˜κΈ° μœ„ν•¨μ΄λ‹€. 예λ₯Ό λ“€μ–΄, μ»¨λ²„ν„°λΈ”μ˜ μ†Œμœ μ£Όλ₯Ό owner라고 ν•˜κ³ , μ‹œλ™μ„ κ±°λŠ” λͺ…령을 turnOn()이라고 ν–ˆμ„λ•Œ, νƒμ‹œμ˜ μ†Œμœ μ£Όλ₯Ό driver라고 ν•˜κ³ , μ‹œλ™μ„ κ±°λŠ” λͺ…λ Ήμ–΄κ°€ start()라고 ν•˜μž. κ³΅ν†΅λœ νŠΉμ§•μ΄μ§€λ§Œ ν•„λ“œλͺ…κ³Ό λ©”μ†Œλ“œμ˜ 이름이 제각각인 경우인데, μ΄λŸ΄λ•Œ CarλΌλŠ” 좔상 ν΄λž˜μŠ€μ— μ†Œμœ μ£Όλ₯Ό owner, μ‹œλ™μ„ κ±°λŠ” λͺ…λ Ήμ–΄λ₯Ό turnOn()이라고 μ„ μ–Έν•˜κ²Œ λœλ‹€λ©΄, 각 싀체 ν΄λž˜μŠ€λŠ” 이λ₯Ό 상속받아 μ‚¬μš©ν•¨μœΌλ‘œμ¨ ν•„λ“œμ™€ λ©”μ†Œλ“œμ˜ 이름을 톡일할 수 μžˆλ‹€.

싀체 클래슀λ₯Ό μž‘μ„±ν•  λ•Œ μ‹œκ°„μ„ μ ˆμ•½

μ΄λŠ” 상속과 λ™μΌν•œ μ΄μœ μ΄λ‹€. ν•­λͺ©μ˜ μ†Œμœ μ£ΌλΌλŠ” ν•„λ“œ κ°’κ³Ό, μ‹œλ™μ„ κ±΄λ‹€λŠ” λͺ…λ Ή, λ©”μ†Œλ“œκ°€ 좔상 ν΄λž˜μŠ€μ—μ„œ λͺ¨λ‘ μ„ μ–Έν•΄λ’€κΈ° λ•Œλ¬Έμ— 싀체 클래슀λ₯Ό μž‘μ„±ν•˜λŠ”λ° μ‹œκ°„μ„ μ ˆμ•½ν•  수 μžˆλ‹€. μ΄λŠ” λ‹€λ₯Έ κΈ°λŠ₯을 μΆ”κ°€ν•œλ‹€κ±°λ‚˜ ν• λ•Œλ§Œ μž¬μ •μ˜ ν•΄μ„œ μ‚¬μš©ν•˜λ©΄ λ˜κΈ°λ„ ν•˜κ³ , ν˜Ήμ€ λ‹€λ₯Έ ν”„λ‘œκ·Έλž˜λ¨Έμ™€ 같이 μž‘μ—…μ„ ν• λ•Œ, 좔상 클래슀 ν•˜λ‚˜λ§Œ 확인해도 ν•„λ“œμ™€ λ©”μ†Œλ“œμ˜ μ •μ˜λ₯Ό 확인할 수 있게 ν•¨μœΌλ‘œμ¨ μž‘μ—… μ „μ²΄μ˜ νš¨μœ¨μ„ μ˜¬λ¦¬λŠ”λ° κΈ°μ—¬ν•  수 있게 λœλ‹€.

(3) 좔상 클래슀 μ„ μ–Έ

좔상 클래슀λ₯Ό μ„ μ–Έν•  λ•Œμ—λŠ” 클래슀λ₯Ό μ„ μ–Έν•  λ•Œ abstract ν‚€μ›Œλ“œλ₯Ό 뢙인닀. μœ„μ—μ„œ λ§ν–ˆλ“― abstractλ₯Ό 뢙이면 μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 수 μ—†κ²Œ λ˜λ―€λ‘œ new μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•  수 μ—†κ³  상속 받은 μžμ‹ 클래슀λ₯Ό ν†΅ν•΄μ„œλ§Œ μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 수 μžˆλ‹€.

public abstract class 클래슀λͺ… {
  //field
  //constructor
  //method
}

(4) 좔상 λ©”μ†Œλ“œμ™€ μ˜€λ²„λΌμ΄λ”©

μ•„λž˜ μ˜ˆμ‹œλŠ” 좔상 λ©”μ†Œλ“œμ™€ 좔상 λ©”μ†Œλ“œμ˜ μ˜€λ²„λΌμ΄λ”©μ— κ΄€λ ¨λœ μ˜ˆμ‹œμ΄λ‹€.

public class HeroTest {
	public static void main(String[] args) {
		
//μ˜μ›… -> ꡉμž₯히 좔상적인 κ°œλ…
//슈퍼맨
	SuperMan superman = new SuperMan("슈퍼맨");
	superman.attack();
		
//아이언맨
	IronMan ironman = new IronMan("아이언맨");
	ironman.attack();
		
//헐크		
	Hulk hulk = new Hulk("헐크");
	hulk.attack();	
	}
}
public abstract class Hero {
	String name;
	
	public Hero() {}
	
	public Hero(String name) {
		super();
		this.name = name;
	}
	
	abstract void attack();
}

class SuperMan extends Hero{
	
	public SuperMan() {}
	
	public SuperMan(String name) {
		super(name);
	}
	
	@Override
	void attack() {
		System.out.println("Attack with Eyeball laserbeam");
	}
}

class IronMan extends Hero{
	
	public IronMan() {}
	
	public IronMan(String name) {
		super(name);
	}
	
	@Override
	void attack() {
		System.out.println("Attack with Hand laserbeam");
	}
}

class Hulk extends Hero{
	
	public Hulk() {}
	
	public Hulk(String name) {
		super(name);
	}
	
	@Override
	void attack() {
		System.out.println("Beat the shit out of them");
	}
}

μœ„μ—μ„œ 좔상 ν΄λž˜μŠ€λŠ” 싀체 ν΄λž˜μŠ€κ°€ κ³΅ν†΅μ μœΌλ‘œ κ°€μ Έμ•Ό ν•  ν•„λ“œμ™€ λ©”μ†Œλ“œλ“€μ„ μ •μ˜ν•΄ 놓은 좔상적인 클래슀라고 μ •μ˜ν–ˆλ‹€. λ§Œμ•½ λͺ¨λ“  싀체듀이 λ˜‘κ°™μ€ 행동을 ν•˜κ³ , λ˜‘κ°™μ€ κΈ°λŠ₯만 ν•œλ‹€λ©΄ 좔상 ν΄λž˜μŠ€μ— μ •μ˜ν•΄ 놓은 λ©”μ†Œλ“œλ‘œ λͺ¨λ“  것을 ν•œ λ²ˆμ— μ²˜λ¦¬ν•  수 μžˆμ„ 것이닀. ν•˜μ§€λ§Œ μ‹€μ œλ‘œλŠ” "동물"μ΄λΌλŠ” 좔상 ν΄λž˜μŠ€κ°€ μžˆλ‹€κ³  ν• λ•Œ, κ°œκ°€ μš°λŠ” μ†Œλ¦¬μ™€ 고양이가 μš°λŠ” μ†Œλ¦¬κ°€ λ‹€λ₯΄λ“―, μ‹€ν–‰ λ‚΄μš©μ΄ 싀체 ν΄λž˜μŠ€λ§ˆλ‹€ 달라야 ν•˜λŠ” κ²½μš°κ°€ λ°œμƒν•œλ‹€. μ΄λŸ΄λ•ŒλŠ” 각 싀체 ν΄λž˜μŠ€μ—μ„œ λ©”μ†Œλ“œλ₯Ό μž¬μ •μ˜ν•΄μ„œ μ‚¬μš©ν•΄μ•Όν•œλ‹€. 좔상 클래슀의 좔상 λ©”μ†Œλ“œλŠ” 일반적인 λ©”μ†Œλ“œμ˜ ν˜•νƒœμ™€ 쑰금 λ‹€λ₯Έλ°, μ„ μ–ΈλΆ€λ§Œ 있고 λ©”μ†Œλ“œμ˜ μ‹€ν–‰ λ‚΄μš©μΈ μ€‘κ΄„ν˜Έκ°€ μ—†λ‹€.

abstract void attack();
// μ ‘κ·Όμ œμ–΄μž abstract λ¦¬ν„΄νƒ€μž… λ©”μ†Œλ“œλͺ…(νŒŒλΌλ―Έν„°1, νŒŒλΌλ―Έν„°2, ...);

보톡 좔상 클래슀λ₯Ό μ„€κ³„ν• λ•Œ, ν•˜μœ„ ν΄λž˜μŠ€κ°€ λ°˜λ“œμ‹œ μ‹€ν–‰ν–ˆμœΌλ©΄ ν•˜λŠ” μ‹€ν–‰ λ‚΄μš©μ„ μ±„μš°λ„λ‘ κ°•μš”ν•˜κ³  μ‹Άμ„λ•Œ ν•΄λ‹Ή λ©”μ†Œλ“œλ₯Ό 좔상 λ©”μ†Œλ“œλ‘œ μ„ μ–Έν•œλ‹€. 그리고 μžμ‹ ν΄λž˜μŠ€λŠ” ν•΄λ‹Ή λ©”μ†Œλ“œλ₯Ό μž¬μ •μ˜ ν•΄μ„œ μ‚¬μš©ν•΄μ•Ό ν•œλ‹€. λ§Œμ•½ κ·ΈλŸ¬μ§€ μ•ŠμœΌλ©΄ 컴파일 μ—λŸ¬κ°€ λ‚œλ‹€. κ·ΈλŸ¬λ‹ˆ λͺ¨λ‘ λΆ€λͺ¨λ‹˜μ΄ ν•˜λŠ” 말을 잘 λ“£μž. μ•„λ‹ˆλ©΄ 등짝 λ§žλŠ”λ‹€.