웹(WEB)/자바(Java)

[Java] 자바 제한자

마달랭 2024. 12. 30. 00:02
반응형

개요

제한자(Access Modifiers)는 클래스, 메서드, 변수 등의 접근 범위를 제한하는 키워드이다.

이를 통해 캡슐화(Encapsulation)를 구현하고, 안전한 코드를 작성할 수 있다.

 

자바에는 4가지 주요 접근 제한자가 있다.

접근 제어자 동일 클래스 동일 패키지 다른 패키지 (상속) 다른 패키지 (비상속)
public
private
protected
default

 

그 외 제한자로는 abstract, final, static이 존재한다.

키워드 사용 목적
abstract - 추상 클래스와 추상 메서드를 정의할 때 사용
- 자식 클래스에서 구현하도록 강제
final - 변수: 값 변경을 방지
- 메서드: 오버라이드 방지
- 클래스: 상속 방지
static - 클래스 변수/메서드: 인스턴스화 없이 클래스에서 직접 접근
- 클래스 로딩 시 자동 실행되는 코드

 

 

public

public 제한자는 외부에서 자유롭게 접근해야 할 때 사용한다.

public으로 선언된 경우 해당 클래스, 메서드, 변수는 어디서든 접근 가능하다.

 

클래스는 public이어야만 다른 패키지에서 접근할 수 있다.

메서드나 변수도 public이면 모든 클래스에서 접근 가능하다.

public class Car {
    public int speed;

    public void drive() {
        System.out.println("Car is driving.");
    }
}

 

위 코드에서 speed와 drive()는 어디서든 접근할 수 있다.

 

 

private

private 제한자는 캡슐화를 통해 클래스 내부 구현을 숨기고, 외부에서 직접 접근하지 못하도록 제한할 때 사용한다.

private으로 선언된 경우 해당 클래스, 메서드, 변수는 오직 동일 클래스 내에서만 접근 가능하다.

다른 클래스에서 접근할 수 없으며, getter와 setter 메서드를 사용해 간접적으로 접근할 수 있다.

public class Car {
    private int speed;

    public void setSpeed(int speed) {
        if (speed >= 0) {
            this.speed = speed;
        }
    }

    public int getSpeed() {
        return speed;
    }
}

 

speed 변수는 private이므로 외부에서 직접 접근할 수 없고, setter와 getter 메서드를 통해 값을 설정하고 읽을 수 있다.

 

 

protected

protected 제한자는 상속받은 클래스에서 부모 클래스의 멤버에 접근할 수 있도록 하면서, 다른 클래스에서는 접근을 제한하고 싶을 때 사용한다.

protected로 선언된 해당 클래스, 메서드, 변수는 같은 패키지 내와 다른 패키지의 자식 클래스에서 접근 가능하다.

부모 클래스의 필드나 메서드를 자식 클래스에서만 사용하게 하려는 경우 유용하다.

public class Vehicle {
    protected int speed;

    protected void accelerate() {
        speed++;
        System.out.println("Speed is now: " + speed);
    }
}

public class Car extends Vehicle {
    public void drive() {
        accelerate();  // 부모 클래스의 protected 메서드 접근
    }
}

 

accelerate() 메서드는 protected이므로, 자식 클래스(Car)에서 접근이 가능하다.

다른 패키지의 클래스에서는 접근할 수 없다.

 

 

default

defalut 제한자는 패키지 내에서만 접근을 허용하고, 외부에서는 접근할 수 없도록 하고 싶을 때 사용한다.

default 제한자가 선언된 해당 클래스, 메서드, 변수는 같은 패키지 내에서만 접근 가능하다.

제한자를 명시하지 않으면 default 접근 제어자가 적용되며, 클래스에만 default 제한자가 적용된다.

class Car {  // default 접근 제어자
    int speed;

    void drive() {  // default 접근 제어자
        System.out.println("Car is driving.");
    }
}

 

Car 클래스와 drive() 메서드는 같은 패키지 내에서만 접근이 가능하며, 다른 패키지에서는 접근할 수 없다.

 

 

abstract

추상 클래스 또는 추상 메서드를 정의할 때 사용하는 키워드

abstract 클래스는 인스턴스화 할 수 없는 클래스이다.

추상 클래스는 일부 메서드를 구현하지 않으며, 해당 메서드를 자식 클래스에서 구현하도록 강제한다.

추상 클래스는 상속을 통해 구체적인 클래스에서 사용할 수 있다.

abstract class Animal {  // 추상 클래스
    abstract void sound();  // 추상 메서드 (구현되지 않음)

    void eat() {  // 일반 메서드
        System.out.println("This animal is eating.");
    }
}

class Dog extends Animal {  // Animal 클래스 상속
    void sound() {  // 추상 메서드 구현
        System.out.println("Bark!");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myDog = new Dog();  // Dog 클래스 객체 생성
        myDog.sound();  // Bark!
        myDog.eat();    // This animal is eating.
    }
}

 

Animal 클래스는 추상 클래스이며, sound() 메서드는 추상 메서드로, 자식 클래스인 Dog에서 구현해야한다.

추상 클래스는 인스턴스를 만들 수 없지만, 자식 클래스에서 상속하여 객체를 생성할 수 있다.

 

 

final

변수, 메서드, 클래스에 사용되어 변경을 제한하는 키워드

 

1. final 변수

final 변수는 한 번 값이 할당되면 변경할 수 없다, 상수(Constant) 값을 설정할 때 사용

public class Main {
    public static void main(String[] args) {
        final int MAX_SPEED = 120;  // final 변수 (상수)
        // MAX_SPEED = 150;  // 오류! final 변수는 값 변경 불가
        System.out.println(MAX_SPEED);  // 120
    }
}

 

2. final 메서드

final 메서드는 자식 클래스에서 오버라이딩을 할 수 없다, 메서드 재정의를 막을 때 사용

class Animal {
    final void sound() {
        System.out.println("Animal makes a sound.");
    }
}

class Dog extends Animal {
    // void sound() {  // 오류! final 메서드는 오버라이드 할 수 없음
    //     System.out.println("Bark!");
    // }
}

 

3. final 클래스

final 클래스는 상속할 수 없다, 해당 클래스를 변경하거나 확장할 수 없게 만든다.

final class Animal {
    void sound() {
        System.out.println("Animal sound");
    }
}

// class Dog extends Animal {  // 오류! final 클래스는 상속할 수 없음
// }

 

 

static

클래스 수준에서 변수, 메서드, 블록을 정의할 때 사용하는 키워드

static으로 선언된 변수나 메서드는 클래스 자체에 속하고, 인스턴스를 생성하지 않고도 접근할 수 있다.

 

1. static 변수

static 변수는 클래스에 하나만 존재하며, 모든 객체가 동일한 값을 공유

클래스의 모든 인스턴스가 동일한 static 변수를 참조한다.

class Counter {
    static int count = 0;  // static 변수

    Counter() {
        count++;  // 인스턴스 생성 시마다 count 증가
    }
}

public class Main {
    public static void main(String[] args) {
        new Counter();
        new Counter();
        new Counter();
        
        System.out.println(Counter.count);  // 3
    }
}

 

2. static 메서드

static 메서드는 인스턴스를 생성하지 않고 클래스 이름으로 바로 호출할 수 있다.

static 메서드는 인스턴스 변수를 사용할 수 없고, 클래스 변수만 접근할 수 있다.

class MathUtil {
    static int add(int a, int b) {  // static 메서드
        return a + b;
    }
}

public class Main {
    public static void main(String[] args) {
        int sum = MathUtil.add(3, 5);  // static 메서드 호출
        System.out.println(sum);  // 8
    }
}

 

3. static 블록

클래스가 로딩될 때 자동으로 실행되는 코드 블록, 주로 클래스 초기화에 사용

class MyClass {
    static {
        System.out.println("Static block executed.");
    }
    
    public static void main(String[] args) {
        System.out.println("Main method executed.");
    }
}

 

클래스가 처음 로딩될 때 static 블록이 실행된다.

 

728x90
반응형

'웹(WEB) > 자바(Java)' 카테고리의 다른 글

[Java] 자바 인터페이스  (0) 2024.12.30
[Java] 자바 Object 클래스  (0) 2024.12.30
[Java] 자바 package, import  (0) 2024.12.29
[Java] 자바 객체지향 프로그래밍  (0) 2024.12.29
[Java] 자바 생성자, this  (1) 2024.12.28