[Java] 제어자(Modifier)

Minuuu·2023년 2월 22일
0

Java

목록 보기
18/18

제어자란?

제어자는 클래스, 변수 또는 메서드의 선언부에 함께 사용되어 부가적인 의미 부여

  • 접근제어자 : public, protect, default, private
  • 그 외 : static, final, abstract, native, transient, synchronized, volatile, strictfp

제어자는 클래스나 멤버변수와 메소드에 주로 사용되며,
하나의 대상에 대해 여러 제어자 조합 사용 가능(단 접근제어자는 넷 중 하나만 가능)

1. static - 클래스의, 공통적인

클래스 변수는 인스턴스에 관계없이 같은 값을 갖는다
하나의 변수를 모든 인스턴스가 공유하기 때문

  • 클래스 변수
    - 모든 인스턴스에 공통적으로 사용되는 클래스 변수
    • 클래스변수는 인스턴스를 생성하지 않고 사용 가능
    • 클래스가 메모리에 로드될 때 생성
  • 클래스 메소드
    - 인스턴스를 생성하지 않고도 호출이 가능한 static메소드
    • static 메소드 내에서는 인스턴스 멤버들을 직접 사용 불가

2. final - 마지막의, 변경할 수 없는

거의 모든 대상에 사용 가능
변수에 사용하면 값을 변경할 수 없는 상수
메소드에 사용되면 오버라이딩 할 수 없다
클래스에 사용되면 자신을 확장하는 자손클래스를 정의하지 못하게 됨


3. abstract - 추상의, 미완성의

메소드의 선언부만 작성하고 실제 수행내용은 구현하지 않은 추상메소드 선언에 사용
abstract는 클래스와 메소드에서만 사용이 가능하다
추상 클래스는 아직 완성되지 않은 메소드가 존재기에 인스턴스를 생성할 수 없다

클래스 자체로는 쓸모 없지만 다르클래스가 이 클래스를 상속받아 일부의 원하는 메소드만 오버라이딩해도 된다는 장점이 있다
이후 인터페이스와 추상클래스에서 더욱 깊이 있게 다루겠다

4. 접근 제어자(access modifier)

멤버 또는 클래스에 사용되어 외부에서 접근하지 못하도록 제한하는 역할
클래스, 멤버변수, 메소드, 생성자에 접근제어자가 지정되어 있지 않다면, default

접근제어자

private - 같은 클래스 내에서만 접근이 가능
default - 같은 패키지 내에서만 접근이 가능
protected - 같은 패키지 내에서, 다르패키지의 자손 클래스에서 접근 가능
public - 접근 제한이 전혀 없다

public > protected > (default) > private

대상 별 사용가능한 접근 제어자
클래스 - public, default
메소드, 멤버변수 - public, protected, default, private
지역변수 - 없음

접근제어자를 이용한 캡슐화

접근제어자 사용 이유

  • 외부로부터 데이터를 보호하기 위해
  • 외부에는 불필요한, 내부적으로만 사용되는, 부분을 감추기위해

위와 같이 외부로부터 접근을 제한하는 것을 객체지향 개념의 캡슐화

public class Time{
	public int hour;
    public int minute;
    public int second;
}

위와 같이 클래스가 정의되어 있을 때 시간에는 0 ~ 23의 값이 들어갈 것이다.
그러나 만약 t.hour = 25의 값이 들어간다면 이를 막을 방법이 없다
이 경우 멤버변수를 private이나 protected로 제한하는 것이 바람직

public class Time{
	private int hour;
}
public void setHour(int hour){
	if(hour < 0 || hour < 23) return;
    this.hour = hour;
}

이렇게 setHour 메소드(setter)를 이용해 클래스 내부에서 멤버 변수의 값을 지정

생성자의 접근 제어자

생성자에 접근 제어자를 사용해 인스턴스의 생성을 제한

class Singleton{
	private static Singleton s = new Singleton();// 인스턴스 미리 생성(static)
	private Singleton(){ // 외부에서 생성자 접근 불가, 클래스 내부에서만 가능
    }
    // 인스턴스를 생성하지 않고 호출하기 위한 static
    public static Singleton getInstance(){
    }
    
}

위 처럼 생성자에 private를 걸어 인스턴스를 생성하지 못하게 하고
public 메소드를 통해 인스턴스에 접근하게 함으로 써 사용할 수 있는 인스턴스 수 제한

생성자가 private이라면 다른 클래스의 조상이 될 수 없다
why? 자손이 조상의 생성자를 호출해야하는데 private이기에 호출이 불가능
-> 그래서 클래스 앞에 final을 추가하여 상속할 수 없는 클래스라는 것을 알리는게 좋다


5. 제어자의 조합

대상 사용 가능한 제어자
클래스public, (default), final, abstract
메소드모든 접근 제어자, final, abstract, static
멤버변수모든 접근 제어자, final, static
지역변수final

제어자 유의사항

  1. 메소드에 static과 abstract 함께 사용 불가
  2. 클래스에 abstract와 final 동시 사용 불가
  3. abstract 메소드에 접근제어자 private 불가
  4. 메소드에 private final 같이 사용할 필요는 없다.

왜 위의 유의사항이 있는지 모르겠다면 다시 한번 공부하자.
도저히 모르겠다면 그 이유를 적어주겠다

1번의 경우 static메소드는 몸통이 있는 메소드에만 사용할 수 있기 때문 abstract는 구현하지 없기 때문이다
2번의 경우 abstract는 상속을 통해 완성하는 추상 클래스인데 final로 확장할 수 없다는 것은 모순이다.
3번의 경우 abstract는 상속관계인데 private이면 접근이 불가능함
4번의 경우 private메소드는 오버라이딩될 수 없기에 하나만 사용해도 의미 충분


후기

접근 제어자의 범위를 기억하자
대상에 따라 사용할 수 있는 제어자를 기억하자
객체지향 프로그래밍의 특징중 하나인 캡슐화와 그 개념을 기억하자
abstract 추상 클래스는 추후에 다룰 것
이 글에서 다루지 않은 제어자를 추후에 더욱 공부해보자!!

profile
꾸준히 한걸음씩 나아가려고 하는 학부생입니다 😄

0개의 댓글