오리
라는 이름을 가진 클래스를 만들어서 오리의 기본적인 행동을 할 메서드를 구현한 다음 청둥오리와 물오리 클래스에서 각각 상속받아 사용하게 하면 아까전에 생겼던 중복 코드를 줄일 수 있을 것이다. extends
키워드를 사용하면 된다.class Child extends Parent {
// ...
}
부모 클래스
, 상속받는 클래스를 자손 클래스
라 한다.조상 클래스 : 부모(parent) 클래스, 상위(super) 클래스, 기반(base) 클래스
자손 클래스 : 자식(child) 클래스, 하위(sub) 클래스, 파생된(derived) 클래스
[이미지 출처] http://www.tcpschool.com/java/java_inheritance_concept
extends
인 이유이기도 하다. 주의사항:
생성자와 초기화 블럭은 상속되지 않는다. 멤버만 상속된다.
자손 클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많다.
오버라이딩
이라 한다. 다중상속
이 가능하지만 자바에서는 오직 단일상속
만 허용한다. powerOn()
이라는 메서드가 있다면 자손 클래스인 클래스 C에서는 어느 부모 클래스의 powerOn()
을 상속받는 것인지 모호해지기 때문이다. 이름을 바꿔가면서 구별하는 것도 한계가 있고... 여러가지로 불편한 점이 많기 때문에 자바에서는 단일상속만 허용한다.Object 클래스
는 모든 클래스의 최상위에 있는 조상 클래스이다. 자바에서 사용되는 클래스들의 부모를 찾아찾아 거슬러 올라가면 마지막엔 Object 클래스
가 있다. 그래서 toString()
이나 equals()
와 같은 메서드들을 따로 정의하지 않고 그냥 사용할 수 있다. 왜냐면 모두 Object 클래스
에 정의되어 있기 때문이다. 여러 가지 형태를 가질 수 있는 능력
을 의미한다. 조상클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있도록 하였다
는 것이다. class Parent {
}
class Child extends Parent {
}
Parent P = new Child(); // 컴파일 잘 됨
Parent
에 정의된 멤버만 사용할 수 있는데 그 수가 자손 클래스인 Child
에 정의된 멤버의 수보다 적기 때문에 없는 것을 사용할 위험은 없기 때문이다. Child c = new Parent(); // 컴파일 에러
하지만 반대 경우는 안 된다.
왜냐면 상속받은 자식 클래스인 Child
의 멤버 개수가 부모 클래스인 Parent
보다 많기 때문에 Parent
에 없는 멤버를 사용하려 할 수 있기 때문이다. 실제 내용물이 없는 것을 참조하면 당연히 NullPointerException
이 발생할 것이다.
이러한 특징은 메서드의 매개변수에도 적용해서 더욱 유연한 코드를 작성할 수 있다.
class Product {
int price;
int bonusPoint;
}
class Tv extends Product {}
class Computer extends Product {}
class Audio extends Product {}
class Buyer {
int money = 1000;
int bonusPoint = 0;
}
Buyer
클래스에 물건을 구입하는 메서드를 추가하는 경우를 생각해 보자.void buy(Tv t) {
money -= t.price;
}
void buy(Computer c) {
money -= c.price;
}
void buy(Audio a) {
money -= a.price;
}
buy()
메서드를 만들어줘야 한다. 여간 귀찮고 유지보수도 힘든 것이 아니다. 여기에 매개변수의 다형성을 적용하면 중복 코드를 줄이고 유지보수도 훨씬 쉬운 코드로 작성할 수 있다. void buy(Product p) {
money -= p.price;
}
이렇게 쓰면 Product
를 상속받는 모든 클래스들의 참조변수를 처리할 수 있다. 상품의 수가 늘어나도 문제가 없다.
이것을 좀 더 확장해 보면 여러 종류의 객체를 배열에도 담을 수 있게 된다.
Product p[] = new Product[3];
Product[0] = new Tv();
Product[1] = new Computer();
Product[2] = new Audio();