Menu
Coddy logo textTech

클래스에서의 널 안정성

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

클래스를 설계할 때, 어떤 필드가 필수이고 어떤 필드가 선택 사항인지 결정해야 합니다. 널 안전성(Null safety)은 인스턴스 변수를 선언하고 생성자를 작성하는 방식에 영향을 미칩니다.

Non-nullable 필드는 생성자 본문이 실행되기 전에 초기화되어야 합니다. 초기화 리스트, 생성자 매개변수 또는 기본값을 사용하여 이를 수행할 수 있습니다:

class User {
  String name;           // 반드시 초기화되어야 함
  String? bio;           // 선택 사항 - null일 수 있음
  int age = 0;           // 기본값이 있음
  
  User(this.name);       // name은 매개변수를 통해 초기화됨
}

null 허용 필드의 경우, 기본값이 null이므로 초기화하지 않은 상태로 둘 수 있습니다. 이는 선택적 데이터에 유용합니다:

class Product {
  String title;
  String? description;   // 선택적인 제품 설명
  double? discount;      // 기본적으로 할인 없음
  
  Product(this.title);
}

var item = Product('Laptop');
print(item.description);  // null
print(item.discount);     // null

nullable 필드에 접근할 때, 앞에서 배운 null-aware 연산자를 사용하세요:

class Order {
  String id;
  User? customer;
  
  Order(this.id);
  
  String getCustomerName() {
    return customer?.name ?? 'Guest';
  }
}

명명된 매개변수에서 required 키워드는 호출자가 필수 값을 제공하도록 보장합니다:

class Account {
  String email;
  String? phone;
  
  Account({required this.email, this.phone});
}

var acc = Account(email: 'test@mail.com');  // phone은 선택 사항입니다

nullable 필드와 non-nullable 필드를 신중하게 선택함으로써, 어떤 데이터가 필수적이고 어떤 데이터가 선택적인지 명확하게 전달하는 클래스를 생성할 수 있습니다.

challenge icon

챌린지

쉬움

null 안전성(null safety)을 활용하여 필수 필드와 선택적 필드를 사려 깊게 혼합하여 클래스를 설계하는 방법을 보여주는 호텔 예약 시스템을 구축해 보겠습니다.

코드를 두 개의 파일로 구성합니다:

  • reservation.dart: 호텔 예약을 나타내는 Reservation 클래스를 정의합니다. 모든 예약에는 특정 필수 정보가 필요하지만, 일부 세부 사항은 투숙객이 제공할 수도 있고 제공하지 않을 수도 있는 선택 사항입니다. 클래스에는 다음이 포함되어야 합니다:
    • null을 허용하지 않는 String guestName - 모든 예약에는 투숙객 이름이 있어야 합니다.
    • null을 허용하지 않는 int roomNumber - 모든 예약에는 방 번호가 할당되어야 합니다.
    • 기본값이 1인 null을 허용하지 않는 int nights - 최소 숙박 기간은 1박입니다.
    • null을 허용하는 String? specialRequests - 투숙객은 특별 요청 사항이 있을 수 있습니다.
    • null을 허용하는 DateTime? checkInTime - 정확한 도착 시간을 알 수 없을 수도 있습니다.
    • guestNameroomNumberrequired를 사용하고, nights는 기본값을 가진 선택적 매개변수로 사용하는 이름 지정 매개변수(named parameters) 생성자
    • 특별 요청 사항이 제공된 경우 이를 반환하고, 그렇지 않으면 ?? 연산자를 사용하여 'No special requests'를 반환하는 getRequestsSummary() 메서드
    • ?.를 사용하여 체크인 시간의 문자열 표현을 반환하거나, 설정되지 않은 경우 null을 반환하는 getArrivalInfo() 메서드
    • 예약 세부 정보를 표시하는 printConfirmation() 메서드
  • main.dart: 예약 클래스를 가져와서 필수 데이터와 선택적 데이터의 다양한 조합을 보여주는 예약을 생성합니다:
    • 투숙객 'Sarah Johnson', 방 번호 101, 3박, 특별 요청 'Late checkout', 체크인 시간 DateTime(2024, 6, 15, 14, 30)으로 예약을 생성합니다.
    • 투숙객 'Mike Chen', 방 번호 205(기본 숙박 일수 사용), 특별 요청 'Extra pillows'만 설정하여 예약을 생성합니다.
    • 투숙객 'Emma Davis', 방 번호 310, 2박으로 예약을 생성합니다(두 선택적 필드는 null로 둡니다).
    • 각 예약을 순서대로 printConfirmation()을 호출한 다음, getArrivalInfo()를 사용하여 Arrival: [result]를 출력합니다.

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

=== Reservation Confirmed ===
Guest: [guestName]
Room: [roomNumber]
Nights: [nights]
Requests: [getRequestsSummary()]

예상 출력:

=== Reservation Confirmed ===
Guest: Sarah Johnson
Room: 101
Nights: 3
Requests: Late checkout
Arrival: 2024-06-15 14:30:00.000
=== Reservation Confirmed ===
Guest: Mike Chen
Room: 205
Nights: 1
Requests: Extra pillows
Arrival: null
=== Reservation Confirmed ===
Guest: Emma Davis
Room: 310
Nights: 2
Requests: No special requests
Arrival: null

치트 시트

Null을 허용하지 않는(Non-nullable) 필드는 생성자 본문이 실행되기 전에 반드시 초기화되어야 하며, Null을 허용하는(Nullable) 필드는 초기화하지 않은 상태(기본값 null)로 둘 수 있습니다:

class User {
  String name;           // 반드시 초기화되어야 함
  String? bio;           // 선택 사항 - 기본값은 null
  int age = 0;           // 기본값이 있음
  
  User(this.name);
}

선택적인 데이터에는 Nullable 필드를 사용하세요:

class Product {
  String title;
  String? description;   // 선택 사항
  double? discount;      // 선택 사항
  
  Product(this.title);
}

var item = Product('Laptop');
print(item.description);  // null

Null-aware 연산자를 사용하여 Nullable 필드에 접근하세요:

class Order {
  String id;
  User? customer;
  
  Order(this.id);
  
  String getCustomerName() {
    return customer?.name ?? 'Guest';
  }
}

필수적인 값에는 명명된 매개변수(named parameters)에 required 키워드를 사용하세요:

class Account {
  String email;
  String? phone;
  
  Account({required this.email, this.phone});
}

var acc = Account(email: 'test@mail.com');

직접 해보기

import 'reservation.dart';

void main() {
  // TODO: 'Sarah Johnson'을 위한 예약 생성
  // 101호, 3박, 특별 요청 사항: 'Late checkout'
  // 체크인 시간: DateTime(2024, 6, 15, 14, 30)
  
  // TODO: 'Mike Chen'을 위한 예약 생성
  // 205호, 기본 숙박 일수 사용, 특별 요청 사항: 'Extra pillows'
  // 체크인 시간 지정되지 않음
  
  // TODO: 'Emma Davis'를 위한 예약 생성
  // 310호, 2박, 특별 요청 사항 없음, 체크인 시간 없음
  
  // TODO: 각 예약에 대해 순서대로 다음을 수행:
  // 1. printConfirmation() 호출
  // 2. getArrivalInfo()를 사용하여 'Arrival: [result]' 출력
}
quiz icon실력 점검

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

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