본문 바로가기
개발/Java

[Java] 정리해서 다시보자 #4 - final 키워드

by onethejay 2022. 12. 19.
728x90

final 키워드 이해하기

final은 '마지막의' 또는 '변경될 수 없는'의 의미를 가지고 있으며 거의 모든 대상에 사용할 수 있습니다.

변수에 사용되면 값을 변경할 수 없는 상수가 되며 메서드에 사용하면 오버라이딩을 할 수 없게 되고
클래스에 사용되면 자신을 확장하는 자손클래스를 정의할 수 없습니다.

final이 사용될 수 있는 곳 - 클래스, 메서드, 멤버변수, 지역변수

제어자 대상 의미
final
클래스변경 될 수 없는 클래스, 확장될 수 없는 클래스가 된다.
final로 지정된 클래스는 다른 클래스의 부모 클래스가 될 수 없다.(상속 불가)
메서드변경 될 수 없는 메서드, final로 지정된 메서드는 자식 클래스에서 오버라이딩을 할 수 없다.
멤버변수변수 앞에 final이 붙으면 값을 변경할 수 없는 상수가 된다.
지역변수

생성자를 이용한 final 멤버 변수의 초기화

final이 붙은 변수는 상수이므로 일반적인 선언과 초기화를 동시에 하지만, 인스턴스변수의 경우 생성자에서 초기화를 진행할 수 있습니다.

class Sample {
    final int MAX_NUM;
    final String SAMPLE_TEXT = "hello world";

    Sample (int num) {
        MAX_NUM = num;
    }
}

final 메서드와 클래스

위에 설명된 것 처럼 메서드에 final이 사용되면 자식 클래스에서 오버라이드가 불가능합니다.
예제 코드로 확인해보겠습니다.

먼저 Bus 클래스를 생성합니다. boot 메서드에만 final을 사용합니다.

public class Bus {

    public void start() {
        System.out.println("출발합니다.");
    }

    public void stop() {
        System.out.println("정지합니다.");
    }

    public final void boot() {
        System.out.println("시동을 겁니다.");
    }

    Bus() {
        boot();
    }
}

이어서 Bus 클래스를 상속받는 ElectricBus 클래스를 생성합니다.

public class ElectricBus extends Bus {

    @Override
    public void start() {
        //super.start();
        System.out.println("전기 버스 출발합니다.");
    }

    @Override
    public void stop() {
        //super.stop();
        System.out.println("전기 버스 정지합니다.");
    }

    @Override
    public void boot() {
        System.out.println("전기 버스 시동을 끕니다.");
    }

    ElectricBus() {
        super.boot();
    }
}

boot 메서드를 오버라이딩 할 수 없다는 에러 메시지가 출력됩니다.

해당 메서드를 자식 클래스에서도 사용하지만, 오버라이딩은 막고 싶을 때 final 키워드를 사용하면 됩니다.

이어서 final 키워드가 붙은 클래스를 확인해보겠습니다.

먼저, 위에서 생성한 ElectricBus에 final 키워드를 추가합니다.

public final class ElectricBus extends Bus {       //public final class 

    @Override
    public void start() {
        //super.start();
        System.out.println("전기 버스 출발합니다.");
    }

    @Override
    public void stop() {
        //super.stop();
        System.out.println("전기 버스 정지합니다.");
    }

    /*
    @Override
    public void boot() {
        System.out.println("전기 버스 시동을 끕니다.");
    }
    */

    ElectricBus() {
        super.boot();
    }
}

이어서 HybridBus 클래스를 생성하고 상속 받으려 하면 에러가 발생합니다.

위와 같이 생성한 클래스를 다른 클래스에서 상속받지 못하게 하고싶다면 final 클래스를 추가하면 됩니다.

참고

자바의 정석 - Chapter 7 객체 지향 프로그래밍 345p

728x90

댓글