[java] 10. 상속


상속



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

상속을 통해서 클래스를 작성하면 보다 적은 양의 코드로 새로운 클래스를 작성할 수 있고

코드를 공통적으로 관리할 수 있기 때문에 코드의 추가 및 변경이 매우 용이합니다.

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

상속을 구현하는 방법은 새로 작성하고자 하는 클래스의 이름 뒤에

상속받고자 하는 클래스의 이름을 키워드 extends와 함께 써주면 됩니다.


class Child extends Parent{
 //...
}



여기서 Child를 자식 클래스(하위 클래스)라고 하고, Parent를 부모 클래스(상위 클래스)라고 합니다.

자식 클래스는 부모 클래스의 모든 멤버를 상속받습니다~!

하지만 생성자와 초기화 블록은 상속받지 않습니다.

예를 들어, 다음과 같은 Parent 클래스가 있다고 합시다.


class Parent{
	String name;
	int age;
	
	Parent(){
		age=50;
		name="꾸리";
	}
	
	void print(){
		System.out.println("이름: "+name+"나이: "+age);
	}
}



그리고 Parent 클래스를 상속받은 Child 클래스가 있다고 합시다.


class Child extends Parent{
	void play(){
		System.out.println("놀자~");	
	}
}



Child 클래스는 Parent의 멤버를 모두 물려 받기 때문에(생성자 제외) 사실상 Child 클래스는 다음과 같습니다


class Child extends Parent{
	String name; //Parent 로부터 물려받음
	int age; //Parent 로부터 물려받음
	
	void print(){ //Parent 로부터 물려받음
		System.out.println("이름: "+name+"나이: "+age);
	}
	
	void play(){
		System.out.println("놀자~");	
	}
}



다음은 상속과 관련된 예제입니다.


image



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



지금까지 상속을 통해 클래스 간에 관계를 맺어 주고 클래스를 재사용하는 방법에 대해서 알아보았는데요~

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

바로 클래스 간의 포함관계를 맺어주는 것입니다.

포함관계란 한 클래스의 멤버변수로 다른 클래스 타입의 참조변수를 선언하는 것을 말합니다.

예를 들어보죠~

원을 표현하기 위한 Circle이라는 클래스가 있다고 하면,


class Circle{
	int x; //원점의 x좌표
	int y; //원점의 y좌표
	int r; //반지름
}



또 좌표상의 한점을 다루기 위한 Point 클래스가 다음과 같이 작성되어 있다고 하면,


class Point{
	int x;
	int y;
}



Circle 클래스를 Point 클래스를 이용하여 다음과 같이 작성할 수 있습니다.


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



이와같이 한 클래스를 작성하는데 다른 클래스를 멤버변수로 선언하여 포함시키는 것은 좋은 생각입니다.

하나의 거대한 클래스를 작성하는 것보다 단위별로 여러개의 클래스를 작성한 다음,

이 단위 클래스들을 포함관계로 재사용하면 보다 간결하고 손쉽게 클래스를 작성할 수 있고,

작성된 단위 클래스들은 다른 클래스를 작성하는데 재사용될 수 있을 것입니다.



클래스간의 관계 결정하기



클래스를 작성하는데 있어서 상속관계를 맺어 줄 것인지 포함관계를 맺어 줄 것인지 혼란스러울 수 있습니다.

그럴 때는 ~은 ~이다(is-a)와 ~은 ~을 가지고 있다(has-a)를 넣어서

문장을 만들어보면 클래스 간의 관계가 보다 명확합니다.


<상속관계> ~은 ~이다(is-a)

<포함관계> ~은 ~을 가지고 있다. (has-a)



다음은 상속관계와 포함관계에 관한 예제입니다.

일단, Shape 클래스와 Point 클래스를 선언합니다.


image



그 다음 Point 클래스를 멤버로 가지고 Shape 클래스를 상속받은 Circle 클래스와 Triangle클래스를 선언합니다.


image



위의 클래스에서 원과 삼각형은 도형이므로(is-a) 상속관계이고,

원과 삼각형은 점을 가지고 있으므로(has-a) 포함관계입니다.

또 주의 깊게 봐야할 것이 Circle 클래스와 Triangle 클래스는 Shape를 상속받으므로

draw()라는 메소드를 멤버로 물려받는데,

draw() 메소드를 자신의 클래스 안에서 다시 정의하고 있습니다.

이를 오버라이딩이라고 하는데, 다음 장에서 배우므로 생략하겠습니다.

다음은 main 함수를 포함한 클래스입니다.


image



실행결과입니다.


image



단일 상속



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

자바에서는 단일 상속만을 허용합니다.

그래서 하나 이상의 클래스로부터 상속을 받을 수 없습니다.

예를 들어 다음과 같은 코드는 에러를 발생시킵니다.


class Child extends Parent1,Parent2{ //에러. 조상은 하나만 허용된다.

}



다중상속을 허용하면 여러 클래스로부터 상속받을 수 있기 때문에 복합적인 기능을 가진 클래스를 쉽게 작성할 수 있다는 장점이 있지만,

클래스간의 관계가 매우 복잡해진다는 것과 서로 다른 클래스로부터 상속받은 멤버간의 이름이 같은 경우

구별할 수 있는 방법이 없다는 단점을 가지고 있습니다.

반면, 단일상속은 클래스 간의 관계가 보다 명확해지고 코드를 더욱 신뢰할 수 있게 만들어주는 장점이 있습니다.



Object 클래스 - 모든 클래스의 부모



Object 클래스는 모든 클래스 상속계층도의 최상위에 있는 부모클래스입니다.

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

이것을 가능하게 합니다.

만일 다음과 같이 다른 클래스로부터 상속을 받지 않는 Tv클래스를 정의하였다고 하면,


class Tv{
	...
}



위의 코드를 컴파일하면 컴파일러는 위의 코드를 다음과 같이 자동적으로 extends Object를 추가하여

Tv클래스가 Object 클래스로부터 상속받도록 합니다.


class Tv extends Object{
	...
}



만일 다른 클래스로부터 상속을 받는다고 하더라도 상속계층도를 따라 부모클래스,

부모클래스의 부모클래스를 찾아 올라가다 보면 결국

마지막 최상위 부모는 Object클래스일 것입니다.

따라서 모든 클래스는 Object 클래스를 상속받고, Object의 메서드를 사용할 수 있습니다.

Object 클래스에는 toString(), equals()가 있으며, Object 클래스의 자세한 내용은 후에 다시 배우겠습니다.