1. 상속(Inheritance)
1) 상속의 정의와 구현
- 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것
- 적은 양의 코드로 새로운 클래스를 작성할 수 있고 코드를 공통적으로 관리할 수 있음
- 코드의 추가 및 변경이 매우 용이함
- 코드의 재사용성을 높이고 코드의 중복을 제거하여 프로그램의 생산성과 유지보수에 크게 기여함
- 상속은 키워드 'extends'를 사용하여 구현함
class Child extends Parent {
...
}
조상 클래스 = 부모(parent)클래스, 상위(super)클래스, 기반(base)클래스
자손 클래스 = 자식(child)클래스, 하위(sub)클래스, 파생된(derived) 클래스
- 상속계층도(class hierarchy) : 클래스 간의 상속관계를 그림으로 표현한 것
class Parent {
int age;
}
class Child extends Parent {
void play() {
System.out.println("play");
}
}
- 조상 클래스(Parent)가 변경되면 자손 클래스(Child)는 영향을 받음
- 자손 클래스(Child)가 변경되어도 조상 클래스(Parent)는 영향을 받지 않음
- 자손 클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많음
- 상속을 거듭할수록 상속받는 클래스의 멤버 개수는 점점 늘어남 (확장 = extend)
- 생성자와 초기화 블럭은 상속되지 않음 (멤버만 상속)
2) 포함(Compostie) 관계
- 상속 외에도 클래스를 재사용하는 방법으로 클래스 간에 '포함(Composite)'관계를 맺어주는 것이 있음
- 한 클래스의 멤버변수로 다른 클래스 타입의 참조변수를 선언하는 것
class Point {
int x;
int y;
}
class Circle {
//int x;
//int y;
Point c = new Point(); // x, y를 갖는 Point 클래스를 참조변수로 선언
int r;
}
3) 상속관계과 포함관계의 구분
상속관계 : ~은 ~이다 (is-a)
포함관계 : ~은 ~을 가지고 있다. (has-a)
ex)
A Circle is a Shape. (O)
A Circle has a Shape. (X)
-> Circle은 Shape를 상속받음
A Circle is a Point. (X)
A Circle has a Point. (O)
-> Circle은 Point를 포함함
4) 단일 상속(single inheritance)
- 둘 이상의 클래스로부터 상속받을 수 없음
- C++에서는 여러 조상 클래스로부터 상속받는 것이 가능한 다중상속(multiple inheritance)을 허용하지만 자바에서는 오직 단일 상속만을 허용
- 클래스 간의 관계가 보다 명확해지고 코드를 더욱 신뢰할 수 있게 만들어 줌
5) Object 클래스
- 모든 클래스 상속계층도의 최상위에 있는 조상클래스
- 자바의 모든 클래스들은 Object에 정의된 멤버들을 사용할 수 있음
ex) toString(), equals() 등
2. 오버라이딩(Overriding)
1) 오버라이딩이란?
- 조상 클래스로부터 상속받은 메서드의 내용을 변경하는 것
- 상속받은 메서드를 그대로 사용하기도 하지만, 용도에 맞게 변경해야 하는 경우 사용
class Point {
int x;
int y;
String getLocation() {
return "x: " + x + ", y: " + y;
}
}
class Point3D extends Point {
int x;
String getLocation() {
return "x: " + x + ", y: " + y + ", z: " + z;
}
}
2) 오버라이딩의 조건
자손 클래스에서 오버라이딩하는 메서드는 조상 클래스의 메서드와
1. 이름이 같아야 함
2. 매개변수가 같아야 함
3. 반환타입이 같아야 함
※ 접근 제어자(access modifier)와 예외(exception)는 제한된 조건 하에서만 다르게 변경할 수 있음
1. 접근 제어자는 조상 클래스의 메서드보다 좁은 범위로 변경할 수 없음
public protected (default) private
<- 접근범위 넓음 접근범위 좁음 ->
2. 조상 클래스의 메서드보다 많은 수의 예외를 선언할 수 없음
3. 인스턴스메서드를 static메서드로 또는 그 반대로 변경할 수 없음
3) 오버로딩 vs 오버라이딩
오버로딩(overloading) 기존에 없는 새로운 메서드를 정의하는 것(new)
오버라이딩(overriding) 상속받은 메서드의 내용을 변경하는 것(change, modify)
4) super
- 자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조하는데 사용되는 참조변수
- 상속받은 멤버와 자신의 멤버의 이름이 같을 때 super를 붙여서 구별함
- this와 마찬가지로 super 역시 static메서드에서는 사용할 수 없고 인스턴스메서드에서만 사용할 수 있음
class Parent {
int x = 10;
}
class Child extends Parent {
int x = 20;
System.out.println(x); // 20
System.out.println(this.x); // 20
System.out.println(super.x); // 10 (조상 클래스인 Parent의 x가 출력)
}
5) super()
- 조상 클래스의 생성자
- 자손 클래스의 인스턴스 생성 시 조상 클래스의 초기화 작업이 수행되어야 함
- 자손 클래스의 생성자에서 조상 클래스의 생성자가 호출되어야 함
- 조상 클래스의 생성자 호출은 최고 조상인 Object 클래스의 생성자에 도달할 때까지 거슬러 올라감
this() 같은 클래스의 다른 생성자를 호출
super() 조상 클래스의 생성자를 호출
Object 클래스를 제외한 모든 클래스의 생성자 첫 줄에 자신의 다른 생성자(this()) 또는 조상의 생성자(super())를 호출해야 함
-> 그렇지 않으면 컴파일러가 자동적으로 super()를 생성자의 첫 줄에 삽입함
class Point {
int x,y;
Point(int x, int y) {
// 컴파일러가 super();를 자동으로 삽입
// 조상 클래스인 Object의 생성자 Object()를 호출
this.x = x;
this.y = y;
}
String getLocation() {
return "x: " + x + ", y: " + y;
}
}
class Point3D extends Point {
int z;
Point3D(int x, int y, int z) {
// 조상 클래스인 Point의 생성자 Point(int x, int y)를 호출
// 조상 클래스의 멤버 변수인 x,y를 초기화 함
super(x, y);
this.z = z;
}
String getLocation() { // 오버라이딩
return "x: " + x + ", y: " + y + ", z: " + z;
}
}
참고 - Java의 정석 3rd Edition (저자 : 남궁성, 출판 : 도우출판)
'공부 > Java' 카테고리의 다른 글
[Java-07] 객체지향프로그래밍Ⅱ - 다형성, 추상클래스 (0) | 2021.03.02 |
---|---|
[Java-07] 객체지향프로그래밍Ⅱ - 패키지, import문, 제어자 (0) | 2021.02.24 |
[Java-06] 객체지향프로그래밍 - 오버로딩, 생성자 (0) | 2021.02.18 |
[Java-06] 객체지향프로그래밍 - 변수, 메서드 (0) | 2021.02.17 |
[Java-06] 객체지향프로그래밍 - 클래스, 객체 (0) | 2021.02.16 |