자바의 상속에 대해 학습하세요.
- 자바 상속의 특징
- super 키워드
- 메소드 오버라이딩
- 다이나믹 메소드 디스패치 (Dynamic Method Dispatch)
- 추상 클래스
- final 키워드
- Object 클래스
A는 B다
테스트를 통해 어떤 것이 다른 것을 확장하는지 확인하여 상속관계 확인A에는 B가 있다
라고 표현해야 된다면 A
객체에 B
인스턴스 변수가 들어간다고 할 수 있음Object
클래스의 자식 클래스A
의 func
메서드를 B
, C
에서 func
메서드를 오버라이딩을 했을 때 D
는 B
, C
중 어떤 func
메서드를 상속받아야 할지 모르기 때문에 컴파일 에러가 발생super(param...)
을 호출해서 부모 클래스의 생성자로 부모의 필드를 초기화 해주어야 함, 부모 클래스에 디폴트 생성자만 있을 경우는 명시적으로 super()
를 해주지 않더라도 컴파일러가 자동으로 호출해줌this
와 super
는 처음 탐색 위치말고 다른게 없는 것 같음public Constructor() {
super(); // 호출해주지 않더라도 컴파일러가 자동으로 해줌
...
}
public Constructor(params) {
super(params); // 디폴트 생성자 이외의 생성자는 꼭 호출해주어야 됨
...
}
class Parent {
public void func1() {}
protected Parent func2() {}
}
class Child extends Parent {
@Override
public void func1() {}
/* 반환 타입이 바뀌었지만 더 좁은 타입으로 바뀌었으므로 OK
* 접근 제어자도 바뀌었지만 더 넓은 범위로 바뀌었으므로 OK
*/
@Override
public Child func2() {}
}
class Parent {
public void func() {
System.out.println("parent class");
}
}
class Child extends Parent {
@Override
public void func() {
System.out.println("child class");
}
}
public class Main {
public static void main(String[] args) {
Child child = new Child();
Parent parent = new Child();
child.func(); // 정적 디스패치
parent.func(); // 동적 디스패치
}
}
/*
output :
child class
child class
모두 같은 메소드가 실행
*/
abstract class 클래스명 {
...
(접근제어자) abstract void abstractMethod();
}
final class 클래스명 { // 부모가 될 수 없는 클래스
final 타입 인스턴스변수 = 값; // 값을 변경할 수 없는 멤버변수(상수)
final 타입 메서드명() { // 오버라이딩할 수 없는 메서드(변경불가)
final 타입 지역변수 = 값; // 값을 변경할 수 없는 지역변수(상수)
}
extends Object
를 추가해줌class Object {
String toString() {...}; // 문자열로 반환
boolean equals(Object obj) {...}; // 같은 지 여부 반환
protected Object clone() {...}; // 인스턴스를 복제하여 새로운 인스턴스를 생성해 반환
protected void finalize() {...}; // 가비지컬렉터(GC)가 객체 리소스를 삭제
Class<T> getClass() {...}; // 객체의 클래스 타입 반환
int hashCode() {...}; // 객체의 해시 코드값 반환
void notify() {...}; // 객체의 대기중인 하나의 스레드를 다시 실행할 때 호출
void notifyAll() {...}; // 객체의 대기중인 모든 스레드를 다시 실행할 때 호출
void wait() {...}; // 객체의 다른 스레드가 notify() 또는 notifyAll() 메소드 실행할 때까지 현재 스레드를 일시적으로 대기시킴
void wait(long timeout) {...}; // 객체의 다른 스레드가 notify() 또는 notifyAll() 메소드 실행하거나 timeout시간이 지날 때까지 현재 스레드를 일시적으로 대기시킴
void wait(long timeout, int nanos) {...}; // 객체의 다른 스레드가 notify() 또는 notifyAll() 메소드 실행하거나 timeout시간이 지나거나 다른 스레드가 현재 스레드를 인터럽트할 때까지 현재 스레드를 일시적으로 대기시킴
}
출처:
객체지향의 사실과 오해
https://leemoono.tistory.com/20
https://yadon079.github.io/2020/java%20study%20halle/week-06