Menu
Coddy logo textTech

Public vs Private 멤버

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

캡슐화는 객체 지향 프로그래밍의 핵심 원칙 중 하나입니다. 이는 클래스의 내부 데이터에 대한 접근을 제어하고, 외부 세계에 무엇을 노출할지 그리고 무엇을 숨길지 결정하는 것에 관한 것입니다.

Dart에서 클래스 멤버(필드 및 메서드)는 기본적으로 공개(public)입니다. 이는 모든 코드에서 직접 접근할 수 있음을 의미합니다:

class BankAccount {
  String owner;
  double balance;
  
  BankAccount(this.owner, this.balance);
}

var account = BankAccount('Alice', 1000);
account.balance = -500;  // 누구나 이것을 직접 수정할 수 있습니다!

이것은 문제가 있습니다. 유효하지 않은 잔액을 설정하는 것을 막을 수 있는 방법이 없습니다.

내부 데이터를 보호하기 위해 Dart는 비공개 멤버를 사용합니다. 멤버의 이름이 밑줄 _로 시작하면 해당 멤버는 비공개가 됩니다:

class BankAccount {
  String owner;
  double _balance;  // 비공개(Private) - 밑줄로 시작함
  
  BankAccount(this.owner, this._balance);
  
  double get balance => _balance;  // 제어된 접근
}

이제 클래스가 정의된 라이브러리 외부에서 _balance에 직접 접근할 수 없습니다. 외부 코드는 대신 공개(public) getter를 사용해야 합니다. 이를 통해 데이터가 읽히고 수정되는 방식을 제어할 수 있으며, 객체가 항상 유효한 상태를 유지하도록 보장합니다.

challenge icon

챌린지

쉬움

공개(public) 멤버와 비공개(private) 멤버의 차이점을 보여주는 간단한 비밀번호 관리자를 만들어 보겠습니다. 언더스코어(_) 접두사가 클래스 라이브러리 외부에서 민감한 데이터에 직접 접근하는 것을 어떻게 방지하는지 확인하게 될 것입니다.

코드를 정리하기 위해 두 개의 파일을 생성합니다:

  • credential.dart: 웹사이트의 로그인 정보를 저장하는 Credential 클래스를 정의합니다. 클래스는 다음을 포함해야 합니다:
    • 공개 String website - 어떤 웹사이트인지 누구나 볼 수 있어도 괜찮습니다.
    • 공개 String username - 사용자 이름은 공개될 수 있습니다.
    • 비공개 String _password - 실제 비밀번호는 보호되어야 합니다.
    • 세 가지 값을 모두 받는 생성자
    • 비공개 _password를 반환하는 공개 게터(getter) password (제어된 접근)
    • 모든 문자가 별표 *로 대체된 비밀번호를 반환하는 getMaskedPassword() 메서드 (실제 비밀번호와 동일한 길이)
    • 자격 증명 정보를 안전하게 출력하는 displayCredential() 메서드 (실제 비밀번호가 아닌 마스킹된 비밀번호를 표시)
  • main.dart: 자격 증명 클래스를 임포트하고 캡슐화가 비밀번호를 어떻게 보호하는지 보여줍니다:
    • 웹사이트 'github.com', 사용자 이름 'dev_user', 비밀번호 'secret123'인 자격 증명을 생성합니다.
    • 웹사이트 'email.com', 사용자 이름 'john_doe', 비밀번호 'myP@ss'인 또 다른 자격 증명을 생성합니다.
    • 각 자격 증명에 대해 displayCredential()을 호출한 다음, 공개 게터를 사용하여 비밀번호 길이에 접근하여 Actual password length: [length]를 출력합니다.

displayCredential() 메서드는 다음 형식으로 출력해야 합니다:

--- Credential ---
Website: [website]
Username: [username]
Password: [maskedPassword]

예상 출력 결과:

--- Credential ---
Website: github.com
Username: dev_user
Password: *********
Actual password length: 9
--- Credential ---
Website: email.com
Username: john_doe
Password: ******
Actual password length: 6

치트 시트

캡슐화는 무엇을 노출하고 무엇을 숨길지 결정함으로써 클래스의 내부 데이터에 대한 접근을 제어합니다.

Dart에서 클래스 멤버는 기본적으로 public입니다:

class BankAccount {
  String owner;
  double balance;  // Public - can be accessed directly
  
  BankAccount(this.owner, this.balance);
}

var account = BankAccount('Alice', 1000);
account.balance = -500;  // Direct modification allowed

내부 데이터를 보호하려면 이름 앞에 언더스코어 _를 붙여 private 멤버를 사용하세요:

class BankAccount {
  String owner;
  double _balance;  // Private - starts with underscore
  
  BankAccount(this.owner, this._balance);
  
  double get balance => _balance;  // Controlled access via getter
}

Private 멤버는 클래스가 정의된 라이브러리 외부에서 직접 접근할 수 없습니다. public getter와 메서드를 사용하여 프라이빗 데이터에 대한 제어된 접근을 제공함으로써 객체가 유효한 상태를 유지하도록 하세요.

직접 해보기

import 'credential.dart';

void main() {
  // TODO: github.com에 대한 자격 증명 생성
  // website: 'github.com', username: 'dev_user', password: 'secret123'
  
  // TODO: 첫 번째 자격 증명에서 displayCredential() 호출
  
  // TODO: 공개 게터(getter)를 사용하여 실제 비밀번호 길이 출력
  // 형식: "Actual password length: [length]"
  
  // TODO: email.com에 대한 자격 증명 생성
  // website: 'email.com', username: 'john_doe', password: 'myP@ss'
  
  // TODO: 두 번째 자격 증명에서 displayCredential() 호출
  
  // TODO: 공개 게터(getter)를 사용하여 실제 비밀번호 길이 출력
}
quiz icon실력 점검

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

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