Menu
Coddy logo textTech

Getter와 Setter 메서드

Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 107개 중 49번째.

내보내지 않은 필드(unexported fields)는 패키지 외부에서 직접 접근할 수 없으므로, 제어된 접근을 허용하는 메서드를 제공해야 합니다. 이러한 메서드들은 흔히 게터(getters)세터(setters)라고 불립니다.

Go에서 getter에 대한 관례는 간단합니다. 필드 이름의 첫 글자를 대문자로 사용하세요. "Get"을 접두사로 붙이지 마세요. GetBalance()가 아니라 그냥 Balance()를 사용하세요:

type BankAccount struct {
    balance int  // 내보내지 않음 (unexported)
}

// Getter - 값을 반환합니다
func (b *BankAccount) Balance() int {
    return b.balance
}

// Setter - 유효성 검사를 거쳐 값을 수정합니다
func (b *BankAccount) SetBalance(amount int) {
    if amount >= 0 {
        b.balance = amount
    }
}

세터(setter)의 진정한 힘은 유효성 검사나 비즈니스 로직을 추가하는 데 있습니다. 외부 코드에서 임의의 값을 직접 설정하도록 허용하는 대신, 허용되는 값을 제어할 수 있습니다:

func (b *BankAccount) Deposit(amount int) bool {
    if amount <= 0 {
        return false
    }
    b.balance += amount
    return true
}

Deposit 메서드는 규칙을 강제하는 특수한 setter 역할을 합니다. 즉, 음수 입금은 허용되지 않습니다. 외부 코드는 반드시 메서드를 거쳐야 하며, 이를 통해 struct가 항상 유효한 상태를 유지하도록 보장합니다. 이것이 바로 캡슐화(encapsulation)의 실제 사례입니다. 데이터를 숨기면서 제어된 동작만을 노출하는 것입니다.

challenge icon

챌린지

쉬움

게터(getter)와 세터(setter) 메서드를 사용하여 적절한 캡슐화를 보여주는 온도 변환기를 만들어 보겠습니다. 내부적으로는 섭씨(Celsius)로 온도를 저장하지만, 유효성 검사가 포함된 메서드를 통해 제어된 접근을 제공하는 구조체(struct)를 만들 것입니다.

코드는 두 개의 파일로 구성됩니다:

  • temperature.go: 외부로 노출되지 않는 celsius 필드(float64)를 가진 Temperature 구조체를 생성합니다. 다음 메서드들을 구현하세요:
    • Celsius() - 현재 섭씨 온도를 반환하는 게터
    • SetCelsius(value float64) - 절대 영도(-273.15) 이상의 값만 허용하는 세터. 값이 이 임계값보다 낮으면 온도는 변경되지 않아야 합니다.
    • Fahrenheit() - (celsius * 9/5) + 32 공식을 사용하여 섭씨를 화씨로 변환하여 반환합니다.
    • SetFahrenheit(value float64) - 입력된 화씨 값을 섭씨로 변환하여 저장하되, 결과 섭씨 값이 -273.15 이상인 경우에만 저장합니다.
    또한 주어진 값으로 초기화된 온도를 생성하는 생성자 NewTemperature(celsius float64) *Temperature를 추가하세요 (생성자에는 유효한 입력이 들어온다고 가정합니다).
  • main.go: 입력에서 온도 값을 읽고 게터/세터 메서드를 시연합니다. 온도를 생성하고 두 단위로 값을 표시한 다음, 새 값을 설정하고 결과를 보여줍니다.

다음 입력이 제공됩니다:

  • 줄 1: 초기 섭씨 값
  • 줄 2: 새로 설정할 섭씨 값
  • 줄 3: 새로 설정할 화씨 값

모든 온도 출력은 소수점 둘째 자리까지 형식화하십시오. 다음 순서대로 출력하세요:

  1. 생성 후: C: [celsius] F: [fahrenheit]
  2. 섭씨 설정 후: C: [celsius] F: [fahrenheit]
  3. 화씨 설정 후: C: [celsius] F: [fahrenheit]

예를 들어, 25, -300, 212가 주어지면 출력은 다음과 같아야 합니다:

C: 25.00 F: 77.00
C: 25.00 F: 77.00
C: 100.00 F: 212.00

두 번째 줄에서 -300은 절대 영도보다 낮기 때문에 세터가 이를 거부하여 값이 변경되지 않은 것을 확인할 수 있습니다. 세 번째 줄은 212°F(섭씨 100°C로 변환됨)를 성공적으로 설정한 후의 온도를 보여줍니다. 이것이 바로 데이터를 유효하게 유지하는 규칙을 강제하는 세터의 힘입니다.

치트 시트

내보내지 않은(Unexported) 필드는 패키지 외부에서 제어된 접근을 위해 gettersetter 메서드가 필요합니다.

Getter 관례

Go에서 getter는 필드 이름의 첫 글자를 대문자로 하여 사용합니다. "Get" 접두사를 붙이지 마세요:

type BankAccount struct {
    balance int  // unexported
}

// Getter - 값을 반환합니다
func (b *BankAccount) Balance() int {
    return b.balance
}

유효성 검사가 포함된 Setter

Setter는 값을 수정하며 유효성 검사나 비즈니스 로직을 포함할 수 있습니다:

// Setter - 유효성 검사와 함께 값을 수정합니다
func (b *BankAccount) SetBalance(amount int) {
    if amount >= 0 {
        b.balance = amount
    }
}

특수 목적의 Setter

직접적인 값 할당을 허용하는 대신 특정 규칙을 강제하는 메서드를 만듭니다:

func (b *BankAccount) Deposit(amount int) bool {
    if amount <= 0 {
        return false
    }
    b.balance += amount
    return true
}

이러한 접근 방식은 캡슐화를 보장합니다. 즉, 데이터를 숨기면서 제어된 동작을 노출하여 구조체(struct)를 유효한 상태로 유지합니다.

직접 해보기

package main

import (
	"fmt"
)

func main() {
	// 입력 값 읽기
	var initialCelsius float64
	var newCelsius float64
	var newFahrenheit float64
	fmt.Scanln(&initialCelsius)
	fmt.Scanln(&newCelsius)
	fmt.Scanln(&newFahrenheit)

	// TODO: 생성자를 사용하여 새로운 Temperature 생성

	// TODO: 초기 값을 "C: [celsius] F: [fahrenheit]" 형식으로 소수점 둘째 자리까지 출력

	// TODO: 새로운 섭씨(Celsius) 값 설정을 시도하고 결과 출력

	// TODO: 새로운 화씨(Fahrenheit) 값 설정을 시도하고 결과 출력
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨