Super class와 Sub class의 생성자 호출 및 실행 관계
여러가지 예시 코드와 질문과 답으로 상속과 생성자를 알아보자.
먼저, 이세상 모~~~든 객체들은 생성되기 위해서 반드시 생성자를 호출해야한다.
그럼 여기서 질문!
Q) 서브 클래스의 객체가 생성될 때 생성자는 몇 번 호출될까?(super와 sub class 두개의 class만 있다고 가정)
A) 정답은 두번이다.
자 생각해보자. 자식이 있기위해서는 부모부터 있어야 할것이다.
그렇다면? 자식을 생성하기 위해서는 부모부터 먼저 생성을 해야한다.
따라서 슈퍼 클래스의 생성자를 호출한 후 서브 클래스의 생성자가 실행된다.
서브 클래스의 생성자가 먼저 호출되고 난 후 슈퍼 클래스의 생성자가 호출되는것은 이제 알겠는데....
서브 클래스의 여러 생성자 중 하나가 실행되고, 슈퍼 클래스의 여러 생성자 중 하나가 실행될텐데....
여기서 질문!
Q) 서브 클래스의 생성자 중 어떤 것과 슈퍼 클래스의 생성자 중 어떤 것이 서로 짝을 이룰까?
A) 4가지 경우로 나눠서 생각해 보자.
1. 서브 클래스 기본 생성자 <---> 슈퍼 클래스 기본 생성자
아래와 같은 경우 A(슈퍼클래스)와 B(서브 클래스)모두 기본 생성자 이므로 자동으로 기본 생성자 끼리 짝을 맺는다.
class A{
public A(){
System.out.println("생성자A");
}
public A(int x){
}
}
class B extends A{
public B(){
System.out.println("생성자B");
}
}
<<<결과값>>>
생성자A
생성자B
2. 서브 클래스 기본 생성자 <---> 슈퍼 클래스 명시적 생성자
그럼 다음과 같이 A(슈퍼 클래스)에 기본 생성자가 없는 경우는 public B()에 대한 짝을 찾을 수가 없어 에러가 발생한다.
class A{
public A(int x){
System.out.println("생성자A");
}
}
class B extends A{
public B(){
System.out.println("생성자B");
}
}
<<<결과값>>>
Implicit super constructor A() is undefined.......(에러)
3. 서브 클래스 명시적 생성자 <---> 슈퍼 클래스 기본 생성자
아래와 같이 B(서브 클래스)클래스의 명시적 생성자를 호출했을 경우 슈퍼 클래스 생성자에 대한 특별한 지시가 없으면 기본 생성자가 호출된다.
class A{
public A(){
System.out.println("생성자A");
}
public A(int x){
System.out.println("매개변수 생성자A");
}
}
class B extends A{
public B(){
System.out.println("생성자B");
}
public B(int x){
System.out.println("매개변수 생성자B");
}
}
public class Test{
public static void main(String[] args){
B b = new B(5);
}
}
<<<결과값>>>
생성자A
매개변수 생성자B
4. 서브 클래스 명시적 생성자 <---> 슈퍼 클래스 명시적 생성자
B 클래스(서브 클래스)의 생성자에서 super(x)로 슈퍼 클래스 생성자의 호출을 명시적으로 하면 슈퍼 클래스의 명시적 생성자가 호출된다.
class A{
public A(){
System.out.println("생성자A");
}
public A(int x){
System.out.println("매개변수 생성자A");
}
}
class B extends A{
public B(){
System.out.println("생성자B");
}
public B(int x){
super(x);
System.out.println("매개변수 생성자B");
}
}
public class Test{
public static void main(String[] args){
B b = new B(5);
}
}
<<<결과값>>>
매개변수 생성자A
매개변수 생성자B
이해가 안간다면 마지막으로 내 코드를 보면서 한번더 복습해 보자!!
Product(슈퍼클래스) - TV, Refrigerator(서브클래스)
// 명시적 생성자만 만들어 주었으므로 기본 생성자를 호출 못함
class Product {
private int serialNo;
private String productName;
private int price;
private int stock;
public Product(int serialNo, String productName, int price, int stock) {
this.serialNo = serialNo;
this.productName = productName;
price = price;
this.stock = stock;
}
public String getProduct() {
return serialNo+"\t"+productName+"\t"+price+"\t"+stock+"\t";
}
}
//super(...)로 명시적으로 슈퍼 클래스의 명시적 생성자 호출
class Refrigerator extends Product{
private double volume;
public Refrigerator(int serialNo, String productName, int price, int stock, double volume) {
super(serialNo, productName, price, stock);
this.volume = volume;
}
@Override
public String toString() {
return super.getProduct() + volume; //이부분은 추후 설명
}
}
class TV extends Product{
private double inchi;
private String displayType;
//super(...)로 명시적으로 슈퍼 클래스의 명시적 생성자 호출
public TV(int serialNo, String productName, int price, int stock, double inchi, String displayType) {
super(serialNo, productName, price, stock);
this.inchi = inchi;
this.displayType = displayType;
}
@Override
public String toString() {
return super.getProduct() + inchi + "\t" + displayType;
}
}
public class ProductTest {
public static void main(String[] args) {
//명시적으로 서브 클래스의 생성자 호출
TV tv = new TV(11111, "aaa", 1500000, 125, 62.0, "eee");
Refrigerator refrigerator = new Refrigerator(22222, "bbb", 3650000, 263, 825.0);
//추후 객체와 toString 관계에 대해 설명할 계획
System.out.println(tv);
System.out.println(refrigerator);
}
}
다음으로는 메소드 오버라이딩에 대해 알아봅시당~~!!
'CS > Java' 카테고리의 다른 글
Java Static - Static에 대한 모든것! 이거 하나면 끝! (0) | 2019.07.29 |
---|---|
Java 상속 - 5. Polymorphism(다형성) & instanceof (0) | 2019.07.29 |
Java 상속 - 4. 오버로딩 vs 오버라이딩 (0) | 2019.07.29 |
Java 상속 - 3. toString (0) | 2019.07.23 |
Java 상속 - 1. 상속이란? (0) | 2019.07.22 |