개요
제한자(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 블록이 실행된다.
'웹(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 |