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<String, int> seungki = Employee(name: '승기', age: 30);
seungki.employeeInfo();
print(seungki.runtimeType); // Employee<String, int>
seungki.varType(); // name : String, age : int
Employee<String, int> 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 키워드를 사용 할 수 없다.
'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 |