[Java] Inheritance & Composite_상속과 포함관계
상속(Inheritance)
Reuse
코드를 재사용하여 새로운 클래스를 작성한다.
코드를 공통적으로 관리할 수 있기 때문에 코드의 추가 및 변경에서 효율적이다.
Extend
상속이라는 개념은 어찌보면 '확장'에 가깝다.
상속을 거듭할수록 상속 받는 클래스 멤버 개수는 점점 늘어나게 된다.
Parent ⊂ Child

조상 클래스가 자손 클래스 내부에 포함된 형태로 자손 클래스는 조상클래스의 내용을 공통적으로 갖고 추가적인 변수나 메서드를 가진다.
Single inheritance (단일 상속 )
다른 객체지향 언어와 달리 java는 단일상속만을 허용한다.
클래스간의 관계가 매우 복잡해질 수 있기 때문이다.
예를들어 서로 다른 클래스의 멤버 변수 이름이 같은 경우에는 구별할 수 있는 방법이 없다.
Object _ 모든 클래스의 조상
만약 클래스의 조상을 따로 코드상으로 표현하지 않았다고 하더라도, 조상은 존재한다.
바로 Object클래스이다. 즉, Object 클래스는 모든 클래스의 직간접적인 조상이 되는거다.
이런식으로 컴파일러가 Object 클래스를 최상위 계층에 두는 이유는 해당 클래스에 인스턴스가 가져야할 기본적인 메서드가 정의되어있기 떄문이다.

Composite_포함관계
상속처럼 클래스를 재활용 하는 방식이다.
그런데 상속과 포함이 쓰이는 지점은 다르다.
상속 관계 : B는 A이다. 포함 관계 : B는 A를 가진다. BMW는 Car이다. (0) BMW는 Car을 가진다. (X) -> 상속관계 Car은 wheel 이다.(x) Car은 wheel을 가진다. (0) -> 포함관계 |
<포함관계>
class car{}
class Car
{
Wheel W = new Wheel();
}
<상속관계>
class Wheel{}
class BMW extends car{
String brand ;
}
<예제_ 출처 : 자바의 정석(남궁성)>
public class DrawShape {
public static void main(String[] args) {
Point[] p = { // 3개의 인스턴스를 생성한다.
new Point(100,100),
new Point(200,250),
new Point(150,100)
};
Triangle t = new Triangle(p);
Circle c = new Circle(new Point(100,100),40);
t.draw();
c.draw();
}
}
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+")";
}
}
class Shape {
String color = "black";
void draw(){
System.out.println("color =" + color);
}
}
class Circle extends Shape {
Point center ;
int r;
Circle(){
this(new Point(0,0),100);
}
Circle(Point center, int r){
this.center = center ;
this.r = r ;
}
// Overwriting
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);
}
}
오버라이딩
<조건> - 클래스 이름이 같아야한다. - 매개변수가 같아야한다. - 반환타입이 같아야한다. |
상속받은 메서드의 내용을 변경하는 것.
<조상 클래스에서의 draw 메서드>
class Shape {
String color = "black";
void draw(){
System.out.println("color =" + color);
}
}
<자식 클래스에서의 draw 메서드>
class Circle extends Shape {
Point center ;
int r;
Circle(){
this(new Point(0,0),100);
}
Circle(Point center, int r){
this.center = center ;
this.r = r ;
}
// Overwriting
void draw()
{
System.out.printf("[center=(%d, %d),r = %d, color = %s]%n",center.x, center.y,r,color);
}
}
shape 클래스를 상속받은 Cricle 클래스는 매개변수의 변동 없이 매서드의 내용을 바꾸고 있음을 보여주고 있다.
이렇게 메서드의 선언부는 조상의 것과 완전히 일치시킨체, 메서드의 내용만을 새로 작성하는 것을 오버라이딩이라고 한다.
클래스의 다중 상속을 지원하지 않는 이유
다중 상속을 지원하게 되면 하나의 클래스가 여러 상위 클래스를 상속 받을 수 있다.
이러한 특징 때문에 발생되는 문제가 바로 '다이아몬드 문제' 이다.

FatherA와 FatherB 가 GrandFather를 상속받고, FatherA, FatherB 클래스 모두 GrandFather 클래스의 A() 메서드를 오버라이딩 했다고 할 때,
FatherA와 FatherB 를 다중 상속 받은 B 클래스는 둘 중 어떤 A() 메서를 이용해야 할까?
https://siyoon210.tistory.com/125
자바는 왜 다중상속을 지원하지 않을까? (다이아몬드 문제)
다이아몬드 문제 다중 상속을 지원하게 되면 하나의 클래스가 여러 상위 클래스를 상속 받을 수 있습니다. 이런 특징 때문에 발생하게 되는 문제가 있는데, 바로 '다이아몬드 문제' 입니다. 위의
siyoon210.tistory.com