목표
자바의 상속에 대해 학습하세요.
학습할 것 (필수)
- 자바 상속의 특징
- super 키워드
- 메소드 오버라이딩
- 다이나믹 메소드 디스패치 (Dynamic Method Dispatch)
- 추상 클래스
- final 키워드
- Object 클래스
1. 자바 상속의 특징
1. 다중상속(Multiple inheritance)을 지원하지 않음
Class 다중상속을 지원하지 않음으로 extends 다음에는 하나의 class 이름만 표기.
2. 상속의 횟수에 제한이 없음
B 클래스는 A클래스를 상속받습니다
C 클래스는 A, B 클래스를 상속받습니다
D 클래스는 A, B, C 클래스를 상속받습니다
3. 계층 구조의 최상위에 있는 클래스는 Object 클래스임
모든 class는 object를 상속받도록 표현하지 않아도 컴파일러에 의해 object 클래스를 자동으로 상속받도록 컴파일됨
2. Super 키워드
super 키워드란 상속받은 자식 클래스 에서 부모 클래스의 메서드나 필드를 접근 할 수 있는 키워드입니다.
이러한 구조가 있을 때
C클래스에서 상속받은 부모의 필드에 접근하고 싶을 때
이런 식으로 super 키워드를 이용하여 접근이 가능하다
사실 우리는 생성자를 통해 이미 Super 키워드를 사용하고 있었다.
왜냐하면 C클래스는 B와 A클래스를 상속받고 있다.
이 말의 뜻은 C클래스를 사용하기 위해선 B클래스를 만들어야 하고
B클래스를 사용하기 위해선? A클래스를 사용하기 때문이다.
즉 그림으로 보면 다음과 같다.
A, B, C 생성자에 print 문을 써놓고 C클래스를 생성하면 다음과 같이 콘솔에 나온다.
여기서 super() 는 항상 생성자 코드에서 첫번째 라인에 와야 함!! 이유는 그림을 보고 생각해보세요
3. 메소드 오버라이딩
메소드 오버라이딩(method overriding) 이란 슈퍼클래스와 서브클래스의 메소드 사이에서 발생하는 관계이다.
즉 슈퍼클래스의 메소드를 동일한 이름으로 서브클래스에서 작성하는 행위를 말한다.
더 간단히 말해서 부모 클래스의 메서드의 행위가 마음에 안 들어서 자식 클래스에서 재 작성하는 것이다.
그림으로 보면 다음과 같다.
C는 A클래스를 상속받고 있다. 하지만 A클래스의 print() 메서드가 마음에 안 들어서 C클래스에서 재정의를 하고 있다.
여기서 C 클래스를 생성하고 print()를 호출하면 A클래스에 있는 print()가 호출되지 않고 C클래스에서 재정의한 print()가 호출된다.
즉 동적 바인딩을 통해 오버라이딩된 메서드가 항상 우선적으로 호출된다.
이제 메서드 오버라이딩에 제약 조건에 대해 더 자세히 알아보자.
1. 부모 클래스의 메소드와 완전히 동일한 메소드를 재정의한다.
-> 부모 클래스에 선언된 메소드와 같은 메소드 시그니처(메서드 이름 , 매개변수의, 순서), 같은 리턴 타입를 갖는 메소드를 작성
2. 부모 클래스의 메서드의 접근 지정자보다 접근의 범위가 좁아질 수 없음
-> 부모 클래스의 메소드가 public이면 오버라이딩 하는 메소드의 접근 지정자는 public만 사용 가능
-> protected면 protected , public만 가능
3. static, private, final로 선언된 메소드는 오버라이딩 불가능
4. 추상 클래스 (abstract class)
추상 클래스란
1. 하나 이상의 추상 메서드(abstract method)를 포함하고 있거나
2. 추상 메서드는 없지만 abstract로 선언한
클래스를 뜻한다.
여기서 추상 메서드(abstract method)란
-> 메서드는 선언되어 있지만 코드가 구현되어 있지 않는 껍데기만 있는 메서드다.
다시 돌아와서 추상 클래스의 특징을 알아보자.
1. 추상 클래스는 인스턴스를 생성할 수 없다.
-> 즉 추상 클래스에는 실행코드가 없는 추상 메서드 때문에 객체로 생성할 수 없다.
2. 추상 클래스를 상속받는 자식 클래스는 반드시 추상 메서드를 재정의(구현)을 해야 한다.
5. 다이나믹 메소드 디스패치(Dynamic Method Dispatch)
다이나믹 메소드 디스패치
->컴파일 시점에서는 어떤 메소드가 실행될지는 모르고 런타임 어떤 메서드가 실행되는지 결정되는 경우를 말한다.
이러한 경우가 언제 발생하는지 알아보자!
다음 같은 A추상 클래스를 B, C에서 상속받는 구조 일 때
A추상 클래스를 상속받았으므로 다형성을 이용 가능하다.
여기서 a.print()를 했을 때는 컴파일 시점에는 B클래스에서 정의한 print()가 실행될지 알 수 없다.
런타임 시점이 되어야 A클래스의 Receiver Parameter를 보고 어떤 method인지 알 수 있다.
더 자세한 내용은 (www.youtube.com/watch?v=s-tXAHub6vg&t=1536s&ab_channel=TobyLee)
그럼 이와 반대되는 경우는 뭐라고 부를까?
정적 디스패치 (Static Dispatch)라고 불린다
정적 디스패치란 다이나믹 메서드 디스패치와는 반대되는 개념으로
컴파일 시점에 어떤 메서드가 실행되는지 알 수 있는 경우다.
즉
이렇게 직접적으로 쓰게 되면 컴파일 시점에서 어떤 print() 메서드를 사용하는지 알 수 있다.
6. final 키워드
final 은 자바에서 상수(constant)를 뜻한다.
상수란 그 값이 변하지 않는 불변량으로, 변수의 반대말이다 (위키백과)
즉 상수란 어떠한 경우에도 변할 수 없는 값을 의미하고 자바에서는 final로 표기한다.
필드에 final을 쓴 경우
Class에 final를 쓴 경우 -> 상속 불가능
method에 fianl를 쓴 경우 -> 오버라이딩 불가능
7. Object 클래스
Object 클래스는 자바 클래스 구조의 최상위에 있는 클래스 임으로 모든 클래스의 부모클래스로 존재한다.
Object 클래스가 가지고 있는 주요 메소드는 다음과 같다.
메소드 | 설 명 |
boolean equals(Object obj) | 두 개의 객체가 같은지 비교하여 같으면 true를, 같지 않으면 false를 반환한다. |
String toString() | 현재 객체의 문자열을 반환한다. |
protected Object clone() | 객체를 복사한다. |
protected void finalize() | 가비지 컬렉션 직전에 객체의 리소스를 정리할 때 호출한다. |
Class getClass() | 객체의 클래스형을 반환한다. |
int hashCode() | 객체의 코드값을 반환한다. |
void notify() | wait된 스레드 실행을 재개할 때 호출한다. |
void notifyAll() | wait된 모든 스레드 실행을 재개할 때 호출한다. |
void wait() | 스레드를 일시적으로 중지할 때 호출한다. |
void wait(long timeout) | 주어진 시간만큼 스레드를 일시적으로 중지할 때 호출한다. |
void wait(long timeout, int nanos) | 주어진 시간만큼 스레드를 일시적으로 중지할 때 호출한다. |
boolean equals(Object obj) | 두 개의 객체가 같은지 비교하여 같으면 true를, 같지 않으면 false를 반환한다. |
객체 주소값을 가지고 == 비교를 함으로 두 객체의 속성이 모두 같아도 false가 나옴으로 주의!
이러한 경우 equals를 재정의(오버라이딩하여 속성이 같으면 같은 객체로 인식하게 만들면 됩니당)
더 자세히 알고 싶다면 저의 [Java]equals , hashCode 사용하기 를 봐주세요
'Java > live-study' 카테고리의 다른 글
[Java] 백기선 라이브스터디 9주차 : 예외 처리 (0) | 2021.01.14 |
---|---|
[JAVA] 백기선 라이브스터디 8주차 과제: 인터페이스 (0) | 2021.01.06 |
(JAVA)백기선 라이브 스터디 7주차 : 패키지 (0) | 2021.01.01 |
[Java] 클래스(class) - 백기선 라이브 스터디 5주차 (0) | 2020.12.13 |
[JAVA] 백기선 자바 스터디 4주차 과제: 제어문 (0) | 2020.12.05 |