클래스 (Classes)

Dart는 클래스 및 믹스인 기반 상속을 사용하는 객체 지향 언어이다. 모든 객체는 클래스의 인스턴스이며 모든 클래스는 Objectarrow-up-right에서 파생된다. 믹스인 기반 상속은 모든 클래스 (Object를 제외하고)는 정확히 하나의 수퍼 클래스를 가지므로 클래스 본문은 여러 클래스 계층에서 다시 사용할 수 있다.

클래스 멤버를 사용하기 (Using class members)

객체는 함수와 데이터로 구성된 멤버를 갖는다 (각각 메소드와 인스턴스 변수). 메소드를 호출하면 객체에서 호출 한다. 메소드는 해당 객체의 함수 및 데이터에 액세스 할 수 있다. 도트(.)를 사용하여 인스턴스 변수 또는 메소드를 참조 한다.

var p = Point(2, 2);

// 인스턴스 변수 y의 값을 설정.
p.y = 3;

// y의 값을 점검.
assert(p.y == 3);

// p에서 distanceTo()를 호출.
num distance = p.distanceTo(Point(4, 4));

최좌측 피연산자가 null 일 때 예외를 피하려면 . 대신 ?.를 사용하라:

// p가 null가 아닌 경우, y 값을 4로 설정.
p?.y = 4;

생성자 사용하기 (Using constructors)

생성자를 사용하여 객체를 만들 수 있다. 생성자 이름은 클래스이름 또는클래스이름.식별자 일 수 있다. 예를 들어, 다음 코드는 Point()Point.fromJson() 생성자를 사용하여 Point 객체를 생성한다 :

var p1 = Point(2, 2);
var p2 = Point.fromJson({'x': 1, 'y': 2});

다음 코드는 동일한 효과를 갖지만 생성자 이름 앞에 선택적인 new 키워드를 사용한다:

Version note: Dart 2에서는new 키워드가 선택 사항이되었다.

일부 클래스는 상수 생성자(constant constructors)arrow-up-right를 제공한다. 상수 생성자를 사용하여 컴파일 타임 상수를 생성하려면 생성자 이름 앞에 const 키워드를 넣으세요:

두 개의 동일한 컴파일 타임 상수를 생성하면 표준 인스턴스가 단일(canonical) 인스턴스가 된다.

상수 컨텍스트(constant context) 내에서 생성자나 리터럴 앞에 const를 생략 할 수 있다. 예를 들어 const 맵을 만드는 이 코드를 살펴보십시오.

const 키워드의 첫 번째 사용을 제외하고 모두 생략 할 수 있다:

상수 생성자가 상수 컨텍스트 외부에 있고 const 없이 호출되는 경우 상수 생성자가 생성된다:

Version note: const 키워드는 Dart 2의 상수 컨텍스트 내에서 선택 사항이되었다.

개체 타입 얻기 (Getting an object’s type)

런타임에 객체의 타입을 얻으려면 Typearrow-up-right 객체를 반환하는 Object의 runtimeType 속성을 사용할 수 있다.


여기까지 클래스를 사용하는 방법을 보았다. 이 섹션의 나머지 부분에서는 클래스를 구현하는 방법을 보여준다.

인스턴스 변수 (Instance variables)

인스턴스 변수를 선언하는 방법은 다음과 같다.

모든 초기화되지 않은 인스턴스 변수는 null 값을 가진다.

모든 인스턴스 변수는 암시적 getter 메소드를 생성한다. Non-final 인스턴스 변수는 암시적 setter 메소드도 생성한다. 자세한 내용은 게터와 세터arrow-up-right를 참조하라.

(생성자 또는 메서드 대신) 선언 된 인스턴스 변수를 초기화하면 생성자 및 초기화 목록이 실행되기 전에 인스턴스가 만들어 질 때 값이 설정된다.

생성자 (Constructors)

클래스와 같은 이름의 함수를 생성하여 생성자를 선언한다 (또 선택적으로 Named constructorsarrow-up-right에 설명 된 추가 식별자). 생성자의 가장 일반적인 형태인 제너레이티브 생성자(generative constructor)는 클래스의 새 인스턴스를 만든다.

this 키워드는 현재 인스턴스를 참조한다.

Note: 이름 충돌이있는 경우에만 this를 사용하라. 그렇지 않으면 Dart 스타일은 this를 생략한다.

인스턴스 변수에 생성자 인수를 할당하는 패턴은 매우 일반적이므로 Dart는 쉽게 만들 수있는 구문적 설탕(syntactic sugar)을 가지고 있다:

기본 생성자 (Default constructors)

생성자를 선언하지 않으면 기본 생성자가 제공된다. 기본 생성자는 인수가 없으며 수퍼 클래스에서 인수가 없는 생성자를 호출한다.

생성자는 상속되지 않음. (Constructors aren’t inherited)

서브 클래스는 슈퍼 클래스에서 생성자를 상속받지 않는다. 생성자를 선언하지 않는 서브 클래스는, 디폴트 (인수 없음, 이름 없음)의 생성자만을 갖는다.

명명 된 생성자 (Named constructors)

명명 된 생성자를 사용하여 클래스에 대한 여러 생성자를 구현하거나 추가 명확성을 제공하라.

생성자는 상속되지 않는다는 것을 기억하라. 즉, 수퍼 클래스의 이름 지정된 생성자가 서브 클래스에 상속되지 않는다는 것을 의미한다. 수퍼 클래스에 정의 된 이름 지정된 생성자로 서브 클래스를 만들려면 해당 생성자를 서브 클래스에 구현해야한다.

디폴트가 아닌 수퍼 클래스 생성자 호출하기 (Invoking a non-default superclass constructor)

디폴트에서는, 서브 클래스의 생성자는, 슈퍼 클래스의 이름이 없는 인수 없는 생성자을 호출한다. 수퍼 클래스의 생성자는 생성자 본문의 처음에 호출된다. 초기자 목록arrow-up-right도 사용중인 경우 수퍼 클래스가 호출되기 전에 실행된다. 요약하면 실행 순서는 다음과 같다.

  1. 초기자 목록

  2. 수퍼 클래스의 인자 없는 생성자.

  3. 메인 클래스의 인자 없는 생성자.

수퍼 클래스에 이름 없는 인수가 없는 생성자가 없으면 수퍼 클래스에서 생성자 중 하나를 수동으로 호출해야한다. 슈퍼 클래스 생성자를 콜론 (:) 다음에 생성자 본문 (있는 경우) 바로 앞에 지정하라. 다음 예제에서 Employee 클래스의 생성자는 수퍼 클래스 Person의 명명 된 생성자를 호출한다. 코드를 실행 하려면 실행 버튼 img 를 누르세요.

수퍼 클래스 생성자에 대한 인수는 생성자를 호출하기 전에 평가되므로 인수는 함수 호출과 같은 표현식이 될 수 있다.

Warning: 수퍼 클래스 생성자에 대한 인수는 this에 접근 할 수 없다. 예를 들어, 인수는 정적 메소드를 호출 할 수 있지만 인스턴스 메소드는 호출 할 수 없다.

초기자 목록 (Initializer list)

수퍼 클래스 생성자를 호출하는 것 외에도 생성자 본문이 실행되기 전에 인스턴스 변수를 초기화 할 수 있다. 쉼표로 초기자를 구분하라.

Warning: 초기화 리스트의 오른쪽은 this에 접근 할 수 없다.

개발하는 동안 초기자 리스트에서 assert를 사용하여 입력을 검증 할 수 있다.

초기자 리스트는 final 필드를 설정할 때 편리한다. 다음 예제에서는 초기자 리스트의 마지막 세 필드를 초기화한다. 코드를 실행 하려면 실행 버튼 img 를 누르세요.

생성자 리디렉션 (Redirecting constructors)

때로는 생성자의 유일한 목적은 동일한 클래스의 다른 생성자로 리디렉션하는 것이다. 리디렉션 생성자의 본문은 비어 있으며 콜론 (:) 다음에 생성자 호출이 나타난다.

상수 생성자 (Constant constructors)

클래스가 변경되지 않는 객체를 생성하면 이러한 객체를 컴파일 타임 상수로 만들 수 있다. 이렇게 하려면 const 생성자를 정의하고 모든 인스턴스 변수가 final인지 확인하라.

상수 생성자는 항상 상수를 생성하지는 않는다. 자세한 내용은 using constructorsarrow-up-right 섹션을 참조하라.

팩토리 생성자 (Factory constructors)

항상 클래스의 새 인스턴스를 생성하지는 않는 생성자를 구현할 때는 factory 키워드를 사용하라. 예를 들어 팩토리 생성자는 캐시에서 인스턴스를 반환하거나 하위 유형의 인스턴스를 반환 할 수 있다.

다음 예제는 캐시에서 객체를 반환하는 팩토리 생성자를 보여준다.

Note: 팩토리 생성자는 this에 접근 할 수 없다.

다른 생성자와 마찬가지로 factory 생성자를 호출하라.

메소드 (Methods)

메서드는 개체에 동작(behavior) 제공하는 함수이다.

인스턴스 메소드 (Instance methods)

객체의 인스턴스 메소드는 인스턴스 변수와 this에 접근 할 수 있다. 다음 예제의 distanceTo()메소드는 인스턴스 메소드의 예이다 :

게터와 세터 (Getters and setters)

getter 및 setter는 객체 속성에 대한 읽기 및 쓰기 액세스를 제공하는 특수 메소드이다. 각 인스턴스 변수에는 암시적인 getter와 적절한 경우 setter가 있다. getset 키워드를 사용하여 getter 및 setter를 구현하여 추가 속성을 만들 수 있다.

getter와 setter를 사용하면 클라이언트 코드를 변경하지 않고 나중에 인스턴스 변수로 시작하고 나중에 메소드로 래핑 할 수 있다.

Note: 증분(++)과 같은 연산자는 getter가 명시적으로 정의되었는지 여부에 관계없이 예상대로 작동한다. 예기치 않은 부작용을 피하기 위해 연산자는 getter를 한 번만 호출하여 해당 값을 임시 변수에 저장한다.

추상 메소드 (Abstract methods)

인스턴스의 getter 및 setter 메서드는 추상화 될 수 있으며, 인터페이스를 정의하지만, 구현을 다른 클래스로 남겨 둔다. 추상 메소드는 추상 클래스 (abstract classes)arrow-up-right에만 존재할 수 있다.

메소드 추상화를 만들려면 메소드 본문 대신 세미콜론(;)을 사용하라.

추상 클래스 (Abstract classes)

abstract 한정자를 사용하여 인스턴스화 할 수 없는 추상 클래스를 정의하라. 추상 클래스는 인터페이스를 정의 할 때 유용하다. 추상 클래스를 인스턴스화 할 수 있게 하려면 factory constructorarrow-up-right을 정의하라.

추상 클래스는 추상 메소드 (abstract method)arrow-up-right를 사용하는 경우가 많다. 다음은 추상 메소드가 있는 추상 클래스를 선언하는 예제이다.

암시적 인터페이스 (Implicit interfaces)

모든 클래스는 클래스의 모든 인스턴스 멤버와 구현하는 인터페이스의 모든 인스턴스를 포함하는 인터페이스를 암시적으로 정의한다. B의 구현을 상속하지 않고 클래스 B의 API를 지원하는 클래스 A를 만들려면 클래스 A가 B 인터페이스를 구현해야한다.

클래스는 하나 이상의 인터페이스를 implements 절에서 선언하고 인터페이스에 필요한 API를 제공함으로써 구현한다. 예 :

다음은 클래스가 다중 인터페이스를 구현하도록 지정하는 예제이다.

클래스를 확장하기 (Extending a class)

서브 클래스를 생성하기 위해서 extends를 사용하고 수퍼 클래스를 참조하기 위해 super를 사용하라:

멤버 재정의 (Overriding members)

서브 클래스는 인스턴스 메소드, getter 및 setter를 오버라이딩 할 수 있다. @override 주석을 사용하여 의도적으로 멤버를 오버라이드하고 있음을 나타낼 수 있다 :

type safearrow-up-right 코드에서 메소드 매개 변수 또는 인스턴스 변수의 타입을 줄이려면 covariant 키워드arrow-up-right를 사용할 수 있다.

재정의 가능한 연산자 (Overridable operators)

다음 표에 표시된 연산자를 재정의 할 수 있다. 예를 들어 Vector 클래스를 정의하면 두 개의 벡터를 추가하는 +메서드를 정의 할 수 있다.

| < | + | | | [] | | ---- | ---- | ---- | ----- | | > | / | ^ | []= | | <= | ~/ | & | ~ | | >= | * | << | == | | | % | >> | |

Note: !=가 오버라이드 할 수 있는 연산자가 아니라는 것을 눈치 챘을 것이다. e1 != e2라는 표현은 !(e1 == e2)의 syntactic sugar 일뿐이다.

다음은 +- 연산자를 재정의 하는 클래스의 예이다:

==를 오버라이드(override)하면, Object의 hashCode getter도 오버라이드 (override) 할 필요가 있다. ==hashCode를 오버라이드하는 예제는 Implementing map keysarrow-up-right를 보십시오.

재정의에 대한 자세한 내용은 일반적으로 클래스 확장 (Extending a class)arrow-up-right을 참조하라.

noSuchMethod()

코드가 존재하지 않는 메소드나 인스턴스 변수를 사용하려고 할 때마다 감지하거나 반응하기 위해 noSuchMethod()를 오버라이드 할 수 있다 :

다음 중 하나가 참이지 않는 한 구현되지 않은 메소드를 호출 할 수 없다.

  • 수신자(receiver)의 정적 타입이 dynamic 이다.

  • 수신자(receiver)는 구현되지 않은 메소드를 정의하는 정적 타입을 갖는다. (추상은 OK이다.) 수신자의 동적 타입은 Object 클래스의 것과는 다른 noSuchMethod()구현을 가지고 있다.

자세한 내용은 비공식 noSuchMethod forward specificationarrow-up-right을 참조하라.

열거 타입 (Enumerated types)

enumerations 또는 enums이라고도하는 열거 타입은 고정 된 수의 상수 값을 나타내는 데 사용되는 특별한 종류의 클래스이다.

열거형 사용 (Using enums)

enum 키워드를 사용하여 열거 타입을 선언하라 :

열거 타입의 각 값에는 열거 타입 getter가 있으며 이 열거 타입은 enum 선언에서 값의 0부터 시작하는 위치를 반환한다. 예를 들어 첫 번째 값은 인덱스 0이고 두 번째 값은 인덱스 1이다.

열거 타입의 모든 값 목록을 얻으려면 열거 형의 values 상수를 사용하라.

switcharrow-up-right에서 열거 타입을 사용할 수 있으며, 모든 열거 타입을 처리하지 않으면 경고 메시지가 표시된다.

열거 타입에는 다음과 같은 제한이 있다.

  • 열거 타입을 서브 클래스화, 믹스인 또는 구현할 수 없다.

  • 열거 타입을 명시적으로 인스턴스화 할 수 없다.

자세한 내용은 Dart language specificationarrow-up-right 를 참조하라.

클래스에 피처 추가하기 : 믹스인 (Adding features to a class: mixins)

믹스인(mixin)은 여러 클래스 계층에서 클래스의 코드를 재사용하는 방법이다.

믹스인을 사용하려면, 하나 이상의 믹스인 이름 뒤에 with 예약어를 사용하라. 다음 예제는 믹스인을 사용하는 두 개의 클래스를 보여준다 :

믹스인을 사용하려면, 하나 이상의 믹스인 이름 뒤에 with 키워드를 사용하라. 다음 예제는 믹스인를 사용하는 두 개의 클래스를 보여준다 :

믹스인을 구현하려면 Object를 확장하고 생성자를 선언하지 않는 클래스를 만든다. 믹스인을 일반 클래스로 사용하지 않으려면 class 대신 mixin 키워드를 사용하라. 예 :

특정 타입만 믹스인을 사용할 수 있도록 지정하려면 - 예를 들어, 믹스인이 정의하지 않은 메소드를 호출 할 수 있도록하려면 on을 사용하여 필수 수퍼 클래스를 지정하라.

Version note: mixin 키워드 지원은 Dart 2.1에서 소개되었다. 이전 버전의 코드는 대개 대신`추상 클래스 '를 사용하였다. 2.1 mixin 변경 사항에 대한 자세한 내용은 Dart SDK changelogarrow-up-right2.1 mixin specificationarrow-up-right.

클래스 변수 및 메소드 (Class variables and methods)

class-wide 변수와 메소드를 구현하려면 static 키워드를 사용하라.

정적 변수 (Static variables)

정적 변수 (클래스 변수)는 클래스 전체의 상태 및 상수에 유용하다.

정적 변수는 사용될 때까지 초기화되지 않는다.

Note: 이 페이지는 상수 이름에 lowerCamelCase를 선호하는 stype guide recommendationarrow-up-right을 따른다.

정적 메소드 (Static methods)

정적 메서드 (클래스 메서드)는 인스턴스에서 작동하지 않으므로 this에 액세스 할 수 없다. 예:

Note: 자주 사용되거나 널리 사용되는 유틸리티와 기능에 대해서는 정적 메소드 대신 최상위 함수를 사용하는 것이 좋다.

정적 메서드를 컴파일 타임 상수로 사용할 수 있다. 예를 들어, 정적 메소드를 매개변수로 상수 생성자에 전달할 수 있다.


이전: 예외 (Exceptions)arrow-up-right

다음: 제네릭 (Generics)arrow-up-right

문서 변경 이력

2019년 5월 15일: 첫 작성.

Last updated