자바 (ref. 자바의정석)

오버라이딩(overriding) + super( ) - JAVA

쿠쿠s 2022. 2. 17. 14:11

 

 

오버라이딩이란?


부모 클래스로부터 상속받은 메서드의 내용을 재정의(변경) 하는 것을 오버라이딩이라고 한다. 물론 상속받은 메서드를 그대로 사용해도 되지만 자식클래스에서 변경해야 하는 경우가 많다. 이렇게 변경이 이루어지는 경우에 부모메서드를 오버라이딩합니다.

 

 

*오버라이딩 사용 조건

오버라딩은 메서드를 새로 만들게 아니고 내용만을 새로 작성하는 것입니다. 메서드의 선언부는 부모와 완전히 일치해야 합니다. 그래서 다음과 같은 조건을 만족해야합니다.

 

1. 자식 클래스의 오버라이딩 하려는 메서드는 부모 클래스의 메서드와
- 이름이 같아야 한다.
- 매개변수가 같아야 한다.
- 반환타입이 같아야 한다.

2. 접근 제어자는 조상클래스의 메서드보다 좁은 범위로 변경할 수 없다.
- ex) 부모클래스 : public void xxx( ){ . . . }  , 자식클래스 : protectecd void xxx( ){ . . . } // 에러!!
-
참고:  public -> protecd, -> (default), -> private 접근 범위가 좁아짐

3. 부모 클래스의 메서드보다 많은 수의 예외를 선언할 수 없다.
- ex) 부모클래스 : void xxx ( ) throws IOException, SQLException { . . . }
       자식클래스:  void xxx ( ) throws Exception { . . . }
단순 개수 문제가 아님. Exception 은 모든 예외의 최고 부모이다. 가장 많은 개수의 예외를 던질 수 있다.

4. 인스턴스 메서드를 static 메서드 또는 그 반대로 변경할 수 없다.

 

 

 

 

간단하게 오버라이딩을 코드로 보여드리겠습니다.

 

class Car{

    void drive(){
        System.out.println("기름을 써서 출발");
    }
}

class EvCar extends Car{

    @Override
    void drive(){
        System.out.println("전기를 써서 출발");
    }
}

class overrridingEX {

    public static void main(String[] args) {

        Car car = new Car();
        car.drive();

        EvCar evCar = new EvCar();
        evCar.drive();
        
    }

}

출력 결과

 

EvCar(자식클래스) 는 Car(부모클래스) 를 상속받아 메서드를 자신에 맞게 전기를 사용한다는 내용을 출력하도록 변경(재정의) 하였습니다. 원래 Car 클래스를 사용하던 사람들은 새로 작성된 EvCar는 상속되었기 때문에 drive 를 호출하면 동일한 기능을 수행할 것이라고 예측할 수 있습니다. 그렇기 때문에 새로 메서드를 제공하기보다 오버라이딩을 사용하는 것이 좋습니다.

 

 

 

super


super는 자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조하는데 사용되는 참조 변수입니다.

멤버변수와 지역변수의 이름이 같을 때 this를 붙여서 구별한 것 처럼 상속받은 멤버와 자신의 클래스에 정의된 멤버의 이름이 같을 때 super를 붙여서 구별할 수 있습니다.

조상의 멤버와 자신의 멤버를 구별하는데 사용된다는 점을 제외하고는 super와 this는 근본적으로 같습니다. 모든 인스턴스메서드에서는 자신이 속한 인스턴스의 주소가 지역변수로 저장이 되는데, 이것이 참조변수인 this와 super의 값이 됩니다.

*static 메서드(클래스메서드)는 인스턴스와 관련이 없어 static메서드에서는 사용이 불가하도 인스턴스메서드에서만 사용이 가능합니다.

 

 

 

 

super( ) - 부모 클래스의 생성자


this( ) 와 마찬가지로 super( ) 역시 생성자입니다. this( ) 는 같은 클래스의 다른 생성자를 호출하는 데 사용되고, super( )는 부모 클래스의 생성자를 호출하는데 사용합니다. 자식 클래스의 인스턴스를 생성하면, 상속 포스팅에 설명드린 것처럼 코드를 공유하기 때문에 멤버가 모두 합쳐진 하나의 인스턴스가 생성이 됩니다. 이때 부모 클래스의 멤버의 초기화 작업이 수행되어야 하기 때문에 자식 클래스의 생성자에서도 부모클래스의 생성자가 호출되어야 합니다.

Object 클래스를 제외한 모든 클래스가 생성자 첫 줄에 생성자 this( ) 또는 super( )를 호출해야 합니다. 그렇지 않으면 컴파일러는 자동적으로 super( ); 를 생성자 첫 줄에 삽입합니다.

 

 

간단한 사용방법을 코드로 보여드리겠습니다.

 

class Car{
    int wheelDrive;

    public Car(int wheelDrive) {
        this.wheelDrive = wheelDrive;
    }

    void drive(){
        System.out.println("기름을 써서 출발 구동은?= " + this.wheelDrive);
    }
}

class EvCar extends Car{
    int chargeEV;

    public EvCar(int wheelDrive, int chargeEV) {
    	//super(); 에러! 부모클래스에 정의된 생성자가 없음
        super(wheelDrive); // 부모클래스의 생성자 Car(int wheelDrive) 호출
        this.chargeEV = chargeEV;
    }

    @Override
    void drive(){
        System.out.println("전기를 써서 출발 " +
                "전기충전량= " + this.chargeEV + " 구동은?= " + this.wheelDrive);
    }

}

class overrridingEX {

    public static void main(String[] args) {

        Car car = new Car(2); //이륜구동
        car.drive();

        EvCar evCar = new EvCar(4, 300); //사륜구동
        evCar.drive();

    }

}

출력 결과

 

 

 

 

위 코드에서 EvCar클래스의 인스턴스를 생성하면, 생성자 EvCar(int wheelDrive, int chargeEv)가 호출되면서 첫 문장인 super( )을 실행하게 됩니다. super( )는 부모클래스인 Car 클래스의 생성자를 호출하게 되는데 만약 매개변수가 없는 super( ) 를 호출하게 되면 부모클래스의 Car( )라는 생성자가 정의되지 않아 컴파일 에러가 발생하게 됩니다.

부모클래스에 Car( ) 를 추가를 해주던가, Car(int wheelDrive)를 호출하도록 super(wheelDrive) 로 변경하면 됩니다.

 

 

 

 

 

 

감사합니다. 혹시 틀린 내용이나 궁금하신점은 댓글 남겨주시면 감사하겠습니다.

 

 

 

 

 

 

'자바 (ref. 자바의정석)' 카테고리의 다른 글

인터페이스(interface) - JAVA  (0) 2022.02.21
다형성(polymorphsim) - JAVA  (0) 2022.02.18
상속(inheritance) - JAVA  (0) 2022.02.16
생성자 (Constructor) - JAVA  (0) 2022.02.15
오버로딩(overloading) - JAVA  (0) 2022.02.14