1. Super와 부모생성자

class가 인스턴스화 될 떄 생성자가 실행되면서 객체를 초가화한다.

그때 자신의 생성자만 실행되는 것이 아니 아니고 부모의 생성자부터 실행됨.

    public class Car{
        public Car(){
            System.out.println("Car의 기본생성자입니다.");
        }
    }

    public class Bus extends Car{
        public Bus(){
            System.out.println("Bus의 기본생성자입니다.");
        }

    }
    
    public class BusExam{
        public static void main(String args[]){
            Bus b = new Bus();
        }
    }

// 이러면 실행했을 떄
// Car의 기본생성자입니다.
// Bus의 기본생성자입니다.
// 이렇게 부모생성자 먼저 실행이 되고, 그 다음 생성자가 실행이 됨.

new 연산자로 Bus객체를 생성하면,

Bus객체가 메모리에 올라갈때 부모인 Car도 함께 메모리에 올라간다.

 

생성자는 객체를 초기화 하는 일을한다.

생성자가 호출될 때 자동으로 부모의 생성자가 호출되면서 부모객체를 초기화 하게된다.

 

super

자신을 가리키는 키워드가 this 라면, 부모들 가리키는 키워드는 super

super() 는 부모의 생성자 == 부모객체를 나타내는 키워드

부모의 생성자를 임의로 호출하지 않으면, 부모 class의 기본 생성자가 자동으로 호출된다.

아래 예제처럼 호출해보면 위에서 super()를 호출하지 않을때와 결과가 같다.

    public Bus(){
        super();
        System.out.println("Bus의 기본생성자입니다.");
    }

 

부모의 기본생성자가 아닌 다른 생성자를 호출하는 방법

클래스는 기본 생성자가 없는 경우도 존재한다.

    public class Car{
        public Car(String name){
            System.out.println(name + " 을 받아들이는 생성자입니다.");
        }
    }

Car class(부모클래스)가 위 처럼 수정되면, Bus생성자에서 컴파일 오류가 발생한다.

부모가 기본생성자가 없기 때문에 컴파일 오류가 발생하게 되는 것이다.

이런 문제를 해결하려면 자식 클래스의 생성자에서 직접 부모의 생성자를 호출해야 합니다.

    public Bus(){
        super("소방차"); // 문자열을 매개변수로 받는 부모 생성자를 호출하였다.
        System.out.println("Bus의 기본생성자입니다.");
    }

super 키워드는 자식에서 부모의 메소드나 필드를 사용할 때도 사용함.

 

2. 오버라이딩 (Overriding)

 

부모가 가지고 있는 메소드와 똑같은 모양의 메소드를 자식이 가지고 있는 것

 == 즉, 메소드를 재정의 하는 것이다.

 

부모의 기능이 나도 필요는 한테 그대로 쓰고싶지는 않을 때,

부모클래스의 메소드를 자식 클래스에서 재정의하여 사용하는 것.

 

Car 클래스를 상속받은 Bus 클래스는 부모클래스가 가진고 있는 run() 메소드를 잘 사용한다.

    //run 메소드를 가지고 있는  Car클래스 
    public class Car{
        public void run(){
            System.out.println("Car의 run메소드");
        }
    }

    //Car 를 상속받는 Bus 클래스 
    public class Bus extends Car{

    }

    public class BusExam{
        public static void main(String args[]){
            Bus bus = new Bus();
            bus.run();  //Car의 run메소드가 실행된다. 
        }
    }

 

Bus클래스에 부모가 가지고 있는 메소드와 모양이 같은 메소드를 선언

    public class Bus extends Car{
        public void run(){
            System.out.println("Bus의 run메소드");
        }
    }

    public class BusExam{
        public static void main(String args[]){
            Bus bus = new Bus();
            bus.run();  //Bus run메소드가 실행된다. 
        }
    }

BusExam을 실행하면, "Bus의 run메소드"가 출력된다.

메소드를 오버라이드 하면, 항상 자식클래스에서 정의된 메소드가 호출된다.

 

오버라이딩 한다고 해서 부모의 메소드가 사라지는 것은 아니다.

super 키워드를 이용하면, 부모의 메소드를 호출 할 수 있다.

    public class Bus extends Car{
        public void run(){
            super.run();  // 부모의  run()메소드를 호출 
            System.out.println("Bus의 run메소드");
        }
    }

 

3. 클래스 형변환

부모타입으로 자식객체를 참조하게 되면 부모가 가지고 있는 메소드만 사용할 수 있다.

자식객체가 가지고 있는 메소드나 속성을 사용하고 싶다면 형변환 해야 한다.

    public class Car{
        public void run(){
            System.out.println("Car의 run메소드");
        }
    }

    public class Bus extends Car{
        public void sound(){
            System.out.println("빵빵.");
        }   
    }

 

상속관계 == is a 관계

== "Bus는 Car다." 라는 관계가 성립되는 것이죠.

 ==> 부모타입으로 자식객체를 참조할 수 있다.

부모타입으로 자식객체를 참조하게 되면 부모가 가지고 있는 메소드만 사용할 수 있다.

== 부모타입으로 자식을 가리킬 수 있으나 이때 부모가 가지고 있는 내용만 사용 가능함.

    public class BusExam{
        public static void main(String args[]){
            Car car = new Bus();
            car.run();
            car.sound(); // 컴파일 오류 발생
        }
    }

*** ppangppang()메소드를 호출하고 싶다면 Bus타입의 참조변수로 참조해야 한다.

 

    public class BusExam{
        public static void main(String args[]){
            Car car = new Bus();
            car.run();
            //car.sound(); // 컴파일 오류 발생

            Bus bus = (Bus)car;  //부모타입을 자식타입으로 형변환 
            bus.run();
            bus.sound(); // 작동
        }
    }

객체들 끼리도 형변환이 가능. 단, 상속관계에 있었을 때만

부모타입으로 자식타입의 객체를 참조할 때는 묵시적으로 형변환이 일어난다.

== 부모 -> 자식으로 형변환은 묵시적

부모타입의 객체를 자식타입으로 참조하게 할때는 명시적으로 형변환 해주어 한다.

== 자식 -> 부모로 형변환은 명시적

단 이렇게 형변환 할때에는 부모가 참조하는 인스턴스가 형변환 하려는 자식타입일 때만 가능하다.

    public class BusExam{
        public static void main(String args[]){
            Car car = new Bus();
            Bus bus = (Bus)car;  //부모타입을 자식타입으로 형변환 
            //이 경우는 car이 자식인 Bus를 참조하고 있었기 때문에 가능한 것.
            
            Car car2 = new Car();
            Bus bus2 = (Bus)car2; //불가능
            //이 경우는 car2가 자식인 Bus를 참조하던 것이 아니라 형변환 불가능함.
        }
    }

'Java > 기초 공부' 카테고리의 다른 글

int와 Integer  (0) 2025.11.26
인터페이스(interface)  (0) 2025.11.21
상속(1) - 상속, 접근제한자, 추상클래스  (0) 2025.11.20
클래스 다듬기 - 생성자, this, 오버로딩, 패키지  (0) 2025.11.20
클래스와 객체(2)  (0) 2025.11.20

+ Recent posts