본문 바로가기
JAVA

JAVA | 상속, 포함관계

by 개발송이 2022. 1. 24.

Ch7. 객체지향 프로그래밍2

 

1.상속(inheritance)

 

1.1상속의 정의와 장점

 

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

두 클래스를 부모-자식으로 관계를 맺어주는 것

class child extends Parent {
   //...
}  //extend확장

 

-자손은 조상의 모든 멤버를 상속받는다(생성자, 초기화블록 제외)

-자손의 멤버 개수는 조상보다 적을 수 없다(같거나 많다)

-자손의 변경은 조상에 영향을 미치지 않는다.

-자손클래스는 조상의 멤버를 모두 상속받기 때문에 조상클래스에 멤버변수 추가하면 자손에 자동추가되는 효과 얻음

-생성자와 초기화 블럭은 상속되지 않고 멤버만 상속된다.

 

조상클래스 - 부모클래스parent, 상위클래스super, 기반클래스base

자손클래스 - 자식child클래스, 하위sub클래스, 파생된derived클래스

class Tv{
	boolean power;
	int channel;
	
	void power() { power = !power; }
	void channelUp() { ++channel; }
	void channelDown() { --channel; }
}  //부모멤버 5개

class CaptionTv extends Tv {
	boolean caption;
	void displayCaption (String text) {
		if(caption) {
			System.out.println(text);
		}
	}
}  //자식멤버2 + 부모멤버5 = 멤버7개

class Ex1 {

	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");
	} //자손클래스의 인스턴스 생성하면 조상 클래스의 멤버도 생성되기 때문에 
      //따로 조상클래스의 인스턴스를 생성하지 않고도 조상클래스 멤버 사용가능
}

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

 

 

1.2 클래스간의 관계 - 포함관계(composite)

 

상속이외에도 클래스 재사용하는 방법은 클래스간의 포함관계를 맺어주는것.

클래스의 멤버로 참조변수를 선언하는 것 ->한 클래스의 멤버변수로 다른 클래스 타입의 참조변수를 선언하는 것

class Point{
    int x; //원점x좌표
    int y; //원점y좌표
}
//Point클래스를 재사용해 Circle클래스 작성

class Circle{
    Point c = new Point(); //원점
    int r;  //반지름
}

 

1.3 클래스간의 관계 결정하기

 

상속관계 '~은 ~이다' is a

포함관계 '~은 ~을 가지고 있다' has a

class Point {
	int x;
	int y;
}

//class Circle extends Point { //상속
//	int r;
//}

class Circle {   //원은 점을 가지고있다
    Point p = new Point();  //포함
    int r;
}

public class InheritanceTest {
	public static void main(String[] args) {
    	Circle c = new Circle();
        c.p.x = 1;      //상속일때는c.x = 1;
        c.p.y = 2;      //         c.y = 2;
        c.r = 3;
        System.out.println("c.p.x="+ c.p.x);
        System.out.println("c.p.y="+ c.p.y);
        System.out.println("c.p.r="+ c.p.r);
}
}
class Ex2 {

	public static void main(String[] args) {
		Point[] p = { new Point(100, 200),
					  new Point(140, 50),
					  new Point(200, 100) };
		
		Triangle t = new Triangle(p);
		Circle c = new Circle(new Point(150, 150), 50);
		//Point p = new Point(150, 150) + Circle c = new Circle(p, 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.x는 인스턴스변수, 뒤에 x는 지역변수
		this.y = y;
	}
	
	Point() {
		this(0,0); //생성자 초기화
	}
	
	String getXY() {
		return "("+x+","+y+")";  //x와 y값을 문자열로 반환
	}
}

class Circle extends Shape {  //원은 도형이다. is a 관계 - 상속
	Point center;  //원의 원점좌표 , 포함관계
	int r;    //반지름
	
	Circle() {
		this(new Point(0,0), 100);  //Circle(Point center, int r)호출. 생성자=초기화
	}     //Point는 포함이라서 합쳐진거
	
	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];  //삼각형은 점을 가지고있다 - 포함
							   //3개의 Point인스턴스를 담을 배열 생성
	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);
	}
}
public class Ex3 {

	public static void main(String[] args) {
		Deck d = new Deck();  //카드 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", "HERAT", "DIAMOND", "SPADE"};
		String numbers = "0123456789XJQK";
		return "kind : "+ kinds[this.kind] +",number :"+ numbers.charAt(this.number);
		
	}
}

 

 

1.4 단일상속 single inheritance

 

자바에서는 오직 단일 상속만을 허용한다.

둘 이상의 클래스로부터 상속받을 수 없다.

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

class VCR {
	boolean power;
	int counter = 0;
	void power() { power= !power;}
	void play() { /*생략*/ }
	void stop() { /*생략*/ }
	void rew() { /*생략*/ }
	void ff() { /*생략*/ }
}

class Ex4 extends Tv {

	VCR vcr = new VCR();  //두개를 상속하지 못하니 VCR은 포함시켜서 사용함
	
	void play() {
		vcr.play();
	}
	
	void stop() {
		vcr.stop();
	}
}

 

 

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

 

부모가 없는 클래스는 자동적으로 Object클래스를 상속받게 된다.

모든 클래스는 Object클래스에 정의된 11개의 메서드를 상속받는다,

->toString(). equals(Object obj). hashCode(), ...

 

모든 상속계층도의 최상위에는 Object클래스가 위치한다.