본문 바로가기
멀티캠퍼스 풀스택 과정/Java의 정석

자바의 정석3-1 상속(Inheritance)과 포함(composite)

by 이쟝 2022. 1. 1.

상속: 두 클래스를 부모와 자식으로 관계를 맺어주는 것.

- 기존의 클래스로 새로운 클래스를 작성하는 것(코드의 재사용)

- 자손은 조상(부모의 부모)모든 멤버를 상속받는다.(생성자, 제외)

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

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

 

기본 구조

class 자식클래스 extends 부모클래스 { // … }

 

class Parent { 
     int age;     //멤버 1개
}

class Child extends Parent {
       // …        //자신의 멤버 0개, 상속받은 멤버 1개 -> 멤버 1개
}

 

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

 

class Parent {
     int age;    // 멤버 1개
} 
class Child extends Parent {
      void play( ) {
          System.our.println(“놀자!”);  // 새로운 멤버 추가해도 Parent에 영향 미치지 xx -> 자신의 멤버 1개, 상속받은 멤버 1개 -> 총 멤버 2개
    } 
}

 

자손의 변경은 조상에 영향을 미치지 않음


class Point {  // 2차원 좌표의 점을 나타내기 위한 클래스

       int x;

       int y;

}

 

class Point3D { 
       int x;
       int y;
       int z;
}
class Point3D extends Point { 
       int z;
}
3차원 좌표의 한 점을 만드는 point3D 클래스(상속 xx)
Point클래스와 관계를 받지 않기 때문에 Point클래스의 변경에 영향을 받지 않음
3차원 좌표의 한 점을 만드는 point3D 클래스(상속받음)
Point클래스에게 상속받기 때문에 Point클래스의 변경에 영향을 받음
멤버변수 3(x, y, z) 멤버변수 3(상속받은 멤버(x,y) + 자신의 멤버(z))

 

예제 부모클래스 Tv와 자식 클래스 SmartTv 클래스

 

public class Inherit {

	public static void main(String[] args) {
		SmartTv stv = new SmartTv();
		stv.channel = 10;   // Tv 클래스로부터 상속받은 멤버
		stv.channelUp();    // Tv 클래스로부터 상속받은 멤버
        
		System.out.println(stv.channel);         // 11
		stv.displayCaption("Helo, Java");
		stv.caption = true;   // 캡션(자막)기능을 켠다.
		stv.displayCaption("Hello, World");     // Hello, World
	}
}
// 부모 클래스 멤버 5개(2개 변수와 3개의 메서드)
class Tv {   //부모 클래스 멤버 5개

	boolean power;  // 전원상태(on/off)
	int channel;    // 채널
	
	void power() { power = !power; }
	void channelUp() { ++channel; }
	void channelDown() { --channel; }
}
// 자식 클래스 멤버 7개(2개 + 5개)
class SmartTv extends Tv {  // SmartTv는 Tv에 캡션(자막)을 보여주는 기능을 제공

	boolean caption;     // 캡션상태(on/off)
    
	void displayCaption(String text) {
		if(caption) {    // 캡션 상태가 on(true)일 때만 text를 보여준다.
			System.out.println(text);
		}
	}
}

포함 관계 

포함(composite): 클래스의 멤버로 참조변수를 선언하는 것

작은 단위의 클래스를 만들고, 이 들을 조합해서 클래스를 만든다.

1번 클래스 생성, 2번 클래스 안에 1번 클래스의 객체 생성, 1번 클래스의 메서드를 사용하는 것

 

class Point {  // 2차원 좌표의 점을 나타내기 위한 클래스

       int x;

       int y;

}

 

class Point3D { 
       int x;
       int y;
       int r;
}
class Circle {
       Point c = new Point();  //원점
       int r;                 //반지름
}
  Circle 클래스이 Point 클래스를 포함(Point c = new Point( ))
저장공간 3(x, y, r) 저장공간 3(r, 참조변수 cxy의 주소값 가리킴)

 

class Car {

       Engine e = new Engine();  // 엔진

       Door[] d = new Door[4];   // , 문의 개수를 넷으로 가정하고 배열로 처리함

}

-> Car 클래스가 Engine 클래스와 Door 객체 배열을 포함!(복잡도가 줄어듦)


클래스 간의 관계 결정하기

상속관계 ~은 ~이다. (is – a)’

포함관계 ~은 ~을 가지고 있다. (has – a)’

AB를 넣어서 자연스러운 것으로 관계를 정립함!(AB이다, AB를 가지고 있다.)

-> 보통 대부분은 상속보다는 포함!, 상속은 여러 가지 제약이 많기 때문에 꼭 필요할 때만!

 

class Circle {
       Point c = new Point(); 
       int r;
}
class Circle extends Point { 
       int r;
}
(Circle)은 점(Point)를 가지고 있다. (포함) CirclePoint클래스를 상속받음

 

예제 1) Point 클래스 생성, Circle 클래스 생성하고 상속을 사용

 

public class Inherit2 {
	public static void main(String[] args) {
		Circle c = new Circle(); // 참조변수의 초기화
		c.x = 1; 
		c.y = 2;
		c.r = 3;
		System.out.println("c.x = " + c.x);
		System.out.println("c.y = " + c.y);
		System.out.println("c.r = " + c.r);
	}
}
class Point {
	int x;
	int y;
}

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

 

예제 2) Point 클래스 생성, Circle 클래스 생성하고 포함을 사용

 

public class Inherit2 {

	public static void main(String[] args) {
		Circle c = new Circle();  
		c.p.x = 1; 
		c.p.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.r = " + c.r);
	}
}

class Point {
	int x;
	int y;
}

class Circle { // 포함
	Point p = new Point();
	int r;
}

//class Circle { // 포함(생성자를 선언해서 그 안에서 초기화 해도됨)위의 코드와 같음
//	Point p;
//	int r;
//	
//	Circle() {
//		p = new Point();
//	}
//}

단일 상속(Single Inheritance)

- Java는 단일상속만을 허용한다.(C++은 다중상속 허용)

- 하나의 부모만 상속 허용 예) class TvDVD extends Tv, DVD

- 비중이 높은 클래스 하나만 상속관계, 나머지는 포함관계로 한다.

 

 


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

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

- 컴파일러가 자동적으로 추가해줌

- 모든 클래스는 Object클래스에 정의된 11개의 메서드를 상속받는다. (toString( ), equals(Object obj), hashCode( ), …

 

class Point {
       int x;
       int y;
}
class Point extends Object {
       int x;
       int y;
}

 

-> 자동으로 컴파일러가 Object 클래스를 추가해줌

-> Object로부터 상속받은 toString( )메서드를 사용할 수 있다.

 

Circle c = new Circle();            

System.out.println(c.toString());

System.out.println(c);

 

<출력값>

inherit.Circle@1c4af82c

inherit.Circle@1c4af82c

-> c.toString( )을 호출하거나 참조변수c를 출력하는 것은 같음