JAVA

[JAVA] 상속(inheritance)

큐범 2021. 8. 17. 10:05

상속의 정의와 장점

상속 : 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것

장점 : 양적으로 적은 양을 통해 코드로 새로운 클래스를 작성할 수 있으며 코드를 공통적으로 관리할 수 있기 때문에 코드의 추가 및 변경이 매우 유용하다.

class child extends parent{
...
}

조상 클래스 : 부모(parent)클래스, 상위(super)클래스, 기반(base)클래스

자손 클래스 : 자식(child)클래스, 하위(sub)클래스, 파생된(derived)클래스

상속의 키워드가 extend인 이유

  • 생성자와 초기화 블럭은 상속되지 않는다. 멤버만 상속된다.
  • 자손 클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많다.
package object_oriented_programming2;

class Tv {
	boolean power;
	int channel;
	
	void power() {power = !power;}
	void channelUp() {++channel;}
	void channelDown() {--channel;}
}

class CaptionTv extends Tv{
	boolean caption;
	void displayCaption(String text){
		if(caption) { //캡션상태가 on일 경우에만 text를 보여준다.
			System.out.println(text);
		}
	}
}

public class CaptionTvTest {
	public static void main(String[] args) {
		CaptionTv ctv = new CaptionTv();
		ctv.channel = 10;
		ctv.channelUp();
		System.out.println(ctv.channel);
		ctv.displayCaption("Hello World");
		ctv.caption = true;
		ctv.displayCaption("Hello World");
		
	}

}
//결과
11
Hello World

자손 클래스의 인스턴스를 생성하면 조상 클래스의 멤버와 자손 클래스의 멤버가 합쳐진 하나의 인스턴스로 생성된다.

클래스 간의 관계 - 포함관계

클래스 간의 '포함(composite)'관계를 맺어주는 것이다. 클래스 간의 포함관계를 맺어 주는 것은 한 클래스의 멤버변수로 다른 클래스 타입의 참조변수를 선언하는 것을 뜻한다.

class Circle{
	int x;
	int y;
	int r;
}
class Circle{
	Point c = new Point();
	int r;
}

 

클래스간의 관계 결정하기

클래스를 작성하는데 있어서 상속 관계를 맺어 줄 것인지 포함 관계를 맺어 줄 것인지 결정하기 애매한 경우가 종종 존재한다 그럴 경우에는, '~은 ~이다(is-a)'와 '~은 ~을 가지고 있다(has-a)'를 넣어서 문자을 만들어 보면 클래스 간의 관계가 보다 명확해진다.

원은 점이다.(Circle is a Point), 원은 점을 가지고있다.(Circle has a Point)

→원은 반지름으로 구성되므로 첫번째보다 두번째 문장이 더 옳다는 것을 알 수 있다.

💡
상속관계 : '~은 ~이다. (is-a) 포함관계 : '~은 ~을 가지고 있다.(has-a)'
package object_oriented_programming2;

public class DrawShape {

	public static void main(String[] args) {
		Point [] p = {  new Point(100, 100),
						new Point(140, 50),
						new Point(200, 100)
				
		};
		
		Triangle t = new Triangle(p);
		
		Circle c = new Circle(new Point(150,150),50);
		
		t.draw();
		c.draw();		
	}
}

class Shape{
	String color = "black";
	void draw() {
		System.out.printf("[color=%s]%n", color);
	}
}

class Point {
	int x;
	int y;
	
	Point(int x, int y){
		this.x = x;
		this.y = y;
	}
	
	Point(){
		this(0,0);
	}
	
	String getXY() {
		return "("+x+", "+y+")"; 
	}
}
class Circle extends Shape{
	Point center;
	int r;
	
	Circle(){
		this(new Point(0,0),100);
	}

	Circle(Point center, int r) {
		this.center = center;
		this.r = r;
	}
	
	void draw() {
		System.out.printf("[center = (%d, %d), r=%d, color=%s] %n", center.x, center.y, r,color);
	}
}

class Triangle extends Shape{
	Point[] p = new Point[3];
	
	Triangle(Point[] p) {
		this.p = p;
	}
	void draw() {
		System.out.printf("[p1=%s, p2=%s, p3=%s, color=%s]%n", p[0].getXY(),p[1].getXY(),p[2].getXY(),color);
	}
}
//결과
[p1=(100, 100), p2=(140, 50), p3=(200, 100), color=black]
[center = (150, 150), r=50, color=black]

A Circle is a shape. → 원은 도형이다.

A Circle is a shape. → 원은 점이다?

 

A Circle has a shape. → 원은 도형을 가지고 있다?

A Circle has a Point. → 원은 점을 가지고있다.

카드뽑기

package object_oriented_programming2;

public class DeckTest {

	public static void main(String[] args) {
		Deck d = new Deck();
		Card c = d.pick(0);
		System.out.println(c);
		
		d.shuffle();
		c = d.pick(0);
		System.out.println(c);
	}
}
class Deck{
	final int CARD_NUM = 52;
	Card cardArr[] = new Card[CARD_NUM];
	
	Deck() {
		int i = 0;
		
		for(int k=Card.KIND_MAX; k>0; k--) 
			for(int n=0; n<Card.NUM_MAX; n++) 
				cardArr[i++] = new Card(k, n+1);
	}
		
		Card pick(int index) {
			return cardArr[index];
		}
		
		Card pick() {
			int index = (int)(Math.random() * CARD_NUM);
			return pick(index);
		}
		
		void shuffle() {
			for(int i=0; i<cardArr.length; i++) {
				int r = (int)(Math.random() * CARD_NUM);
				
				Card temp = cardArr[i];
				cardArr[i] = cardArr[r];
				cardArr[r] = temp;
			}
		
	}
}
	

class Card{
	static final int KIND_MAX = 4;
	static final int NUM_MAX = 13;
	
	static final int SPADE = 4;
	static final int DIAMOND = 3;
	static final int HEART = 2;
	static final int CLOVER = 1;
	int kind;
	int number;
	
	Card(){
		this(SPADE, 1);
	}
	
	Card(int kind, int number){
		this.kind = kind;
		this.number = number;
	}
	
	public String toString() {
		String[] kinds = {"","CLOVER","HEART","DIAMOND","SPADE"};
		String number = "0123456789XJQK";
		
		return "kind : "+kinds[this.kind]+", number : "+number.charAt(this.number);
	}
}
//결과
kind : SPADE, number : 1
kind : CLOVER, number : Q

단일상속(single inheritance)

자바는 단일상속만을 허용하고 c++과는 다르게 다중상속을 허용하지 않음.

package object_oriented_programming2;

class Tv2{
	boolean power;
	int channel;
	
	void power() {power = !power;}
	void channelUp() {++channel;}
	void channelDown() {--channel;}
}

class VCR {
	boolean power;
	int counter = 0;
	void power() {}
	void play() {}
	void stop() {}
	void rew() {}
	void ff() {}
}

class TVCR extends Tv2{
	VCR vcr = new VCR();
	
	void play() {
		vcr.play();
	}
	
	void stop() {
		vcr.stop();
	}
	
	void rew() {
		vcr.rew();
	}
	
	void ff() {
		vcr.ff();
	}
}

Object클래스 - 모든 클래스의 조상

class Tv extends Object {
	...
}
 

출처 : JAVA의 정석 - (남궁성지음)