JAVA(자바) - 상속 / 상속에서의 생산자와 super()
상속 예시 코드
class Person {
int age;
public String name;
}
class Student extends Person { //Person의 필드를 상속
int class; // 추가로 특성 확장(Extends) 해서 사용
Student(){
this.name = "홍길동";
this.age = 20;
}
}
상속이란?
객체 지향 언어에서 상속은 부모 클래스에 만들어진 필드와 메소드를 자식 클래스가 물려받는 것이다.
내가 자식 클래스에 같은 코드를 만들지 않아도 만든 것과 같은 효과를 볼 수 있고 거기서 더 확장(extends)할 수 있다.
단, 상속은 클래스 간의 상속이지 객체 사이의 상속이 아니라는 점을 주의해야한다. 그렇기에 어떤 객체는 물려받고 어떤 객체는 물려받지 않는 경우는 존재하지 않는다.
상속을 하는 이유
- 코드 중복을 제거하여 클래스를 간결하게 구현할 수 있다.
- 클래스들이 계층적으로 분류되어 관리에 용이하다.
- 코드의 재사용과 확장이 용이하여 소프트웨어 생산성이 향상된다.
자바 상속의 특징
- 다중상속을 지원하지 않는다.
하나의 클래스는 부모를 하나만 가질 수 있다.
참고로 C++은 클래스 다중 상속을 지원한다. - 상속의 횟수에 제한을 두지 않는다.
쉽게 말하면 부모는 하나만 가능하지만 조부모, 증조부모 등 족보가 세로로 길어지는 것은 가능하다. - 자바 계층 구조의 최상위에는 java.lang.Object가 있다.
모든 클래스는 Object 클래스를 자동으로 상속받도록 컴파일 된다. Object 클래스만이 유일하게 슈퍼 클래스를 가지지 않는다. 관련 글은 나중에~
서브 클래스와 슈퍼 클래스의 생산자
서브 클래스의 객체가 생성되면 이 객체 속에 서브 클래스의 생산자와 슈퍼 클래스의 생산자 모두 실행된다.
실행 순서는 슈퍼 클래스가 우선으로 실행되지만, 호출은 서브 클래스가 우선으로 호출된다.
아래의 코드로 예를 들어보자
package nothing;
class A{
public A() {
System.out.println("A");
}
}
class B extends A {
public B() {
System.out.println("B");
}
}
class C extends B {
public C() {
System.out.println("C");
}
}
public class Eraser {
public static void main(String args[]) {
C inst = new C();
}
}
항상 main이 먼저 실행되므로 main을 먼저 보자
public class Eraser {
public static void main(String args[]) {
C inst = new C();
}
}
클래스 C의 default 생성자가 호출되었다.
class C extends B {
public C() {
System.out.println("C");
}
}
이때 class C의 생성자를 호출하러 가보니 class B가 상속된걸 확인할 수 있다.
그래서 C의 생성자가 실행되지 않고 class B로 올라간다.
class B extends A {
public B() {
System.out.println("B");
}
}
그래서 class B로 가봤는데 또 class A가 상속되어있다.
다시 생성자 B()가 실행되지 않고 바로 class A로 올라간다.
class A{
public A() {
System.out.println("A");
}
}
class A로 와보니 드디어 상속받은게 없는 클래스로 도달했다.
여기서부터 시작하여 다시 A -> B ->C의 순서로 클래스가 실행이 되어 결과가 이렇게 나온다.
super()
주의할 점은 생성자를 지정하지 않으면 컴파일러는 자동으로 default 생성자를 지정하기 때문에 슈퍼 클래스에 default 생성자가 없는 경우 오류가 발생한다. 또한 이대로면 슈퍼 클래스의 생성자가 여러개인 경우 내가 원하는 생성자로 가고 싶어도 컴파일러는 default 생성자를 호출하게 된다.
class A{
public A(int x) { // default 생성자가 없어서 에러
this.x = x
System.out.println("A");
}
}
class B extends A {
public B() {
System.out.println("B");
}
}
그렇기에 필요한 것이 super()이다.
super()은 서브 클래스의 생산자가 명시적으로 슈퍼 클래스의 생성자를 선택하여 호출하는 코드이다.
단, this()와 마찬가지로 super()도 생성자의 맨 첫 라인에 사용되어야 한다.
*** 참고로 this()는 같은 클래스 내에서 생성자가 다른 생성자를 호출할 때 사용하는 코드
class A{
public A() {
System.out.println("A");
}
public A(int x){
System.out.println("수퍼 실행 완료");
}
}
class B extends A {
public B(int x) {
super(x); // 생산자 A(int x) 실행
System.out.println("B");
}
}
public Main(){
public static void main(String[] args){
B inst = new B(1);
}
}