Java Study #11

allzeroyou·2022년 2월 17일
0

Java

목록 보기
11/14

final 제어자

필드, 지역변수, 메서드, 클래스 앞에 위치
어디에 위치하느냐에 따라 의미가 다름.

final 변수

final 제어자는 변수를 선언할 때만 지정가능
final 변수는 한번 대입된 값을 수정할 수 없음.
즉, 한번 대입된 값이 최종값이 되는 셈.


클래스 내 필드는 선언과 동시에 값을 대입(A1)할 수 있고 선언과 초기화를 분리(A2)해 작성 가능.
이때 final 필드의 초기화는 반드시 생성자에서 진행해야 함.
세번째는 필드를 선언할때 초기화를 수행하고, 객체를 생성할 생성자에서 값을 변경(A3)하는 경우이다.
클래스 A1에서 필드 b가 final로 선언되어있다.
즉, 필드 b의 값은 이미 5로 초기화되었으므로 절대 수정 불가.
따라서 다음처럼 A1 a1 = new A1();와 같이 객체를 생성했을 때 a1.a 값은 수정 가능, a1.b는 수정 불가.

클래스 A2도 마찬가지, 클래스 A1와 차이점은 final 필드도 선언과 값의 대입을 분리해 표시 가능.
이렇게 선언과 값의 대입을 분리했을 때는 적어도 생성자에서는 값을 대입해야 함.

클래스 A3은 클래스 자체에 오류가 있다. final 필드 b는 선언과 동시에 이미 초기화했음. 따라서 생성자라 하더라도 더 이상 값 변경 불가.

  • 필드나 지역변수가 final로 선언될 때 메모리에서 일어나는 상황
    객체 생성 시 final 필드를 final 영역에 복사함
    필드는 멤버이므로 final 필드이든 아니든 객체 속에 포함됨.
    그러나 객체가 만들어질 때 final로 선언된 필드값은 상수(final)영역에 딱 1번 복사됨.
    final로 선언된 모든 필드값이 상수 영역에 복사되므로 첫 번째 메모리영역을 상수 영역이라고도 부름.

왜 final을 굳이 사용할까?
stack 메모리의 지역변수는 {}가 끝나면, 변수가 사라진다. 그러나 이벤트처리같은 경우 중괄호가 끝나도 필요하다. 이 경우에 final이 필요하다.


field 지역변수는 반드시 한번 값이 대입된 후 값을 입력하는 행위 불가.

final 메서드와 final 클래스

final 변수가 저장한 값이 최종값의 의미를 지닌 것처럼, final 메서드와 클래스도 저장한 값이 최종 값이다.


최종 메서드는 상속할 때 부모의 메서드를 오버라이딩하면 자식 클래스에서는 메서드의 기능이 변경됨.
따라서 final 메서드의 경우 자식 클래스에서 해당 메서드를 오버라이딩 불가.

final 클래스 역시 상속 자체가 불가능.
String 클래스 또한 final 클래스로 정의돼있어 String 클래스를 상속받아 자식 클래스 생성 불가.

abstract 제어자

abstract가 붙은 제어자를 추상 메서드, abstract가 붙은 클래스를 추상 클래스라고 함.
추상 메서드는 {}가 없는 메서드로, 메서드 기능 자체가 정의되지않으며 세미콜론으로 끝남.


Animal 클래스의 cry()메서드는 내부에서 아무런 기능 x
자식 클래스에서 cry()메서드를 오버라이딩해 사용하기 때문이다.

그럼에에도 아무런 기능이 없는 cry()메서드를 Animal 클래스에 정의한 이유는 Animal animal1 = new Cat(); 과 같은 다형적 표현을 사용했을 때도 animal1.cry()형태로 cry()메서드를 호출하기 위함이다.


Animal 클래스 내의 cry()메서드가 아무런 기능을 수행하지 않는다면, 즉 중괄호 안을 비워둘 것이라면 중괄호 자체가 없는 미완성 메서드인 추상메서드로 정의하는 것이 효율적임.

주의) 추상 메서드를 1개 이상 포함하고 있는 클래스 => 반드시 추상클래스로 정의해야 함.

즉, Animal 클래스의 cry()메서드를 추상 메서드로 만들면 Animal 클래스는 반드시 추상클래스여야 함.

추상클래스도 클래스이므로 상속 가능
따라서 자식 클래스들은 Animal 추상 클래스를 상속받아 cry()를 오버라이딩함으로써 동일한 결과 도출 가능.

abstract 제어자의 장점

자식 클래스에서 부모 클래스의 메서드를 오버라이딩하는 과정에서 메서드명에 오타가 있다고 가정하자.
이때 (추상클래스가 아닌)일반 클래스를 상속한 자식 클래스에서는 오버라이딩이 아니라 추가로 새로운 메서드를 정의한 셈으로(오타때문에 오버라이딩이 안되어) 2개의 메서드 존재하는 오류 발생.

이러한 상황에서 부모클래스를 객체로 생성하고, 메서드를 호출하면 당연히 다른 메서드로 출력x
부모에서 넘겨받은 메서드가 아무런 동작을 하지 않기 때문에.

만약 추상메서드를 상속받는다면?

자식클래스가 오버라이딩하려고 하는 과정에서 오타가 발생하면 문법 오류가 발생.

그 이유는?
추상 클래스를 상속하면 추상 메서드도 내려받는데,
추상클래스를 상속받은 자식클래스 내부에서는 상속 받은 추상 메서드가 1개라도 있다면 해당 클래스는 추상 메서드를 일반 메서드로 오버라이딩하거나 자신을 추상클래스로 정의해야 하기 때문이다.

profile
모든 건 zero 부터, 차근차근 헛둘헛둘

0개의 댓글