Java (오버로딩(Overloading) / Getter·Setter / 접근제어자)

최병현·2025년 12월 30일

java

목록 보기
16/38

1. 생성자 오버로딩 (Constructor Overloading)

생성자 오버로딩이란, 매개변수의 개수나 타입이 다른 여러 생성자를 같은 클래스 안에 정의하는 것을 말한다. 같은 클래스로 객체를 만들더라도 상황에 따라 다른 방식으로 초기화할 수 있어서 유연한 객체 생성이 가능해진다.

생성자의 특징은 다음과 같다.

  • 생성자 이름은 클래스명과 동일하다.
  • 리턴 타입이 없다.
  • 매개변수 구성이 다르면 여러 개 선언할 수 있다.

예시로 Product 클래스를 생성자 오버로딩 형태로 작성하면 아래와 같다.

public class Product {
    int productNum;
    String productName;

    public Product() {
    }

    public Product(int productNum) {
        this.productNum = productNum;
    }

    public Product(String productName) {
        this.productName = productName;
    }

    public Product(int productNum, String productName) {
        this.productNum = productNum;
        this.productName = productName;
    }
}

같은 Product 클래스라도 번호만 초기화하거나, 이름만 초기화하거나, 둘 다 초기화하는 등 다양한 생성 방식이 가능해진다.


2. Getter / Setter의 필요성

필드를 외부(다른 클래스)에서 직접 수정할 수 있게 두면, 잘못된 값이 들어가도 이를 통제하기가 어렵다. 예를 들어 나이(age)에 -10 같은 비정상적인 값이 들어가도 막을 방법이 없다.

public class Person {
    // field 선언
    String name;
    int age;
}

public class PersonMain {
    public static void main(String[] args) {
        Person person1 = new Person(); // 객체 생성

        // 외부에서 직접 값 대입 가능
        person1.name = "길동";
        person1.age = -10; // 비정상 값

        System.out.println(person1.name); // 길동
        System.out.println(person1.age);  // -10
    }
}

이처럼 외부에서 직접 필드값을 바꾸는 구조는 데이터 무결성이 깨질 수 있다는 문제가 있다. 이를 해결하기 위한 방법이 Getter / Setter 개념이다.


3. Getter / Setter란?

1) Setter

Setter는 데이터를 설정(set)하는 역할을 하는 메서드이다. 외부에서 필드를 직접 수정하지 못하도록 막고, 특정 메서드를 경유해서 값을 전달받아 초기화 또는 수정하도록 만든다. 또한 이 과정에서 유효성 검증 로직을 넣을 수 있다.

2) Getter

Getter는 데이터를 조회(get)하는 역할을 하는 메서드이다. 외부에서 필드를 직접 읽지 못하도록 막고, 메서드를 통해 안전하게 값을 반환(return)한다.


4. Getter / Setter의 장점

  • 데이터 보호: 필드를 private로 숨겨 외부에서 직접 접근하지 못하게 한다.
  • 유효성 검증: setter에서 -10 같은 잘못된 값(범위 초과 등)을 걸러낼 수 있다.
  • 캡슐화(encapsulation): 데이터를 숨기고 필요한 경우에만 제한적으로 접근하도록 만들어 내부 구현을 외부에 노출하지 않는다.
  • 유연성 증가: 요구사항이 바뀌어도 Main이 아닌 클래스 내부 메서드만 수정하면 되어 유지보수가 쉬워진다.

5. Getter / Setter 기본 구조

Setter 구조

public void set속성명(자료형 변수명) { this.속성명 = 변수명; }

public void setName(String name) {
this.name = name;
}

Getter 구조

public 자료형 get속성명() {
    return 속성명;
}

public int getAge() { // field와 getter의 자료형이 일치해야 함
    return age;
}

6. 접근제어자(Access Modifier)

1) 정의

접근제어자는 클래스, 필드, 메서드, 변수의 접근 범위를 제어하는 키워드이다. 정보 은닉(캡슐화)을 실현하고, 코드의 보안성과 유지보수성을 높이기 위해 사용한다.

2) 종류

  • public: 모든 클래스에서 접근 가능
  • protected: 같은 패키지 + 상속 받은 자식 클래스에서 접근 가능
  • default: 접근제어자를 명시하지 않으면 default (같은 패키지에서만 접근 가능)
  • private: 같은 클래스 내부에서만 접근 가능

일반적으로 필드는 private로 숨기고, 외부 접근은 public getter/setter로 열어주는 방식이 많이 사용된다.


7. 실습 예제 — UniveStudent2 (유효성 검증 포함)

Setter에 유효성 검증을 넣어서 잘못된 데이터가 들어오면 막도록 구현했다. 또한 생성자에서도 범위를 검사해 불가능한 입력을 처리하는 예시를 만들었다.

public class UniveStudent {
    String name;
    int grade;
    double score;

    public UniveStudent() {
    }

    public UniveStudent(String name) {
        this.name = name;
    }

    public UniveStudent(int grade) {
        this.grade = grade;
    }

    public UniveStudent(String name, int grade) {
        this.name = name;
        this.grade = grade;
    }

    public UniveStudent(String name, int grade, double score) {
        this.name = name;
        this.grade = grade;
        if(score < 0 || score > 4.5) {
            System.out.println("불가능한 입력입니다.");
            return;
        }
        this.score = score;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setGrade(int grade) {
        if(grade < 0 || grade > 4) {
            System.out.println("불가능한 범위 입력입니다.");
            return;
        }
        this.grade = grade;
    }

    public void setScore(double score) {
        if(score < 0 || score > 4.5) {
            System.out.println("불가능한 범위 입력입니다.");
            return;
        }
        this.score = score;
    }

    public String getName() {
        return name;
    }

    public int getGrade() {
        return grade;
    }

    public double getScore() {
        return score;
    }

    public void showInfo() {
        System.out.println("\n이름: " + name + "\n학년: " + grade + "\n점수: " + score);
    }
}

9. 접근제어자 확인 예제

private 필드는 외부에서 직접 접근할 수 없기 때문에, getter를 통해서만 값을 확인할 수 있다.


// 이하의 클래스는 default가 생략
class AccessModifierExample { // 간판 클래스는 public이 명시돼야 함.
    public int publicVar = 10;
    protected int protectedVar = 20;
    int defaultVar = 30;
    private int privateVar = 40;

    public int getPrivateVar() {
        return privateVar;
    }
}

public class Main {
    public static void main(String[] args) {
        AccessModifierExample example = new AccessModifierExample();

        System.out.println(example.publicVar);
        System.out.println(example.protectedVar);
        System.out.println(example.defaultVar);
//        System.out.println(example.privateVar); // private 접근 제어자이기 때문에 오류
        System.out.println(example.getPrivateVar());
    }
}

10. 오늘 정리하며 느낀 점

생성자 오버로딩을 통해 같은 클래스라도 다양한 상황에 맞게 객체를 초기화할 수 있다는 점이 확실히 이해됐다. 또 Getter / Setter는 단순한 문법이 아니라, 데이터를 직접 건드리지 못하게 막고 검증을 거쳐 안전하게 관리하는 구조라는 점이 핵심이었다.

접근제어자를 함께 적용하면 정보 은닉(캡슐화)이 자연스럽게 구현되고, 클래스 내부 로직을 외부에서 함부로 깨지 못하게 만들 수 있다는 점이 인상 깊었다. 결국 객체지향에서 중요한 건 “값을 아무렇게나 넣고 꺼내는 것”이 아니라, 클래스가 책임지고 데이터를 관리하도록 설계하는 것이라는 걸 체감했다.

profile
Develop

0개의 댓글