자바 상속
Class Hero extends Animal implements SuperNatural {}
- 일반 클래스 상속은 extends 인터페이스 구현은 implements 키워드를 사용한다.
- 기존 클래스를 재사용해서 새로운 클래스를 만든다.
- 객체를 생성할 수 없는 추상 클래스를 상속해서 객체 생성 가능한 클래스를 만들 수 있다.
- 인터페이스를 구현해서 객체간의 프로토콜(규약)을 맞추는데 사용할 수 있다.
- extends를 이용한 상속은 단일상속만을 허용한다. (C++은 다중상속)
- 상속은
Is-a
관계가 성립한다.
Object
- 모든 클래스의 조상
- 모든 클래스는
toString()
, equals(Object obj)
등 약 10개 정도의 메소드를 상속받는다.
protected Object clone();
boolean equals(Object obj);
protected void finalize();
Class<?> getClass();
int hasCode();
void notify();
void notifyAll();
String toString();
void wait();
void wait(long timeout);
void wait(long timeout, int nanos);
public Object()
super 키워드
스터디를 통해 생성자 오류 해결한 이야기
public class Human {
private String name;
protected int age;
public Human(String name, int age) {
this.name = name;
this.age = age;
}
public void hello() {
System.out.printf("Hello I am %s and I am %d years old\n", this.name, this.age);
}
}
public class Hero extends Human{
private String weapon;
public Hero(String name, int age, String weapon) {
super(name, age);
this.weapon = weapon;
}
}
- 생성자는 부모 클래스의 기본 생성자를 암묵적으로 호출하는데 부모클래스에 기본 생성자가 없을 경우 오류가 발생함
- 오래전 이 오류를 만나서 부모 클래스에 필요없는 기본 생성자를 만들어 주었는데 스터디 중에 생각해 보니 이미 있는 생성자인
super(name, age)
를 호출하면 에러 해결 가능
- 생각해 보니 너무 당연한 것이었다. 스터디 만세!
그외 super 키워드 활용하기
this
와 활용법이 같다. 다만 super
는 부모의 멤버를 참조한다.
- 부모 메소드 호출 호출:
super.hello();
- 부모 멤버변수 사용:
super.age = 20;
메소드 오버라이딩
- 부모클래스로부터 상속받은 메소드의 내용을 변경하는 것
- 오버라이딩을 위해서는 메소드의 시그니쳐(이름, 매개변수, 리턴 타입)가 같아야 한다.
- 접근 제어자를 좁은 범위로 변경할 수 없다. 같거나 넓은 범위러 변경 가능하다.
- 조상 클래스보다 더 많은 예외를 선언할 수 없다.
- 오버로딩(이름이 같은 새로운 메소드를 정의)와 헷갈리지 말자.
다이나믹 메소드 디스패치 (Dynamic Method Dispatch)
- 자바는 오버라이딩된 메소드를 호출할 때 어떤 메소드를 호출할치 런타임에 결정하는데 이를 dynamic dispatch라고 한다.
- 다이나믹 디스패치를 통해 실행하는 메소드나 함수를 virtual function (method) 라고 부른다.
Human h = new Hero();
h.hello();
추상 클래스
- 하나 이상의 추상 메소드를 가지고 있는 클래스는 abstract class로 선언해야 한다.
- 인스턴스를 생성할 수 없으므로 상속해서 추상 메소드를 구현하거나 new 로 인스턴스를 생성과 동시에 추상 메소드를 구현해야 한다.
- 8 이후 인터페이스의 기능이 강화(Default method, static method 추가)되어서 주로 인터페이스를 사용하는 느낌.
- 인터페이스는 다중 구현이 가능하므로 인터페이스 쪽이 더 좋은 것 같다.
추상 메소드
- 선언부만 작성하고 구현부는 없는 메소드
- 상속해서 구현한다.
final 키워드
- 클래스 사용시: 상속 불가능
- 메소드 사용시: 오버라이딩 불가능
- 변수에 사용시: 상수가 된다.