flutter_note010 Widget과 Class의 상관 관계 2.

5yattree·2023년 1월 24일
0

Flutter 정리 노트

목록 보기
10/13

Widget과 Class의 상관 관계 2.

Class(클래스), Constructor(생성자), Instance(인스턴스)

class StudyMembers{
  String study = 'Flutter & Dart';
  String? name;
  int? age;
  String? location;
  bool? prior;
}

void main(){
  
  StudyMembers member1 = StudyMembers();
  member1.name = '5yattree';
  member1.age = 100;
  member1.location = 'Seoul';
  member1.prior = false;
  
  print(member1.study);
  print(member1.name);
  
}

위의 코드는 Flutter와 Dart를 함께 공부하는 스터디 멤버들의 속성을 정의하기 위해 작성한 Class(클래스)이며 또한 이렇게 작성한 Class(클래스)를 이용하여 Constructor(생성자)를 통해 새로운 Instance(인스턴스)를 생성한 것을 이해하기 위해서 작성한 코드이다.

class StudyMembers{
  String study = 'Flutter & Dart';
  String? name;
  int? age;
  String? location;
  bool? prior; 
  // 이 클래스 내의 속성 즉, study, name, age, location, prior는 멤버 변수라고 한다.
  
}

Class(클래스)의 내부를 살펴보면 스티디 멤버들이 어떤 것을 공부하는지 또 스터디 멤버의 이름과 나이, 사는 지역과 이전의 프로그래밍 경험등을 속성(아규먼트,Argument)으로 가질 수 있도록 작성하였다. 이와 같은 속성들 즉, Class(클래스) 내부의 변수는 또 다른 말로 Member Variable(멤버 변수)라고도 한다.

*String?, int?, bool? 뒤의 물음표(?)를 넣어둔 건 Null Safety를 적용하기 위함으로 Nullable한 변수로써 지정하기 위함.

void main(){
  
  StudyMembers member1 = StudyMembers();
  member1.name = '5yattree';
  member1.age = 100;
  member1.location = 'Seoul';
  member1.prior = false;
  
  print(member1.study); // "Flutter & Dart"
  print(member1.name); // "5yattree"
  
}

main() 함수 내부의 코드를 살펴보면
StudyMembers member1 = StudyMembers(); 구문에서 생성자를 통해 member1 이라는 인스턴스를 생성하고 각각 속성의 데이터를 정의하는 것을 확인할 수 있다. 예시에서는 스터디 멤버인 member1은 생성자를 통해 새롭게 생성된 인스턴스로 5yattree라는 이름과 100살의 나이, 또 서울에 거주하며 이전에 프로그래밍 경험이 없는 것으로 정의되어 각 변수에 값이 할당되었다.

StudyMembers member1 = StudyMembers(); 생성자.

Default Constructor (기본 생성자)

class StudyMembers{
  String study = 'Flutter & Dart';
  String? name;
  int? age;
  String? location;
  bool? prior;
}

사실 작성한 위의 Class(클래스) 코드에서는 멤버 변수외에 별도 따로 작성한 부분은 존재하지 않는다.
하지만 우리 눈에 보이지 않을 뿐 Dart 프로그래밍 언어가 알아서 Default Constructor(기본 생성자)라는 것을 만들어 둔다.

class StudyMembers{
  String study = 'Flutter & Dart';
  String? name;
  int? age;
  String? location;
  bool? prior;
  
  // 실제로 눈에 보이진 않지만 Default Constructor(기본 생성자)는 존재하며 있다.
  // StudyMembers(); 
  // StudyMembers(){}
  
}

void main(){
  
  StudyMembers member1 = StudyMembers();
  
  print(member1.study); // Flutter & Dart 출력
  print(member1.name); // null 출력
  print(member1.age); // null 출력
  print(member1.location); // null 출력
  print(member1.prior);  // null 출력
  
  member1.name = '5yattree';
  member1.age = 100;
  member1.location = 'Seoul';
  member1.prior = false;
  
  print(member1.study); // Flutter & Dart 출력
  print(member1.name); // 5yattree 출력
  print(member1.age); // 100 출력
  print(member1.location); // Seoul 출력
  print(member1.prior);  // false 출력
  
}

따라서 위의 기본 생성자를 통해 만들어진 처음의 member1 인스턴스는 Class(클래스)에서 사전에 정의된 데이터를 토대로 생성되는 것으로 이해할 수 있고, 이렇게 생성된 인스턴스의 각 변수에는 다시 값을 할당하여 이용 수 있는 것으로 이해할 수 있다.

그러나 이렇게 매번 Class(클래스)와 Constructor(생성자)를 통해서 인스턴스를 생성할 때마다 각각의 변수를 일일히 할당하는 것은 어쩌면 비효율적이고 번거로운 일이 될 수 있다. 따라서 이런 경우 Class(클래스)내의 Constructor(생성자)를 직접 정의하여 새롭게 이용할 수 있다.

생성자 응용 1. 생성자 새롭게 정의 하기.

class StudyMembers{
  String study = 'Flutter & Dart';
  String? name;
  int? age;
  String? location;
  bool? prior;
  
  StudyMembers(String name, int age, String location, bool prior){
    this.name = name;
    this.age = age;
    this.location = location;
    this.prior = prior;
  }
  
  // StudyMembers(this.name, this.age, this.location, this.prior); 다른 표현. V
  // StudyMembers(this.name, this.age, this.location, this.prior){} 다른 표현.
  
}

void main(){
  
  StudyMembers member1 = StudyMembers('5yattree', 100, 'Seoul', false);
  StudyMembers member2 = StudyMembers('Yesol', 100, 'Jeju', true);
  
  print(member1.study); // Flutter & Dart 출력
  print(member1.name); // 5yatree 출력
  print(member1.age); // 100 출력
  print(member1.location); // Seoul 출력
  print(member1.prior);  // false 출력
  
  print(member2.study); // Flutter & Dart 출력
  print(member2.name); // Yesol 출력
  print(member2.age); // 100 출력
  print(member2.location); // Jeju 출력
  print(member2.prior);  // true 출력
    
}

StudyMembers 클래스 내에 생성자를 직접 정의하였고 이렇게 새롭게 정의한 생성자를 통해서
호출된 생성자에게 각 아규먼트의 순서와 데이터 타입에 맞게 값을 할당하여 새로운 인스턴스를 생성할 수 있다.
만일 아규먼트의 순서와 데이터 타입이 일치하지 않는다면 오류가 발생하므로 주의

생성자 응용 2. 네임드 아규먼트 (Named Argument)

이처럼 생성자를 새롭게 정의하여 일일히 번거롭게 인스턴스를 생성하고 변수의 값을 할당하는 작업을 진행하지 않고 한번에 인스턴스를 생성할 수 있지만 만약 아규먼트의 갯수가 30개, 40개, 100개로 비교적 많다면?
또 새로운 인스턴스를 생성자를 통해 생성할 때 100개의 아규먼트 중 3,4개 정도만 입력받고 싶다면?
현재 생성자로는 아규먼트가 몇개 이건 반드시 순서를 지키며 모든 값을 입력 해야하는데...
이를 해결하기 위해서 만들어진 네임드 아규먼트 (Named Argument)

class StudyMembers{
  String study = 'Flutter & Dart';
  String? name;
  int? age;
  String? location;
  bool? prior;
  
  StudyMembers({String? name, int? age, String? location, bool? prior}){
    this.name = name;
    this.age = age;
    this.location = location;
    this.prior = prior;
  }
  
  // StudyMembers({String? name, int? age, String? location, bool? prior}); 다른 표현. V
  // StudyMembers({String? name, int? age, String? location, bool? prior}){} 다른 표현.
  // {} 생성자 내의 아규먼트들을 중괄호 Curly Brackets 로 감싸서 아규먼트들을 선택 사항으로 이용.
  
}

void main(){
  
  StudyMembers member1 = StudyMembers(name: '5yattree');
  StudyMembers member2 = StudyMembers(age: 100);
  
  print(member1.name); // 5yatree 출력
  
  print(member2.age); // 100 출력
    
}

위의 코드에서처럼 네임드 아규먼트(Named Argument)를 이용한다면 모든 아규먼트들을 지정하지 않아도 인스턴스가 생성되며, 입력하고자하는 특정 아규먼트만 값을 할당하여 이용이 가능하다.

Widget과 Class의 상관 관계 결론

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Color Palette',
      home: HomePage(),
      debugShowCheckedModeBanner: true,
      theme: ThemeData(primarySwatch: ),
    );
  }
}

최종적으로 결론으로 돌아와 처음에 이야기를 나누었던 Object(객체), Class(클래스), Instance(인스턴스), Constructor(생성자), Named Argument(네임드 아규먼트)들을 이해하고 나서 위의 코드를 다시 한번 살펴본다면.

이젠 무언가 다른 느낌을 받을 수 있다.

결국, MaterialApp Widget(위젯)은 MaterialApp Class(클래스) 내의 생성자를 통해서 생성된 새로운 인스턴스이며.
title, home, debugShowCheckedModeBanner, theme 등 아규먼트들은 Named Argument(네임드 아규먼트)이다.

app.dart 파일에 정의된 MaterialApp 을 살펴보아도 MaterialApp Class(클래스) 내에 생성자를 통해서 각각의 속성들이 Named Argument(네임드 아규먼트)로써 정의된 것으로 이해할 수 있다.

profile
오얏나무 한 그루

0개의 댓글