모델링 할 때 '특징 정리하기' 단계 빼먹지 말기
만들기 전, 만들 대상의 정보를 정리하는 작업은 중요하다 특히 우리같은 초보자에게
계층구조에서 하위 계층은 상위 계층의 특징을 당연히 가지고 있음
즉 하위 계층이 상위 계층에서 언급된 특징까지 설명할 필요 없음
상속 관계는 클래스 사이의 계층구조를 형성한다
class ElectricCar extends Car{
int batteryLevel;
}
// 'class A extends B' 형태
// 전기차 클래스는 차 클래스를 확장한다. -> 전기차 클래스는 차 클래스를 상속받아온다.
상속의 조건
① +a가 존재 (추가정보-멤버변수, 메서드, 생성자 등의-가 존재)
② is-a 관계 성립 (하위 개념이면 상위 개념이 충족됨-B가 A를 상속해온다면 ‘B is a A’)
ex) 가수 클래스를 상속해오는 아이유, 에일리 클래스
-> 아이유 is a Singer, 에일리 is a Singer
둘 다 만족될 때만 상속을 사용할 수 있음
(그런 경우마다 반드시 사용해야 하는 것은 아님!)
프로그램에서 상속을 '해준다'는 말은 없다. 상속은 '받는(받아오는)‘ 것이다.
: 'A <- B (B가 A를 상속받음)' 관계에서 B는 A를 인지하지만, A도 B를 인지하는 것은 아니다.
상속은 A가 하는 게 아니라 B가 받아오는 것이다.
모든 객체지향 언어에는 상속 개념이 존재함
언어마다 상속의 정의가 조금씩 다름
상속 남발의 주의점
‘태권v 클래스 <- 사람 클래스’의 상속관계를 만든다면, 사람 객체에 '주먹 발사'가 들어갈 수 있다!
(is-a 관계가 성립하지 않기 때문 - ‘사람 is NOT a 태권v’)
단순히 코드 재활용을 위해 마구잡이로 상속을 사용하면, 사람이 주먹을 발사하게 된다😅
상속 또한 중복을 줄이는 방법 중 하나
지금까지 배운 중복 줄이기 방법은 '클래스 안'에 한정되었으나,
이젠 상속을 통해 클래스 사이에 존재하는 중복도 제거할 수 있다.
(물론 상속 말고 다른 방법도 있다. - 아직 안배움)
상속을 사용하는 이유
현실에서 계층구조 사용하는 이유와 같다?
상속의 방향
상속은 '단방향 행위'다
무슨 말이냐?
A를 상속받아 사용하는 B가 있어도, A는 B를 인지하지 않기 때문에, B를 고려하지 않고 A를 변경할 수 있다
=> A를 상속받는 B에게 치명적 오류가 생길 수 있다
심지어 A를 상속받는 B를 상속받는 C를 상속받는 D가 있다면? 고려하기 어렵고, 자칫 의도하지 않은 심각한 문제가 생길 가능성이 높아지는 것.
상속, 사용할 때 주의해야 하는 이유
상속은 기본적으로 의존성이 굉장히 높은 기술 (A가 있어야 B가 존재할 수 있다는 높은 의존성)
프로그래밍에서 의존성은 지양해야 하는 특성이며 의존성이 높으면 위험성이 높다.
다중상속을 지원하지 않는다
부모 클래스는 하나만 존재한다. (상속받아오는 클래스는 1개)
다중상속은 상위 클래스간 개념의 충돌로 문제가 생길 수 있음 -> 최근으로 올수록 더 많은 언어에서 금지함
상속 횟수에는 제한이 없다.
상속 계층 구조의 최상위에는 java.lang.Object 클래스가 있다.
(모든 것은 결국 객체다. 모든 객체는 결국 Object 클래스의 자식이다.)
(그러므로 모든 객체에는 toString이 존재함 - java.lang.Object가 소유하는 toString을 상속받아오는 것.)
상속관계는 생각하기 나름
①컴퓨터, ②랩탑, ③데스크탑, ④태블릿의 관계도
- 재귀호출
메소드 안에 자기 자신을 부르는 부분이 있음 (일반적으로 반복문 형태가 됨)public void attack(Zealot target) { ... target.attack(this); ... }
만들기도 이해하기도 어렵지만, 일반 반복문보다 속도가 빠르다
class Parent {
private int age;
public Parent(int age) {
this.age = age;
System.out.println("Parent");
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class Child extends Parent {
public Child(int age) {
super(age); // 작성하지 않아도 알아서 추가되는 super() : 부모클래스 생성자
System.out.println("Child");
}
public void printAge() {
System.out.println(getAge());
}
}
class Ex1 {
public static void main(String[] args) {
Child c = new Child(30);
c.setAge(15);
c.printAge();
}
}
super() : 부모 클래스의 생성자를 호출
this()와 마찬가지로 생성자의 첫 명령으로 들어가야 한다.
this()보다 super()를 많이 사용하는 이유