[자바 스터디] 6주차 과제: 상속
목표
자바의 상속에 대해 학습하세요.
학습할 것
- 자바 상속의 특징
- super 키워드
- 메소드 오버라이딩
- 다이나믹 메소드 디스패치 (Dynamic Method Dispatch)
- 추상 클래스
- final 키워드
- Object 클래스
자바 상속의 특징
상속
- 상위클래스에서 정의한 필드와 메서드를 하위클래스도 동일하게 사용할 수 있게 물려받는 것
- 상속 관계(일반화/특수화)를 결정하는 것은 객체의 상태를 표현하는 데이터가 아니라 행동
생성자와 초기화 블럭은 상속되지 않음
- 자식 클래스가 부모 클래스를 물려받고 그 이외 더 많은 행동을 하니까 기능의 관점에서 보면 벤다이어그램을 위의 그림과 같이 표현할 수 있음
- 하지만 상속 관계의 일반화와 특수화 관점에서 보면 부모 클래스가 더 일반적이고 자식 클래스가 특수한 경우이기 때문에 일반적인 부모 클래스에 좀 더 특수한 경우인 자식 클래스가 포함되어 있게 표현하는게 더 상속 관계를 이해하는데 도움이 될 것 같음
"A는 B다" 와 "A에는 B가 있다" 관계
A는 B다
테스트를 통해 어떤 것이 다른 것을 확장하는지 확인하여 상속관계 확인- 만약
A에는 B가 있다
라고 표현해야 된다면A
객체에B
인스턴스 변수가 들어간다고 할 수 있음
자바 상속의 특징
- 다단계 상속이 가능하고, 다중 상속을 지원하지 않음
- 모든 클래스는
Object
클래스의 자식 클래스
다중 상속을 지원하지 않는 이유 : 다이아몬드 문제
A
의func
메서드를B
,C
에서func
메서드를 오버라이딩을 했을 때D
는B
,C
중 어떤func
메서드를 상속받아야 할지 모르기 때문에 컴파일 에러가 발생
super 키워드
- 자식 클래스에서 부모 클래스를 가리키는 키워드
- super 키워드를 통해 자식 클래스는 부모 클래스의 필드나 메서드를 호출
- 부모 클래스에 디폴트 생성자 이외 생성자가 있다면 자식 클래스에서
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() {}
}
다이나믹 메소드 디스패치 (Dynamic Method Dispatch)
- 어떤 메소드를 호출할 지 런타임에 결정하는 것
- 런타임 시점에 할당된 객체의 타비을 보고 메소드를 실행함
- 같은 타입의 객체로 여러 타입의 객체를 초기화할 수 있어 한 타입으로 여러 타입의 기능을 실행 가능 (다형성)
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
모두 같은 메소드가 실행
*/
추상 클래스
- 추상 클래스는 인스턴스로 생성 X, 추상 클래스를 구현하려면 상속을 받은 클래스를 통해 인스턴스로 생성해야 됨
- 추상 메서드를 포함하고 있다는 것을 제외하고 일반 클래스와 동일함, 생성자, 멤버변수 그리고 메서드 모두 가질 수 있음
- 추상 메서드를 포함하고 있지 않더라도 추상클래스를 직접 인스턴스로 생성하지 못하게 하는 용도로 사용할 수 있을 것 같음
abstract class 클래스명 {
...
(접근제어자) abstract void abstractMethod();
}
final 키워드
- 다시 무언가를 정의내리는 것을 막는 키워드
- 변수에 final을 사용하면 불변하는 것이 맞지만 메모리를 새롭게 할당하는 것을 막는다는 것을 의미
- final이 붙은 변수는 일반적으로 선언과 동시에 초기화를 동시에 하지만 생성자에서 초기화 가능, 그러므로 생성자 이전 초기화하는 과정들에서도 모두 final 변수를 초기화할 수 있음
final class 클래스명 { // 부모가 될 수 없는 클래스
final 타입 인스턴스변수 = 값; // 값을 변경할 수 없는 멤버변수(상수)
final 타입 메서드명() { // 오버라이딩할 수 없는 메서드(변경불가)
final 타입 지역변수 = 값; // 값을 변경할 수 없는 지역변수(상수)
}
- 프리미티브 타입의 값이 곧 데이터이기 때문에 final로 정의내리면 값을 바꿀 수 없음
- 레퍼런스 타입의 값은 실제 사용하는 데이터가 아닌 사용하는 데이터(인스턴스)의 주소값이기 때문에 final로 정의내리더라도 주소값을 바꾸지 않는 이상 데이터를 바꿀 수 있음
Object 클래스
- 모든 클래스의 최고 조상 클래스이므로 모든 클래스를 Object 타입으로 초기화 할 수 있음
- 컴파일러에서 자동으로
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
Author And Source
이 문제에 관하여([자바 스터디] 6주차 과제: 상속), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@yunu/자바-스터디-6주차-과제-상속저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)