1. final 키워드

- 클래스, 메서드, 변수에 적용

- abstract와 동시에 사용 불가

- 상속 및 재정의 불가, 즉 서브클래스를 가질 수 없음

- final 변수 값 변경 불가

 

1) final class

- 클래스 선언 시 final을 사용하면 그 클래스는 상속 불가능

- 자식클래스를 가질 수 없고, 오직 외부에서 객체 생성을 통해서만 사용 가능

- final 클래스의 대표적인 예가 String 클래스

  → 사용자가 임의로 String 클래스를 상속받아 메서드를 재정의하는 것을 방지하기 위함

위와 같이 final 키워드를 가진 클래스는 상속이 불가하다는 것을 확인할 수 있다.

 

2) final method

- 메서드 선언 시 final을 사용하면 그 메서드는 상속 시 오버라이딩 불가

- 원본 메서드를 변형할 수 없도록 하기 위함

- 호출은 가능

위와 같이 상속은 가능하지만 final 키워드가 붙은 method2는 자식 측에서 재정의할 수 없는 것을 확인할 수 있다.

 

3) final 변수

- 한 번 값을 할당하면 그 값을 변경할 수 없음

- 선언 시 초기화하는 방법과 생성자를 통하여 초기화하는 방법이 있는데, 초기화하지 않고 남겨두면 컴파일 에러 발생

public class Person {
	// final 변수는 단 한 번 초기화될 수 있고 이후에는 변경이 불가능함
	// 선언 시에 아예 직접 초기화를 해주거나 생성자에서 초기화를 해줘야 함
	public final String nationality = "대한민국"; // 선언부 초기화
	public final String name; // 이렇게 선언부에서 초기화를 안하면 생성자 초기화
	public int age; // final이 안 붙은 멤버변수는 초기화 의무 X
	
	public Person(String name) {
		this.name = name;
	}
}
public class MainClass {

	public static void main(String[] args) {
		Person kim = new Person("김자바");
		//kim.nationality = "일본"; // final 변수 변경 불가
		//kim.name = "채자바";       // final 변수 변경 불가
		kim.age = 25;
		
		System.out.println("국적: " + kim.nationality); // public이므로 호출 가능
		System.out.println("이름: " + kim.name); // public이므로 호출 가능
		System.out.println("나이: " + kim.age); // public이므로 호출 가능
	}
}

위와 같이 final 키워드로 가장 처음 생성했던 값이 출력되는 것을 확인할 수 있다.

즉, final 키워드를 이용하여 변수를 생성하면 변수의 값은 변경할 수 없지만 호출하는 것에는 문제가 없다.

 

- final 배열 예시

public class Collector {
	// 참조형 변수를 가진 경우 변수 자체의 주는 final이지만,
	// 참조형 변수의 내부자료까지 바뀌지 않음을 보장하지 않음
	public final String[] stickers = {"피카츄", "꼬부기", "미뇽"};
}
import java.util.Arrays;

public class MainClass2 {
	public static void main(String[] args) {
		Collector c1 = new Collector();
		System.out.println(Arrays.toString(c1.stickers));
		
		c1.stickers[0] = "파이리";
		System.out.println(Arrays.toString(c1.stickers));
	}
}

final 키워드로 생성한 c1 객체는 해당 배열이 있는 주소를 변경하는 것이 불가능할 뿐이고,

해당 배열이 가리키고 있는 참조형 변수의 내부자료까지는 변경 방지를 보장해주지 않는다.

따라서 위와 같이 배열 내부 요소가 변경된 값이 오류 없이 출력되는 것을 확인할 수 있다.

 

4) 상수(static final)

- 상수 : 불변의 값을 저장하는 필드

- 상수는 객체마다 저장할 필요가 없는 공용성을 가져야 하고,

  여러가지 값으로 초기화될 수 없기 때문에 static과 final 제한자를 동시에 붙여 선언해야 함

- 상수 이름은 모두 대문자로 작성하는 것이 관례, 연결된 단어라면 "_"로 연결

// 상수를 선언할 때는 상수 집합을 만드는 목적으로 아래와 같이 클래스 선언
public class CountrySizes {
	// 상수는 보통 public으로 풀고 사용 (값 변경이 불가능하고, 공용성을 띔)
	public final static int KOREA_SIZE = 100431;
	public final static int STATES_SIZE = 9833519;
	public final static int THAILAND_SIZE = 513120;
}
public class MainClass {
	public static void main(String[] args) {
		// 상수만 모아둔 클래스 특성 상 클래스명이 곧 집합을 대표하는 이름이 됨
		System.out.println(CountrySizes.KOREA_SIZE);
		System.out.println(CountrySizes.STATES_SIZE);
		System.out.println(CountrySizes.THAILAND_SIZE);
	
		// 이를 잘 사용하는 예시는 자바의 Math 클래스가 있음
		System.out.println(Math.PI);
		System.out.println(Math.E);
	}
}

위와 같이 잘 출력되는 것을 확인할 수 있다.

'네트워크캠퍼스 > JAVA' 카테고리의 다른 글

인터페이스  (0) 2024.01.16
추상화  (0) 2024.01.15
싱글톤 패턴  (0) 2024.01.15
사용제한자  (0) 2024.01.12
매개변수의 다형성  (0) 2024.01.11

+ Recent posts