예시 코드
public class GokuTest {
public static void main(String[] args) {
Goku g = new Goku("손오공", 100);
SuperGoku sG = new SuperGoku("초사이어인 손오공", 160, 100);
SuperGoku2 sG2 = new SuperGoku2("초사이어인2 손오공", 230, 140, 100);
Goku[] gokus = { g, sG, sG2 };
for (int i = 0; i < gokus.length; i++) {
System.out.println(gokus[i].toString());
}
}
}
class Goku {
protected String name;
protected int hp;
public Goku(String name, int hp) {
this.name = name;
this.hp = hp;
}
public String toString() {
return String.format("[사이어인] %s, HP: %d", name, hp);
}
}
class SuperGoku extends Goku {
protected int mp;
public SuperGoku(String name, int hp, int mp) {
super(name, hp);
this.mp = mp;
}
public String toString() {
return String.format("[초사이어인] %s, HP: %d, MP: %d", name, hp, mp);
}
}
class SuperGoku2 extends SuperGoku {
protected int shield;
public SuperGoku2(String name, int hp, int mp, int shield) {
super(name, hp, mp);
this.shield = shield;
}
public String toString() {
return String.format("[초사이어인2] %s, HP: %d, MP: %d, SH: %d", name, hp, mp, shield);
}
}
1. 상속이란?
상속이란 기존 클래스를 확장하는 방법을 의미한다. 상속을 통해서 기존 클래스를 확장할 뿐만 아니라 중복된 코드를 제거할 수 있다.
상속은 extends 키워드를 통해서 수행할 수 있다. class SuperGoku extends Goku와 class SuperGoku2 extends SuperGoku가 예이다.
앞의 예시를 통해 설명하자면 SuperGoku 클래스는 자식 클래스로, 부모 클래스인 Goku의 필드와 메소드를 상속 받는다. 뒤의 예시도 같은 관계이다.
2. 클래스 확장과 중복 코드 제거
위의 예시코드에서 기존 클래스인 Goku를 토대로 SuperGoku, SuperGoku를 토대로 SuperGoku2로 확장되는 것을 볼 수 있다. 이럴 경우, 중복 코드를 제거할 수 있다.
예를 들어 부모 클래스인 Goku에 name, hp 필드가 있기 때문에 SuperGoku에 name과 hp를 작성하지 않아도 해당 필드를 갖게 된다.
또한 SuperGoku2도 부모 클래스인 SuperGoku에 mp 필드가 있기 때문에 별도로 작성할 필요가 없다.
여기서 눈여겨 볼 점은 연속 확장의 개념이다. 현재 상속의 관계가 Goku > SuperGoku > SuperGoku2인 것을 알 수 있는데, SuperGoku2는 Goku의 속성과 SuperGoku의 속성을 모두 갖게 된다.
3. 업캐스팅
클래스 확장의 측면에서 또 하나 중요한 개념이 업캐스팅이다. 자식 클래스는 부모 클래스이지만, 부모 클래스는 자식 클래스가 아니라는 개념이다.
Goku[] gokus = { g, sG, sG2 }; 에서 sG와 sG2는 Goku이기 때문에 Goku 배열에 담을 수 있다. 그러나 만약 SuperGoku2[] gokus = { g, sG, sG2 }; 라는 코드가 있다면 에러가 발생한다. g와 sG는 SuperGoku2가 아니기 때문이다.
이처럼 자식 클래스 타입은 업캐스팅 개념을 통해 부모 클래스 타입 처럼 다뤄질 수 있다.
4. 메소드 오버라이딩
메소드 오버라이딩은 상속 관계인 클래스들에서 동일한 이름을 가졌으나, 동작이 다른 메소드를 사용하기 위한 개념이다. 좀 더 정확히 말하자면, 부모 클래스의 메소드를 자식 클래스에서 재정의하는 개념이다.
위의 예시코드에서 상속 관계인 Goku, SuperGoku, SuperGoku2 세 클래스가 toString(){...}이라는 동일한 이름을 가진, 그러나 동작은 다른 메소드를 가진 것을 볼 수 있다. Goku의 toString() {...}은 SuperGoku에서 재정의 되었으며, SuperGoku의 toString() {...}은 SuperGoku2에서 재정의 되었다.
5. protected와 super
protected는 이전의 접근제한자 게시글에서 잠깐 언급한 적이 있다. protected는 접근제한자 중 하나로, 다른 패키지여도 상속된 클래스에서는 접근이 가능하다.
자식 클래스 타입의 객체를 생성하면서 동시에 초기화하려면 부모 클래스의 생성자가 먼저 호출되어야 한다. 이때 사용되는 키워드가 super이다.
SuperGoku sG = new SuperGoku("초사이어인 손오공", 160, 100);가 실행되면, 먼저 SuperGoku의 생성자가 실행된다.
public SuperGoku(String name, int hp, int mp) { super(name, hp); this.mp = mp; }에서 파라미터 값을 받고 동작이 실행되는데, super(name, hp);를 통해 부모 클래스의 생성자 public Goku(String name, int hp) { this.name = name; this.hp = hp; }가 호출되고 실행된다.
'Java > Java' 카테고리의 다른 글
메모리, 변수 (0) | 2021.07.06 |
---|---|
인터페이스 (0) | 2021.06.15 |
자바 API (0) | 2021.06.06 |
접근 제한자, 게터와 세터 (0) | 2021.05.31 |
레퍼런스 변수, static (0) | 2021.05.20 |