Programming/Flutter

Dart Class 기본적인 사용법 정리

Jan92 2023. 9. 24. 23:56

Dart 언어 Class 기본적인 사용법 정리

 

dart class

Dart는 객체 지향 프로그래밍 언어이며, Flutter 역시 객체 지향 프레임워크인데요.

객체 지향 프로그래밍(OOP)에서는 특정 객체를 생성하기 위한 틀인 클래스(class)가 중요하기 때문에 'Dart 언어의 기본적인 Class 사용법'을 정리한 내용입니다.

 


Class

class Student {
  String name = "leo";
  int grade = 3;
  final String birth = "920101";
  
  void info() {
    print("name: $name, grade: $grade");
  }
}

void main() {
  var student = Student();
  
  //출력 가능
  print(student.name);
  //수정 가능
  student.grade = 4;
  //final 선언된 property 수정 불가
  student.birth = "920102";
}

dart의 class에서 property를 선언할 때는 var가 아닌 구체적인 타입을 꼭 명시해주어야 합니다.

 

그리고 main 메서드의 첫 번째 줄을 살펴보면 'var student = Student();'와 같이 Student class의 인스턴스를 만들 수 있는데요.

이때 new 키워드를 사용해도 되고, 예시와 같이 사용하지 않아도 됩니다.

 

이어서 info() method를 살펴보면 클래스 내부 변수를 사용할 때 this 키워드를 사용하지 않는 것을 볼 수 있는데요.

'this.name', 'this.grade'으로도 사용할 수 있지만, dart에서는 method 내부적으로 같은 이름의 변수가 있는 경우가 아니라면 class method 내에서의 this 사용이 권고되지 않는다고 합니다.

 

 


Constructor

class Student {
  late String name;
  late int grade;
  
  //생성자 예시1
  Student(String name, int grade) {
    this.name = name;
    this.grade = grade;
  }
  
  //생성자 예시2 (위 생성자를 다음과 같이 사용 가능)
  Student(this.name, this.grade);
}

void main() {
  var student1 = Student("leo", 3);
  var student2 = Student('kai', 4);
}

constructor method는 this 키워드를 사용하여 예시 2번과 같이 사용할 수도 있는데요.

dart의 타입추론을 통해 생성자의 첫 번째 자리에는 name의 타입인 String이 와야 하고, 두 번째 자리에는 grade의 타입인 int가 와야 한다는 것을 알 수 있기 때문입니다.

 

하지만 위와 같은 방식으로 클래스의 인스턴스를 생성하는 경우, 예시와 같이 생성자의 parameter가 많지 않은 경우는 문제가 없지만 생성자의 parameter가 많은 경우 어느 위치에 어떤 값이 들어가야 하는지 헷갈리는 문제가 발생할 수 있는데요.

 

이러한 문제를 해결하기 위해 아래와 같은 Named Parameters Constructor를 사용할 수 있습니다.

class Student {
  late String name;
  late int grade;
  
  Student({
    required this.name, 
    required this.grade,
  });
}

void main() {
  var student = Student(
    name: "leo", 
    grade: 3,
  );
}

해당 방식을 사용함으로써 인스턴스 생성 시 각 parametor name을 통해 parametor에 맞는 값을 넣어줄 수 있습니다.

 

 


Named Constructor

enum Gender {
  MAN, WOMAN
}

class Student {
  late String name;
  late int grade;
  Gender gender;
  
  //named 형식
  Student.createMan({
    required String name,
    required int grade,
  })  :  this.name = name,
         this.grade = grade,
         this.gender = Gender.MAN;
  
  //positional 형식
  Student.createWoman(String name, int grade)
    :  this.name = name,
       this.grade = grade,
       this.gender = Gender.WOMAN;
}

void main() {
  var student1 = Student.createMan(
    name: "leo", 
    grade: 3,
  );
  
  var student2 = Student.createWoman("kai", 4);
}

다음과 같이 Student를 초기화하는 named constructor를 사용하여 필요에 따라 다른 인자를 받을 수도 있습니다.

 

여기서 '콜론(:)'을 사용하는 부분은 dart의 고유한 문법적 특징인데요. 콜론(:) 뒷부분에서 class의 property 값을 초기화할 수 있습니다.

 

 


재할당

class Student {
  late String name;
  late int grade;
  
  Student({required this.name, required this.grade});
}

void main() {
  var student1 = Student(
    name: "leo",
    grade: 3,
  )
    ..name = "kai"
    ..grade = 4;
  
  var student2 = student1
    ..name = "leo"
    ..grade = 3;
}

dart에서는 위 예시와 같이 ..을 사용하여 property의 값을 재할당(수정) 할 수도 있는데요.

..를 활용하면 student2 인스턴스를 생성하는 것과 같이 기존의 객체를 기반으로 필요한 값을 수정한 새로운 객체를 생성할 수도 있습니다.

 

 


Inheritance, Mixin

class Human {
  String name;
  Human(this.name);
  
  void info() {
    print("Human info method name:$name");
  }
}

class Student extends Human {
  late int grade;
  
  Student({
    required String name, 
    required this.grade,
  }) : super(name);
  
  @override
  void info() {
    print("Student info method gread:$grade");
  }
}

다음은 Student class에서 Human class를 상속받은 예시인데요.

상속에는 extends 키워드가 사용되며, 하나의 클래스에 대해서만 가능합니다.

 

다음과 같이 상속을 하는 경우 Student class에서 extends한 Human class의 생성자를 호출해야 하며, 방식은 콜론(:)을 사용하고 그 뒤에서 'super' 키워드를 통한 생성자를 호출하게 됩니다.

 

여기서 super class는 extends한 부모 클래스(Human)를 의미하며, super 키워드를 통해 extends한 부모 클래스와 상호작용을 할 수 있게 됩니다.

 

 

mixin A {
  final int a = 123;
}

mixin B {
  void b() {
    ...
  }
}

class Student with A, B{
  late String name;
  late int grade;
  
  Student(String name, int grade);
}

void main() {
  var student = Student("leo", 3);
  
  //A Mixin의 property에 접근 가능
  student.a;
    
  //B Mixin의 method에 접근 가능
  student.b();
}

mixin의 경우 extends와는 다르게 with 키워드를 사용하며, extends의 대상 클래스가 부모 클래스가 되는 것과는 다르게 단순히 mixin 클래스 내부의 property와 method를 가져와서 사용하기 위한 것입니다.

 

mixin의 경우 생성자가 없어야 한다는 조건이 있습니다.

 

 

 

< dart 관련 포스팅 >

2023.08.29 - [Programming/Flutter] - Flutter 학습 전 Dart 언어의 특징 살펴보기

 

(해당 포스팅은 '노마드 코더의 Dart 시작하기' 강의를 참고하여 정리한 내용입니다.)