본문 바로가기
Java

자바 static 과 final, 추상화(abstract) 개념 정리

by 오늘이 내가 된다. 2022. 1. 5.

이전에 접근제한자에 대해 알아보았다. 이번엔 그 나머지 제한자를 알아보자.

제한자의 종류에는 static, final, abstract, synchronized 등이 있다. 그 중 중요한 개념 몇 가지를 정리해보았다.

 


제한자란?

- 클래스, 변수, 메서드의 선언부에 사용되어 부가적인 의미를 부여
- 제한자는 접근 제한자와 그 외 제한자로 나뉨
- 하나의 대상에 여러 개의 제한자를 조합해서 사용 가능 (단, 접근제한자는 단 하나만 사용 가능)

 

 

static

제한자 대상 의미
static 멤버변수 - 모든 인스턴스에 공통적으로 사용되는 클래스 변수
- 클래스변수는 인스턴스를 생성하지 않고도 사용 가능
- 클래스가 메모리에 로드될 때 생성
메서드 - 인스턴스를 생성하지 않고도 호출이 가능한 메소드
- static 메소드 내에서는 인스턴스멤버를 직접 사용할 수 없음
static은 멤버변수, 메소드, 초기화 블럭에서 사용이 가능하다.

 

static의 특징

- static이 붙은 변수나 메소드는 모두 클래스가 메모리에 로드될 때 자동적으로 생성 (즉, 인스턴스 생성이 불필요)

- 멤버변수 앞에 static이 붙으면 클래스변수로서 모든 인스턴스가 공유

- static 메소드에서는 인스턴스 멤버를 사용할 수 없음

 

 

final

제한자 대상 의미
final 클래스 변경될 수 없는 클래스, 확장될 수 없는 클래스
final로 지정된 클래스는 다른 클래스의 부모가 될 수 없음
메소드 변경될 수 없는 메소드, final로 지정된 메소드는 오버라이딩을 통해 재정의 될 수 없음
멤버변수 변수 앞에 final이 붙으면 값을 변경할 수 없는 상수가 됨
지역변수
final은 클래스, 메소드, 멤버변수, 지역변수에서만 사용이 가능하다.

 

final의 특징

- 변수 앞에 final 붙으면 값을 변경할 수 없는 상수가 됨 (상수는 대문자로 선언)

- 클래스 앞에 final이 붙으면 부모 클래스가 될 수 없음 (확장이 불가능)

- 메소드 앞에 final이 붙으면 변경될 수 없는(오버라이딩 할 수 없는) 메소드 (자식클래스에서 이 메소드를 재정의x)

 

class Card {
  final int NUMBER;
  final String KIND;
  static int width = 100;
  static int height = 250;
    
  Card(String kind, int num) {
    KIND = kind;
    NUMBER = num;
  }
    
  Card() {
    this("HEART", 1);
  }
    
  public String toString() {
    return "" + KIND + " " + NUMBER;
  }
}

대부분의 상수는 선언과 동시에 초기화를 해준다.

final int NUMBER;

final String KIND;

위의 경우처럼 인스턴스 변수의 경우에는 선언하면서 초기화를 하지 않고, 생성자에서 초기화를 할 수 있다.

 

Card클래스를 정의할 때 선언하자마자 초기화를 하게 되면

불행히도, 모든 Card 인스턴스는 같은 NUMBER와 KIND 값을 가지게 될 수 있다.

 

 

static과 final의 차이는?

static은 따로 인스턴스의 생성이 불필요하며, 메모리에 로드될 때 자동적으로 생성이 된다.

final은 따로 변수선언을 해야 하며, 고정된 값을 지닌다.

 

예를들어 홍길동이라는 사람은 태어나기 이전(객체가 생성되기 이전)에 이미 '홍'이라는 성(姓)을 가진다.

=> static 특징 ( static의 값은 변할 수 있지만 되도록 변경하지 않음. 값이 변하더라도 개념이나 의미는 변하지 않음

길동은 태어난 이후에 생긴 이름이다.

=> 객체 생성

출생신고를 하게 되면 고유한 주민등록번호를 발급받을 것이고, 바뀌지 않는 고정된 값이다.

(혹은 좋은 예로 수학공식 PI값이 있다. final double PI = 3.14 로 선언한다.)

=> final 특징 (선언 시 변경이 불가)

 

왜 static final을 같이 쓰는가?

클래스 멤버변수(static)를 왜 final과 같이 쓸까?

앞서 말했듯이 static의 경우 의미를 고정하는 역할을 수행(값도 대부분 고정)

final의 경우 선언을 하게 되면 값은 바뀔 수 없게 된다.

 

따라서 클래스에서 사용할 해당 멤버 변수의 데이터와 의미 등을 고정하기 위해서 대부분의 경우에 함께 사용한다.

 

abstract

제한자 대상 의미
abstract 클래스 클래스 내에 추상메소드가 선언되어 있음
메소드 선언부만 작성하고 구현부는 작성하지 않은 추상 메소드
abstract는 클래스와 메소드에서 사용할 수 있다.

 

추상클래스

추상클래스는 객체생성을 할 수 없다

=> 자기 책임성에 위배되기 때문이다.

객체를 생성해봤자 추상클래스는 아무 일도 하지 못하기 때문에 객체를 생성하지 못하도록 한다.

상속을 통해서 자식클래스에 의해 완성이 가능하다.

 

예를들면 최신 휴대폰으로 바꾸려고 할 때 기종은 동일하고 용량만 64gb , 128gb 등으로 나뉘는 것을 볼 수 있다.

이 처럼 이 들의 설계도는 거의 동일하다고 볼 수 있다. (혹은 아이폰12, 아이폰12 미니, 아이폰12 맥스 등)

 

서로 다른 설계도를 따로 그리는 것보다, 공통부분만을 그린 미완성 설계도를 만들어 놓고,

미완성 설계도를 이용해서 각각의 설계도를 완성하는 것이 효율적일 것이다.

 

추상클래스는 키워드 'abstract'를 붙이기만 하면 된다. 클래스를 사용할 때, 선언부의 abstract를 보고,

'이 클래스에는 추상메서드가 있으니 상속을 통해서 구현해주어야 한다.' 라는 것을 파악할 수 있다.

abstract class 클래스이름 {
  ...
}

 

추상메소드

메소드는 선언부와 구현부로 구성되어 있다.

선언부는 작성하고, 구현부는 작성하지 않은 채로 남겨 둔 것이 추상메소드이다.

위에서 말했듯이 상속받는 클래스에 따라 달라지도록, 실제 내용은 상속받는 클래스에서 구현하도록 비워둔다.

 

 

추상메소드는 구현부가 존재하지 않아서 전부 리턴타입이 void 일까요? 아니면 다른 경우가 있나요?
구현부가 없다는 얘기는 return타입이 없다는 말 인데 다른 return타입이 존재하나요..?

추상클래스의 하위 클래스를 만들어서 오버라이딩해서 사용이 가능

댓글