1. 접근 제한자
접근 제한자(Access Modifier)는 클래스, 변수, 메서드 등에 대해 다른 클래스나 객체가 접근할 수 있는 범위를 지정하는 키워드입니다. 대표적인 접근 제한자로는 public, protected, default(아무 것도 안 쓴 상태), private이 있으며, 각각의 제한자는 접근 허용 범위가 다릅니다. public은 어디서든 접근 가능하고, protected는 같은 패키지 또는 자식 클래스에서 접근 가능하며, default는 같은 패키지 내에서만 접근할 수 있고, private은 선언된 클래스 내부에서만 접근할 수 있습니다. 이를 통해 개발자는 코드의 캡슐화와 정보 은닉을 구현하고, 클래스 간의 불필요한 의존성을 줄일 수 있습니다.
접근 제한자의 종류와 범위

1. public
- 어디서든 접근 가능
- 클래스, 메서드, 필드 등에 사용 가능
public class Car {
public String brand = "Hyundai";
public void drive() {
System.out.println("운전 중입니다.");
}
}
2. private
- 오직 같은 클래스 내에서만 접근 가능
- 외부에서 직접 접근할 수 없음 -> 정보 은닉에 필수
public class Account {
private int balance = 1000;
public int getBalance() {
return balance;
}
}
3. default (package-private, 아무 것도 안 씀)
- 같은 패키지 내에서만 접근 가능
- 키워드를 명시하지 않으면 default로 간주됨
class PackageExample {
void show() {
System.out.println("같은 패키지에서만 접근 가능");
}
}
4. protected
- 같은 패키지 또는 다른 패키지의 자식 클래스에서 접근 가능
public class Animal {
protected void eat() {
System.out.println("먹고 있어요");
}
}
class Dog extends Animal {
void barkAndEat() {
eat(); // 부모의 protected 메서드 접근 가능
System.out.println("멍멍!");
}
}
많이 사용하는 예

// 같은 패키지 내의 클래스
public class Person {
public String name = "김사과"; // 어디서든 접근 가능
private int age = 20; // 클래스 내부에서만 접근 가능
protected String hobby = "코딩"; // 같은 패키지나 자식 클래스에서만
String job = "개발자"; // default: 같은 패키지에서만
public void showInfo() {
System.out.println("이름: " + name);
System.out.println("나이: " + age);
System.out.println("취미: " + hobby);
System.out.println("직업: " + job);
}
}
// 같은 패키지 내의 다른 클래스
public class Test {
public static void main(String[] args) {
Person p = new Person();
System.out.println(p.name); // ✅ public → 접근 가능
// System.out.println(p.age); // ❌ private → 접근 불가
System.out.println(p.hobby); // ✅ protected → 같은 패키지 OK
System.out.println(p.job); // ✅ default → 같은 패키지 OK
}
}
2. 객체지향 프로그래밍의 4가지 특징
| 캡슐화(Encapsulation) | 데이터(변수)와 기능(메서드)을 하나의 클래스로 묶고, 외부에서 직접 접근하지 못하도록 보호하는 것 |
| 상속(Inheritance) | 기존 클래스의 속성과 메서드를 새로운 클래스가 물려받아 재사용할 수 있는 것 |
| 다형성(Polymorphism) | 하나의 메서드나 객체가 여러 형태로 동작할 수 있는 것 (오버라이딩, 오버로딩 포함) |
| 추상화(Abstraction) | 복잡한 내부 구현은 숨기고, 중요한 기능만 외부에 제공하는 것 |
1. 캡슐화
public class Account {
private int balance = 0; // 외부에서 직접 접근 불가
// public 메서드를 통해서만 접근 가능
public void deposit(int amount) {
if (amount > 0) balance += amount;
}
public int getBalance() {
return balance;
}
}
public class Main {
public static void main(String[] args) {
Account acc = new Account();
acc.deposit(1000); // 안전한 방식으로 입금
// acc.balance = 10000; // ❌ private이므로 직접 접근 불가
System.out.println("잔액: " + acc.getBalance());
}
}
2. 상속
class Animal {
public void eat() {
System.out.println("먹는다.");
}
}
class Dog extends Animal {
public void bark() {
System.out.println("멍멍!");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat(); // Animal 클래스에서 상속받은 메서드
dog.bark(); // Dog 클래스의 메서드
}
}
3. 다형성
class Animal {
public void speak() {
System.out.println("동물이 소리를 냅니다.");
}
}
class Cat extends Animal {
@Override
public void speak() {
System.out.println("야옹~");
}
}
class Dog extends Animal {
@Override
public void speak() {
System.out.println("멍멍!");
}
}
public class Main {
public static void main(String[] args) {
Animal a1 = new Cat(); // 업캐스팅
Animal a2 = new Dog();
a1.speak(); // 야옹~
a2.speak(); // 멍멍!
}
}
4. 추상화
abstract class Vehicle {
abstract void move(); // 구현은 하지 않음 (추상 메서드)
public void start() {
System.out.println("시동을 겁니다.");
}
}
class Car extends Vehicle {
@Override
void move() {
System.out.println("도로를 달립니다.");
}
}