본문 바로가기
Language/Java

[Java] 객체지향 프로그래밍 -상속과 포함관계,Object클래스

by 계범 2022. 3. 4.

상속(inheritance)

상속의 정의와 장점

상속이란, 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것이다.

 

상속을 통해서 클래스를 작성하면 보다 적은 양의 코드로 새로운 클래스를 작성할 수 있고 코드를 공통적으로 관리할 수 있기 때문에 코드의 추가 및 변경이 매우 용이하다.

 

이러한 특징은

코드의 재사용성을 높이고, 코드의 중복을 제거하여 프로그램의 생산성과 유지보수에 크게 기여한다.

 

자바에서 상속을 구현하는 방법

새로 작성하고자 하는 클래스의 이름뒤에 상속받고자 하는 클래스의 이름을 키워드'extends'와 함께 써주면 된다.

 

class Child extends Parent{
	// ...
}

// Child 상속받는 자손 클래스
// Parent 상속 해주는 조상 클래스
조상 클래스 = 부모(parent)클래스 = 상위(super)클래스 = 기반(base)클래스
자손 클래스 = 자식(child)클래스 = 하위(sub)클래스 = 파생된(derived)클래스

 

자손 클래스는 조상 클래스의 모든 멤버를 상속받기 때문에,

Child클래스는 Parent클래스의 멤버들을 포함한다고 할 수 있다.

 

만약, Parent 클래스에 멤버가 추가된다면 상속받은 Child도 추가된 것과 같은 효과를 얻는다.

반대로 Child 클래스에 멤버가 추가되면 Parent 클래스엔 변화가 없다.

 

자손 클래스는 조상 클래스보다 항상 같거나 많은 멤버를 가지는데, 상속이 거듭될수록 클래스의 멤버의 개수는 계속 늘어나는데, 이러한 것을 확장한단 의미로 'extends(확장)'를 붙였다고 해석하면 외우기 쉽다.

 

 - 생성자와 초기화 블럭은 상속 x. 멤버만 상속

 

// 사용예제

class Tv {
	boolean power; 	// 전원상태(on/off)
	int channel;	// 채널

	void power()        {   power = !power; }
	void channelUp()    { 	 ++channel;     }
	void channelDown()  {	 --channel;	    }
}

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

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");	// 캡션을 화면에 보여 준다.
	}
}

 

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

상속이외에도 클래스를 재사용하는 또 다른 방법이 있는데,

클래스간에 '포함(Composite)'관계를 맺어 주는 것이다.

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

 

// 두개의 클래스
class Circle{
	int x; // x좌표
    int y; // y좌표
    int r; // 반지름
}

class Point{
	int x;
    int y;
}

// 클래스간 포함관계로 변경
class Point{
	int x;
    int y;
}

class Circle{
	point c = new Point(); // x,y 좌표
    int r;
}
class Car{
	Engine e = new Engine(); // 엔진
    Door[] d = new Door[4]; // 문
}

 

클래스간의 관계 결정하기(상속관계,포함관계)

위의 예제로 예시

// 포함관계
class Circle{
	Point c = new Point();
    int r;
}

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

'~은 ~이다(is-a)' 와 '~은 ~을 가지고 있다(has-a)'를 넣어서 문장을 만들어보면 클래스 간의 관계가 보다 명확해 진다.

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

원은 원점(Point)과 반지름으로 구성되므로 두 문장 중 두 번째 문장이 더 옳다는 것을 알 수 있다.

 

그래서 Circle과 Point는 포함관계를 맺어주는게 더 옳다.

 

단일 상속(single inheritance)

다른 객체지향언어인 C++에서는 여러 조상 클래스로부터 상속받는 것이 가능한 '다중상속'을 허용하지만,

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

 

CLASS TVCR extends TV, VCR { //에러. 조상은 하나만 허용
	// ...
}

 

다중 상속의 장점

  • 여러 클래스로부터 상속받을 수 있기 때문에 복합적인 기능을 가진 클래스 쉽게 작성

다중 상속의 단점

  • 클래스 간의 관계가 매우 복잡
  • 서로 다른 클래스로부터 상속받은 멤버가 이름이 같은 경우 구별 불가능

 

자바는 이러한 문제점 때문에 다중상속의 장점을 포기하고 단일상속만 허용.

 

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

Object클래스는 모든 클래스 상속계층도의 최상위에 있는 조상클래스이다.

 

다른 클래스로부터 상속받지 않는 모든 클래스들은 자동적으로 Object 클래스로부터 상속받게 한다.

 

컴파일 과정에서 컴파일러가 상속이 없는 클래스는 'extends Object'를 추가해준다.

toString()이나 equals(Object o)와 같은 메서드를 따로 정의하지 않고도 사용할 수 있었던 이유는 Object클래스에 정의된 것이기 때문이다.

 

참조

'Java의 정석' 책

댓글