클래스를 정의할 때 이미 구현된 클래스를 상속받아서 속성이나 기능이 확장되는 클래스를 구현하는 것
class B extends A {
}
외부 클래스 | 하위 클래스 | 동일 패키지 | 내부 클래스 | |
---|---|---|---|---|
public | O | O | O | O |
protected | X | O | O | O |
default | X | X | O | O |
private | X | X | X | O |
❗️ 반드시 상위-하위 생성자를 호출해야하므로 없으면 명시적으로 호출한다.
상위 클래스의 인스턴스가 먼저 생성되고, 하위 클래스의 인스턴스가 생성된다.
접근이 안될 뿐, super.private프로퍼티
하면 생성이 된 것을 알 수 있다.
this가 자신의 인스턴스 주소를 갖는 것처럼, super는 하위 클래스가 상위 클래스에 대한 주소를 갖는다.
상위 클래스로의 묵시적 형 변환.
하위 클래스는 상위 클래스의 타입을 내포하고 있어서 상위 클래스로 선언하고 하위 클래스 인스턴스를 생성할 수 있다.
Human lee = new Woman();
상위 클래스에 정의된 메서드에 수정이나 추가 기능이 필요한 경우 같은 이름과 매개변수로 하위 클래스에서 재정의한다.
프로그램에서 어떤 객체의 변수나 메서드의 참조는 그 타입에 따라 이루어진다.
가상 메서드는 타입과 상관없이 실제 생성된 인스턴스의 메서드가 호출되는 원리이다.
Human lee = new Woman();
lee의 타입은 Human이지만, 실제 생성된 인스턴스인 Woman 클래스의 (부모와 기능이 같은)메서드가 호출된다.
하나의 코드가 여러 가지 자료형으로 구현되어 실행되는 것
class Animal {
public void move(){
System.out.println("동물이 움직인다.");
}
}
class Human extends Animal {
public void move() {
System.out.println("사람이 걷는다.");
}
}
class Tiger extends Animal {
public void move() {
System.out.println("호랑이가 움직인다.");
}
}
public class AnimalTest {
public static void main(String[] args) {
AnimalTest test = new AnimalTest();
test.moveAnimal(new Human());
test.moveAnimal(new Tiger());
// 사람이 걷는다.
// 호랑이가 움직인다.
}
public void moveAnimal(Animal a){
a.move();
}
}
공통적인 요소는 모으고 상속받아 필요한 특성과 메서드를 구현하는 방법
일반적인 개념과 구체적인 개념의 관계
한 클래스가 다른 클래스를 소유한 관계 (코드 재사용)
하위 클래스가 상위 클래스로 형 변환 되는 것은 묵시적으로 이루어지지만 다시 돌아가려면 명시적으로 다운 캐스팅을 해야한다.
이때 원래 인스턴스의 타입을 체크하는 예약어가 instanceof
이다.
public void moveAnimal(Animal a){
a.move();
if (a instanceof Human) {
Human human = (Human) a;
human.readBook();
}
else if (a instanceof Tiger) {
Tiger tiger = (Tiger) a;
tiger.hunting();
}
}