백_곰 2021. 1. 8. 12:15

1. 상속을 씀으로써 얻을 수 있는 기대효과

(1) 코드의 재사용성을 높이고 코드의 중복성을 제거할 수 있다.

 

(2) 프로그램의 생산성과 유지보수에 크게 기여된다.

 

 

 

2. 부모와 아이

- 부모는 조상, 상위, 기반 클래스라고도 불리어진다.

 

- 아이는 자손, 하위, 파생된 클래스라고도 불리어진다.

 

( age는 부모에서 생성된 age이다. )

( 이처럼 age는 아이에게 포함되므로 부모에서 정의한 것을 같이 사용할 수 있다. )

 

 

 

3. 상속될 때 규칙

(1) 생성자와 초기화 블럭은 상속되지 않는다. 맴버만 상속될 수 있다.

 

(2) 항상 상위 클래스보다 하위클래스는 같거나 많은 맴버를 갖는다.

 

 

 

 

4. 간접적인 상속 관계

 

( GrandChild와 Parent 관계가 있을 때, 우리는 간접적인 상속 관계라고 부른다. )

 

 

 

5. 클래스 간의 관계: 포함관계

- 상속이외에도 클래스를 재사용하는 또 다른 방법이 있는데, 그것은 클래스 간에 '포함' 관계를 맺어 주는 것이다.

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

뜻한다.

 

 

- 아래의 예제를 통해 이해하자.

 

( 위는 평범한 코드지만, 포함 관계를 쓰면 아래의 코드처럼 바뀐다. )

 

 

( Circle이 Point를 포함함으로써 '원은 점을 가지고 있다' 라는 뜻이 된다. )

 

( 이렇게 해준다면, 클래스를 작성하는 것이 쉽고 코드도 간결해서 이해하기 쉽다. )

( 또한 단위 클래스별로 코드가 작게 나뉘어 작성되어 있기 때문에 코드를 관리하는데도 수월하다. )

 

 

 

6. 클래스 간의 관계 결정하기: 상속 vs 포함

- 상속이냐 포함이냐 를 따질 때, 우리는 '~은 ~이다'(상속)'~은 ~을 가지고 있다'(포함) 를 넣어서 문장을 만들어보면 클래스 간의 관계가 보다 명확해진다.

 

- 포함은 위의 예제로 따지면 '원은 점이다''원은 점을 가진다' 중에 옳은 문장은 후자가 된다.

 

- 상속은 예를 들면 '사람은 부모이다''부모는 사람이다' 중에 옳은 문장은 후자가 된다.

 

 

 

7. 예제(1) - 배열로 객체 선언하고 반환해보기.

( '원은 도형이다' 와 '원은 점을 가진다' 가 옳은 문장이므로, 위의 예제처럼 잘 결정해야 한다. )

 

 

 

8. 예제(4) - 예제(1)을 실제 활용해보는 예제이다.

public class Exercise001 {	
	
	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+")"; // x와 y의 값을 문자열로 반환
	}
}

class Circle extends Shape {
	Point center;	// 원의 원점좌표
	int r;			// 반지름

	Circle() {		
		this(new Point(0, 0), 100); // Circle(Point center, int r)를 호출
	}

	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);
	}
}

 

 

 

9. 예제(3) - 배열로 객체 선언하고 반환해보기. (포함)

public class Exercise001 {	
	
	public static void main(String[] args) {
		Deck d = new Deck();	   // 카드 한 벌(Deck)을 만든다.
		Card c = d.pick(0);	   // 섞기 전에 제일 위의 카드를 뽑는다.
		System.out.println(c); // System.out.println(c.toString());과 같다.

		d.shuffle();			   // 카드를 섞는다.
		c = d.pick(0);		   // 섞은 후에 제일 위의 카드를 뽑는다.
		System.out.println(c);
	}
}

// Deck클래스
class Deck {
	final int CARD_NUM = 52;	// 카드의 개수
	Card cardArr[] = new Card[CARD_NUM];  // Card객체 배열을 포함

	Deck () {	// 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) {	// 지정된 위치(index)에 있는 카드 하나를 꺼내서 반환
		return cardArr[index];
	}

	Card pick() {			// Deck에서 카드 하나를 선택한다.
		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;
		}
	}
} // Deck클래스의 끝

// Card클래스
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 numbers = "0123456789XJQK"; // 숫자 10은 X로 표현

		return "kind : " + kinds[this.kind] 
			+ ", number : " + numbers.charAt(this.number);
	} // toString()의 끝
} // Card클래스의 끝

 

( 여기서 Deck과 Card 클래스의 관계가 무엇인지 확인해본다. )

( Card의 toString 함수에 대해 무엇인지 확인해본다. )