다트 (Dart) 클래스
Null
을 제외한 모든 클래스는 Object 를 상속받음- mixin 을 기반으로 한 상속 지원
- mixin 기반이라는 것은 모든 클래스에 정확히 하나의 슈퍼클래스가 있지만, 클래스 바디를 다양한 클래스 계층 구조에서 재사용할 수 있다는 것
- 002.확장-메서드(Extension-methods): 클래스를 바꾸지 않고 메서드 추가 가능
- 003.클래스-제어자(class-modifier): 하위 클래스 만드는 방식을 제어 가능
클래스 멤버 사용
- 기본적으로 자바나 자바스크립트와 동일하게
.
으로 접근 가능 null
일 수도 있는 경우.
대신?.
을 사용
// p가 non-null이라면, a의 값을 p의 y의 값으로 설정합니다.
var a = p?.y;
생성자 사용
- 정적 팩터리 메서드나 일반 생성자 다 가능
- ClassName 혹은 ClassName.factoryMethodName
new
키워드는 붙여도 되고 안붙여도 됨 (선택적)
var p1 = Point(2, 2);
var p2 = Point.fromJson({'x': 1, 'y': 2});
// new 안붙여도 됨
var p1 = new Point(2, 2);
var p2 = new Point.fromJson({'x': 1, 'y': 2});
상수 생성자
- 컴파일 타임 상수를 만드는 상수 생성자 도 존재함
- 이 때는 생성자 앞에
const
키워드 사용 가능
var a = const ImmutablePoint(1, 1);
var b = const ImmutablePoint(1, 1);
assert(identical(a, b)); // 상수라 다른 변수에 담겨있어도 똑같음
- 상수 컨텍스트 내에서 생성자나 리터럴 앞에
const
를 생략하는 것도 가능 - 아래는
const
맵을 만드는 예시
// const 키워드가 너무 남발됨
const pointAndLine = const {
'point': const [const ImmutablePoint(0, 0)],
'line': const [const ImmutablePoint(1, 10), const ImmutablePoint(-2, 11)],
};
// const 한번으로 상수 컨텍스트를 생성함
const pointAndLine = {
'point': [ImmutablePoint(0, 0)],
'line': [ImmutablePoint(1, 10), ImmutablePoint(-2, 11)],
};
- 단, 상수 컨텍스트 밖인데
const
없이 생성자 호출하면 상수가 아닌 오브젝트로 생성됨
var a = const ImmutablePoint(1, 1); // Creates a constant
var b = ImmutablePoint(1, 1); // Does NOT create a constant
assert(!identical(a, b)); // NOT the same instance!
런타임에 오브젝트의 타입 알기
Object
프로퍼티 중runtimeType
으로 Type 을 알 수 있음
print('The type of a is ${a.runtimeType}');
프로덕션에서는
o.runtimeType === Type
보다는 type test operator 를 사용하는 게 더 좋음
인스턴스 변수
class Point {
double? x; // Declare instance variable x, initially null.
double? y; // Declare y, initially null.
double z = 0; // Declare z, initially 0.
}
- 초기화되지 않으면
null
을 가짐 - 모든 인스턴스 변수는 묵시적으로 getter 메서드를 생성함
- initializer 가 없는
final
이 아닌 인스턴스 변수와late final
인스턴스 변수도 묵시적 setter 메서드를 생성 late
가 아닌 인스턴스 변수를 선언된 곳에서 초기화하면, 생성자와 해당 이니셜라이저 목록이 실행되기 전에 값이 설정된다.- 따라서,
late
가 아닌 인스턴스 변수 이니셜라이저는this
에 접근할 수 없다.
- 따라서,
class Point {
double? x; // Declare instance variable x, initially null.
double? y; // Declare y, initially null.
}
void main() {
var point = Point();
point.x = 4; // Use the setter method for x.
assert(point.x == 4); // Use the getter method for x.
assert(point.y == null); // Values default to null.
}
final
인스턴스 변수
- 인스턴스 변수는
final
일 수 있다.- 이 경우 한번만 값이 들어갈 수 있다.
final
,non-late
인스턴스는 선언시 생성자 파라미터를 이용하거나 생성자의 이니셜라이저 리스트를 이용하여 초기화한다.
class ProfileMark {
final String name;
final DateTime start = DateTime.now();
ProfileMark(this.name);
ProfileMark.unnamed() : name = '';
}
final
인스턴스 변수를 생성자 바디가 시작한 이후에 할당하고 싶다면?- 팩토리 생성자 를 이용
late final
을 이용- 이니셜라이저가 없는
late final
을 이용하면, API 에 세터가 추가되니 주의
- 이니셜라이저가 없는
묵시적 인터페이스
- 모든 클래스는 클래스와 클래스가 구현하는 모든 인스턴스 멤버를 포함하는 인터페이스를 암시적으로 생성한다.
Class B
의 구현을 상속하지 않고Class B
의 API 를 지원하는Class A
를 만들고 싶다면,Class A
는Class B
의 인터페이스를 구현해야 한다.implements
를 이용하면, 몇개의 묵시적 인터페이스든 구현할 수 있다.
// greet() 을 포함한 묵시적 인터페이스는 자동으로 생성되어 있다.
class Person {
// 인터페이스에 있지만, 이 라이브러리에서만 볼 수 있다.
final String _name;
// 생성자이기 때문에 인터페이스에 없다.
Person(this._name);
// 인터페이스에 있다.
String greet(String who) => 'Hello, $who. I am $_name.';
}
// Person 의 묵시적 인터페이스를 구현한다.
class Impostor implements Person {
String get _name => '';
String greet(String who) => 'Hi $who. Do you know who I am?';
}
String greetBob(Person person) => person.greet('Bob');
void main() {
print(greetBob(Person('Kathy')));
print(greetBob(Impostor()));
}
- 여러개를 구현하고 싶다면, 그냥 아래처럼 하면 된다.
class Point implements Comparable, Location {...}
클래스 변수와 메서드
- 클래스 전체에 걸쳐 구현되는 변수나 메서드는
static
키워드를 사용하면 된다.
static
변수
static
변수의 특이한 점은 사용될 때까지 초기화되지 않는다는 것이다.
이 페이지에서는 스타일 가이드를 따라 상수의 이름을
lowerCamelCase
로 작성했다.
class Queue {
static const initialCapacity = 16;
// ···
}
void main() {
assert(Queue.initialCapacity == 16);
}
static
메서드
static
메서드는 인스턴스에서 동작하지 않고 그래서this
에 접근도 불가능하다.static
변수로의 접근은 가능하다.- 인스턴스화 없이 바로 호출이 가능하다.
- 정적 메서드를 컴파일 타임 상수로 사용할 수 있다.
- 정적 메서드를 상수 생성자에게 매개변수로 전달할 수 있다.
일반적이고 널리 쓰일 유틸리티 와 기능을 위해서는 static 메서드 대신 최상위(top-level) 함수를 고려하라.
import 'dart:math';
class Point {
double x, y;
Point(this.x, this.y);
static double distanceBetween(Point a, Point b) {
var dx = a.x - b.x;
var dy = a.y - b.y;
return sqrt(dx * dx + dy * dy);
}
}
void main() {
var a = Point(2, 2);
var b = Point(4, 4);
var distance = Point.distanceBetween(a, b);
assert(2.8 < distance && distance < 2.9);
print(distance);
}
레퍼런스
반응형
'Dart' 카테고리의 다른 글
다트 비동기 프로그래밍 (Future, Async, Await) (0) | 2023.10.22 |
---|---|
다트 (Dart) 언어의 생성자 (Constructors) 정리 (0) | 2023.10.13 |
다트(Dart) 언어의 클래스 제어자 (Class modifier) 정리 (0) | 2023.10.12 |
다트(Dart) 언어의 확장 메서드 (Extension methods) 정리 (0) | 2023.10.10 |
다트의 오류 처리 방식 (1) | 2023.10.08 |