티스토리 뷰
1. 자바 상속의 특징
class Child extends Parent {
// ...
}
- 단일 상속만을 허용 -> 클래스 간의 관계가 명확해지고 코드의 신뢰성이 높아짐
- C++에서는 다중 상속 허용
- 다중 상속을 받으면 클래스 간의 관계가 복잡해짐, 다른 클래스로 부터 상속 받은 멤버의 이름이 같은 경우 구분이 불가능함
- 자손 클래스는 조상의 멤버를 모두 상속 받는다.
- 생성자와 초기화 블럭은 상속되지 않는다. 멤버만 상속된다
- 자손클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많다
class TVCR extends TV, VCR { // 에러, 하나만 허용됨
// ...
}
2. super 키워드
- 조상 클래스로부터 상속받은 멤버를 참조
- 상속 받은 멤버와 자신의 클래스에 정의된 멤버의 이름이 같을 때 super로 구별함
- static 메서드는 인스턴스와 관련이 없어서 super를 사용할 수 없음
- 메서드도 super를 써서 호출할 수 있음
- super() : 조상클래스의 생성자, 조상 클래스의 멤버들을 먼저 초기화 하기 위해서 사용
class SuperTest{
public static void main(String args[]) {
Child c = new Child();
c.method();
}
}
class Parent {
int x = 10;
}
class Child extends Parent {
void method() {
System.out.println("x=" + x);
System.out.println("this.x=" + this.x);
System.out.println("super.x=" + super.x);
}
}
// 결과
x=10
this.x=10
super.x=10
class SuperTest2{
public static void main(String args[]) {
Child c = new Child();
c.method();
}
}
class Parent {
int x = 10;
}
class Child extends Parent {
int x = 20;
void method() {
System.out.println("x=" + x);
System.out.println("this.x=" + this.x);
System.out.println("super.x=" + super.x);
}
}
// 결과
x=20
this.x=20
super.x=10
3. 메소드 오버라이딩
- 상속받은 메서드의 내용을 변경하는 것
- 자손 클래스 자신에 맞게 변경함
- 오버라이딩하는 메서드는 이름, 매개변수, 반환타입이 같아야 함
- 접근제어자는 조상클래스의 메서드보다 좁은 범위로 변경할 수 없음
- 조상 클래스의 메서드보다 많은 수의 예외를 선언할 수 없음
- 인스턴스 메서드를 static 메서드 혹은 그 반대로 변경할 수 없음
class Point {
int x;
int y;
String getLocation() {
return "x :" + x = ", y :" + y;
}
}
class Point3D extends Point {
int z;
String getLocation() { // 오버라이딩
return "x :" + x = ", y :" + y + ", z :" + z;
}
}
- 오버 로딩 : 기존에 없는 메서드를 정의하는 것 (new)
class Parent {
void parentMethod() {}
}
class Child extends Parent {
void parentMethod() {} // 오버라이딩
void parentMethod(int i) {} // 오버로딩
void childMethod() {}
void childMethod(int i) {} // 오버로딩
void childMethod() {} // 에러, 중복정의됨
}
4. 다이나믹 메소드 디스패치 (Dynamic Method Dispatch)
- 런타임 시점에서 할당된 객체의 타입을 보고 메소드를 찾아 실행하는 것
- 컴파일 시점에서 어떤 메소드를 호출 하는지 모르고, 추상 타입의 메소드를 호출하는 것만 알고 있음
public class Dispatch{
static abstract class Service{
abstract void run();
}
static class ServiceTest extends Service{
@Override
void run() {
System.out.println("ServiceTest run");
}
}
public static void main(String[] args) {
Service svc = new ServiceTest();
svc.run();
}
}
5. 추상 클래스
- abstract 키워드 사용
- abstract 클래스 : 클래스 내에 추상 메서드가 선언 되어 있음을 의미
- abstract 메서드 : 선언부만 작성하고 구현부는 작성되지 않은 추상 메서드임을 의미
abstract class AbstractTest { // 추상 클래스 (추상 메서드를 포함한 클래스)
abstract void move(); // 추상 메서드 (구현부가 없음)
}
- 아래와 같이 정의되면 다른 클래스가 WindowAdapter 클래스를 상속 받아서 일부의 원하는 메서드만 오버라이딩 할 수 있다
public abstract class WindowAdapter
implements WindowListener, WindowStateListener, WindowFocusListener {
public void windowOpened (WindowEvent e) {}
public void windowClosing (WindowEvent e) {}
public void windowClosed (WindowEvent e) {}
public void windowIconfied (WindowEvent e) {}
...
}
6. final 키워드
- 클래스 : 변경될 수 없는, 확장 불가능한 클래스가 됨, 다른 클래스의 조상이 될 수 없음
- 메서드 : 변경할 수 없는 메서드, 오버라이딩으로 재정의 될 수 없음
- 멤버변수, 지역변수 : 값을 변경할 수 없는 상수
class Card {
final int NUMBER;
final String KIND;
static int width = 100;
static int height = 250;
Card(String kind, int num) {
KIND = kind;
NUMBER = num;
}
Card() {
this("HEART", 1);
}
public String toString() {
return KIND + " " + NUMBER;
}
}
class FinalCardTest {
public static void main(String args[]){
Card c = new Card("HEART", 10);
// c.NUMBER = 5; // 에러, 5를 할당할 수 없음
System.out.println(c.KIND);
System.out.println(c.NUMBER);
System.out.println(c);
}
}
// 결과
HEART
10
HEART 10
7. Object 클래스
- 모든 클래스의 최상위에 있는 조상클래스
- 'extends Object' 생략되어 있음
- toString(), exquals(Object o) 따로 정의하지 않고도 사용할 수 있음
출처
자바의 정석, 남궁 성 지음
https://castleone.tistory.com/9
'개발 > Java Study' 카테고리의 다른 글
8주차 : 인터페이스 (0) | 2021.02.15 |
---|---|
7주차 : 패키지 (0) | 2021.02.13 |
5주차 : 클래스 (0) | 2021.02.12 |
4주차 : 제어문 (0) | 2021.02.09 |
3주차 : 연산자 (0) | 2021.02.03 |