상속?
상속이란, 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것이다.
상속의 장점은 적은 양의 코드로 새로운 클래스를 작성할 수 있고 코드를 공통적으로
관리할 수 있기 때무에 코드의 추가 및 변경이 매우 용이하다.
자바에서 상속을 구현하는 방법은 아주 간단하다.😊
작성하려는 클래스의 이름 뒤에 상속받으려는 클래스의 이름을 키워드 'extends'와 함께
써 주기만 하면 된다.
class Child extends Parant {
// ...
}
이 두 클래스는 서로 상속 관계에 있다고 하며, 상속해주는 클래스를 '조상 클래스'라 하고
상속 받는 클래스를 '자손 클래스'라 한다.
혹은 두 클래스를 아래와 같은 용어로 표현하기도 한다.
조상 클래스 : 부모(parent)클래스, 상위(super)클래스, 기반(base)클래스
자손 클래스 : 자식(child)클래스, 하위(sub)클래스, 파생된(derived)클래스
Parent클래스에 age라는 변수를 멤버변수로 추가하면, 자손 클래스는 조상의 멤버를 모두 상속받기 때문에
Child클래스는 자동적으로 age라는 멤버변수가 추가된것과 같은 효과를 얻는다.
반대로 Child클래스에 name이라는 변수를 추가해도 Parent클래스에는 아무런 영향도 주지 못한다.
생성자와 초기화 블럭은 상속되지 않는다. 멤버만 상속된다.
자손 클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많다.
그렇다면 Parent클래스로부터 상속받는 클래스가 Child와 Child2로 2개라면?
class Parent { }
class Child extends { }
class Child2 extends { }
클래스 Child와 Child2가 모두 Parent클래스를 상속받고 있을때 Child와 Child2클래스 사이에는
아무런 관계도 성립되지 않는다. 클래스 간의 관계는 부모 자식만 있을뿐 형제관계와 같은 것은 없다.😑
만일 Child 클래스와 Child2클래스에 공통적으로 추가되어야 하는 멤버(멤버변수나 메서드)가 있다면,
이 두 클래스에 각각 따로 추가 해주기보다 공통조상인 Parent클래스에 추가하는 것이 좋다.
이렇게 한다면 같은 내용의 코드를 한 곳에서 관리할수 있어 코드의 중복이 줄어든다!
코드의 중복이 줄어들면? 유지보수가 쉬워지고 일관성을 유지하기 쉽다.😁
프로그램이 어떤 때는 잘 동작하지만 어떤 때는 오작동을 하는 경우가 있다, 바로 중복된 코드 중에서
바르게 수정되지 않은 곳이 있기 때문이다.🤢
또! Parent에서 상속받은 Child에 자식클래스로 GrandChild를 추가한다면?
예상되듯이 GrandChild클래스는 자신의 부모님 Child의 모든 멤버를 물려받게 되고
부모의 Child의 부모 Parent의 모든 멤버 역시 물려받게 된다.
즉 손자가 할아버지 아버지의 모든 재산을(?)...💶
말은 쉽지만 사실 많은 경우를 생각해야 하므로 전체 프로그램을 구성하는 클래스들을
면밀히 설계 분석하여 클래스간의 상속관계를 적절히 맺어 주는 것이 객체지향 프로그래밍에서
가장 중요한 부분이다🌌
자손 클래스의 인스턴스를 생성하면 조상 클래스의 멤버와 자손 클래스의 멤버가
합쳐진 하나의 인스턴스로 생성된다.
클래스간의 관계 - 포함관계
상속을 통한 클래스 재사용이 아닌 또 다른 방법이 있다, 바로 클래스간에 '포함(Composite)'관계를
맺어 주는 것이다.
포함관계란 한 클래스의 멤버변수로 다른 클래스 타입의 참조변수를 선언하는 것이다.
class Point {
int x; // x좌표
int y; // y좌표
}
class Circle {
int x; // 원점의 x좌표
int y; // 원점의 y좌표
int r; // 반지름(radius)
}
-------------------------------------
↓포함을 시키면↓
-------------------------------------
class Point {
int x; // x좌표
int y; // y좌표
}
class Circle {
Point c = new Point();
int r; // 반지름(radius)
}
클래스간의 관계 결정하기
클래스를 작성 할 때 상속관계를 맺어 줄 것인지 포함관계를 맺어 줄 것인지 결정하는 것은
혼돈스러울 수 있다.
그럴 때는 '~은 ~이다(is-a)'와 '~은 ~을 가지고 있다(has-a)'를 넣어서 문장을 만들어보자
원(Circle)은 점(Point)이다. - Circle is a Point - 상속관계
원(Circle)은 점(Point)을 가지고 있다. - Circle has a Point - 포함관계
위와 같이 '~은 ~이다'가 어색하다면 상속관계, '~은 ~을 가지고있다'가 어색하지 않다면 포함관계를
맺어주는게 옳다.
또 상속에서 부모 자식을 정하는 방법은 SportsCar는 Car이다 할때 오른쪽에 오는 클래스를
부모로 지정하여 상속관계를 맺어 주어야 한다.
포함관계도 Circle은 Point를 가지고 있다 라고 할때 Point를 먼저 만들어 놓고
Circle에 Point를 포함 시켜야 한다.
상속관계 '~은 ~이다.(is-a)' : ~이다가 조상, ~은이 자손
포함관계 '~은 ~을 가지고있다.(has-a)' : ~을이 먼저 만들어져 ~을 가지고 있다 에 포함됨.
프로그램의 모든 클래스를 분석하여 가능한 많은 관계를 맺도록 노력해서 코드의 재사용을 높야아 겠다.🤢
상속관계와 포함관계를 어떻게 써야 할지 감이 왔다고 생각하다가도
설계가 서툴러서 그런지 막상 쓰려고 하면 너무 어렵고 머리가 어지러워진다🌌
디자인 패턴에 대해 공부를 할 예정인데 디자인 패턴을 공부하고서는
객체지향에 대해 익숙해져 있을까?🤣
댓글