728x90

Last Updated : 2023.10.19

 

Dart Class

- this.name 에서 this는 클래스를 의미한다.

- 인스턴스를 생성할 때 new 키워드는 붙여도 되고 붙이지 않아도 된다.

- final 키워드를 사용하여 생성자 생성시 name, leg를 변경하지 못하게 할 수 있다.

- String? _name 처럼 변수명 앞에 _가 붙으면 private를 의미하며, 같은 파일내에서만 private로 동작한다.

  Java는 Class 당 1개의 파일을 생성하는 것을 원칙으로 하고 있어 class 내에서만 private가 동작한다.

- 가시성 : 밑줄로 시작하지 않으면 모든 것이 공개(public)된다.

  자바처럼 public, protected, private 키워드를 별도로 사용하지 않는다.

void main(){
  Animal lion = Animal(name: '사자', leg: 4);
  lion.move();
 
  Animal spider = Animal(name: '거미', leg: 8);
  spider.move();
}
 
class Animal {
  final String name;
  final int leg;
 
  //Animal(this.name, this.leg);
  Animal({required this.name, required this.leg});
 
  void move(){
    print('${this.name}가 ${this.leg}개의 다리로 움직입니다.');
  }
}

 

getter / setter 예제

void main(){
  Animal lion = Animal('사자'4);
  lion.name = '호랑이'// setter
  lion.move();
 
  Animal spider = Animal('거미'8);
  spider.move();
  print(spider.name); // getter
}
 
class Animal {
  String? _name;
  final int leg;
 
  Animal(String name, int leg): this._name= name, this.leg=leg;
 
  // String get name {
  //   return this._name ?? '';
  // }
  String get name => this._name ?? ''// getter
 
  void set name(String name) { // setter
    this._name = name;
  }
 
  void move(){
    print('${this._name}가 ${this.leg}개의 다리로 움직입니다.');
  }
}

 

static 은 인스턴스에 귀속되지 않고 class 에 귀속된다.

class Employee {
  static String? building;
  final String name;
 
  const Employee({
    required this.name,
  });
 
  void workInfo(){
    print('제 이름은 ${name}입니다. ${building} 건물에서 근무중입니다.');
  }
}
 
void main() {
  Employee.building = '르네상스호텔'// static은 class 에 귀속된다.
  Employee seungki = Employee(name: '승기');
 
  seungki.workInfo();
 
  Employee gildong = Employee(name: '길동');
  gildong.workInfo();
}

 

Class Generic

- 제네릭(Generic) : 클래스를 정의할 때, 구체적인 타입(type)을 적지 않고 변수 형태로 적어 놓는 것이다. 
- 클래스를 선언하여 객체를 생성할 때, 구체적인 타입을 기재한다. 즉, 타입을 어떤 클래스 종류의 매개변수로 보는 것이다.

- 제네릭 프로그래밍(Generic Programming) : 작성한 코드를 다양한 타입의 객체에 대해 재사용하는 객체 지향 기법이다.

class Employee<T, V> {
  // Generic : 타입을 외부에서 받을 때
  final T name;
  final V age;
 
  const Employee({
    required this.name,
    required this.age,
  });
 
  void employeeInfo(){
    print('제 이름은 ${name}이고, 나이는 ${age}살 입니다.');
  }
 
  void varType(){
    print('name : ${name.runtimeType}, age : ${age.runtimeType}');
  }
}
 
void main() {
  Employee<Stringint> seungki = Employee(name: '승기', age: 30);
  seungki.employeeInfo();
  print(seungki.runtimeType); // Employee<String, int>
  seungki.varType(); // name : String, age : int
 
  Employee<Stringint> gildong = Employee(name: '길동', age: 35);
  gildong.employeeInfo();
}

 

 

 

If We have a few classes such as a Dog class, Cat Class, Wolf Class, Cow class and a Lion Class.

We can see that all these classes share common behaviors and features. 

All of these classes should have a eat method, sleep method, move method

and a makenoise method and common characteristics such as food.

클래스 상속

- 클래스는 다른 클래스를 상속(Inheritance) 받을 수 있다.

- 상속 받을 때에는 extends라는 키워드를 사용한다.

- Dart에서는 하나의 클래스만 상속이 가능하다.

- 부모 클래스에 접근하기 위해서는 super 키워드를 사용한다.

- 자식 클래스에서 @override 키워드를 사용하여 부모 클래스 메소드를 오버라이드(재정의)할 수 있다.

- 자식 클래스에서 새로운 메소드를 추가할 수 있다.

void main(){
  Animal spider = Animal(name: '거미', leg: 8);
  spider.move();
 
  Cat cat = Cat(name: '고양이', leg: 4);
  cat.move();
  cat.eat();
 
  Dog dog = Dog(name: '개', leg: 4);
  dog.move();
 
  print('------ Type Comparison ---- ');
  print(spider is Animal); // true
  print(spider is Cat); // false
  print(dog is Animal); // true
  print(dog is Dog); // true
}
 
class Animal {
  final String name;
  final int leg;
 
  //Animal(this.name, this.leg);
  Animal({required this.name, required this.leg});
 
  void move(){
    print('${this.name}가 ${this.leg}개의 다리로 움직입니다.');
  }
}
 
class Cat extends Animal {
  Cat({required super.name, required super.leg});
 
  void eat(){
    print('${super.name}가 참치를 맛있게 먹고 있습니다.');
  }
 
}
 
class Dog extends Animal {
  Dog({required super.name, required super.leg});
 
  @override
  void move() {
    //super.move();
    print('${super.name}가 ${super.leg}개의 다리로 힘차게 달립니다.');
  }
}

 

인터페이스

- Dart에서는 Interface라는 키워드 대신 class를 사용하여 인터페이스를 정의한다.

- Dart 3.0 부터는 interface class로 선언할 수 있으며 implement만 가능하다.

- 인스턴스 생성을 못하게 abstract 키워드를 붙이고, 메소드 정의만 하도록 한다.

- 인터페이스 구현은 implements 를 사용한다.

abstract class Food {
  String? name;
  void printName(); // 메소드 정의
}
 
class Fruit implements Food {
  String? name;
 
  Fruit(String name) : this.name = name;
 
  void printName() { // 메소드 구현
    print('Fruit name is ${this.name}!');
  }
 
}
 
void main() {
  Fruit fruit = Fruit('Apple');
  fruit.printName();
}

 

 

클래스 확장, 인터페이스 구현, 추상 클래스 외에도 다트는 믹스인(mixin) 개념을 제공하고 여기서 with 키워드를 사용한다.

 

Mixins

- 믹스인은 여러 클래스 계층에서 클래스의 코드를 재사용하는 방법이다.
- with 키워드를 사용하면 상속하지 않고 다른 클래스의 기능을 가져오거나 override 할 수 있다.
- 믹스인을 구현하려면 생성자를 선언하지 않는 클래스를 만든다.
- 믹스인을 일반 클래스로 사용하려면 class 대신 mixin 키워드를 사용한다.

abstract class Super {
  void method() {
    print("Super");
  }
}
 
class MySuper implements Super {
  void method() {
    print("MySuper");
  }
}
 
mixin Mixin on Super {
  void method() {
    super.method();
    print("Sub");
  }
}
 
class Client extends MySuper with Mixin {}
 
void main() {
  Client().method();
}
/* 실행 결과
MySuper
Sub
*/

참고 : https://medium.com/flutter-community/dart-what-are-mixins-3a72344011f3

 

 

Dart 3.0 변경 사항

- final로 클래스를 선언하면 extends, implement, mixin 으로 사용이 불가능하다.

- base로 선언하면 extends는 가능하지만 implement는 불가능하다.

- base, sealed, final로 선언된 클래스만 extend가 가능하다.

- interface로 선언하면 implement만 가능하다.

- sealed 클래스는 adstract이면서 final이다.

  또한 sealed 클래스는 패턴 매칭을 사용할 수 있도록 해준다.

- mixin 클래스로 선언 하여 사용할 수 있다.(mixin과 동일한 특성)

  • extends나 with를 사용할 수 없다.
  • on 키워드를 사용 할 수 없다.

 

728x90

'Flutter 앱 > Dart 언어' 카테고리의 다른 글

Dart 3.0 records  (0) 2023.10.19
Dart Collection  (0) 2022.06.28
Dart Asynchronous programming(비동기 프로그래밍)  (0) 2022.06.23
Dart function(함수)  (0) 2022.06.22
Dart Type 검사(is, is!)  (0) 2022.06.22
블로그 이미지

Link2Me

,