class Animal {
// 클래스 내에 변수 지정
String type;
String name;
// 생성자
Animal(this.name, this.type); // this를 통해 클래스 내 변수에 접근가능
}
void main(){
Animal cat = Animal("루미","고양이"); // 인스턴스화
// 생성자를 사용해 인스턴스화
print(cat.name) // "루미"
// 객체에는 함수와 데이터로 구성된 멤버가 있으며 접근하기 위해선 객체에 .을 통해 접근가능
print(cat.runtimeType) // Animal 객체 타입을 가져오는 방법
}
모든 클래스 변수는 암시적 getter 메서드를 생성합니다.
setter의 경우 final,const가 붙지 않은 경우 암시적으로 생성됩니다.
class Animal {
// 클래스 내에 변수 지정
String type;
String name;
final bool isAnimal;
late int? age; // ?를 통해 초기에 null이 들어가며 추후에 값이 추가됨을 표시
// 생성자
Animal({required this.name, required this.type, this.isAnimal = true});
// 선언적 get 사용방법 : 타입 get 함수이름 => 값
int? get getAge => age;
// 선언적 set 사용방법 : set 함수이름(파라미터) => 변경할 변수 = 값;
set setAge(int value) => age = value;
}
void main(List<String> args) {
Animal cat = Animal(name: "에옹이", type: "고양이", isAnimal: true);
// setter
cat.setAge = 10;
cat.age = 10;
// getter
print(cat.getAge);
print(cat.age);
}
class Animal {
// 클래스 내에 변수 지정
String type;
String name;
// 생성자 객체 형태로 인자를 받기
Animal({required this.name, required this.type});
// 명명된 생성자
Animal.origin(this.name, this.type);
Animal.origin2(getName,getType):
name = getName,
type = getType;
}
하위 생성자 실행순서
1. 초기화 목록
2. 슈퍼클래스의 인수가 없는 생성자
3. 기본클래스의 인수가 없는 생성자
Person을 상속한 Employee에서 수퍼 클래스 생성자 호출 하는 예제
class Person {
String? firstName;
Person.fromJson(Map data) {
print('in Person');
}
}
class Employee extends Person {
// Person does not have a default constructor;
// you must call super.fromJson().
Employee.fromJson(super.data) : super.fromJson() {
print('in Employee');
}
}
void main() {
var employee = Employee.fromJson({});
print(employee);
// Prints:
// in Person
// in Employee
// Instance of 'Employee'
}
class Point {
double x, y;
// 메인 생성자.
Point(this.x, this.y);
// 메인 생성자를 리디렉션 하는 생성자.
Point.alongXAxis(double x) : this(x, 0);
}
/// 상수 생성자
class ImmutablePoint {
// 컴파일 타임 상수
static const ImmutablePoint origin = ImmutablePoint(0, 0);
// 인스턴스 생성시 상수로 지정
final double x, y;
const ImmutablePoint(this.x, this.y);
}
팩토리 생성자는 this에 접근할 수 없습니다.
class Logger {
final String name;
bool mute = false;
// _cache is library-private, thanks to
// the _ in front of its name.
static final Map<String, Logger> _cache = <String, Logger>{};
factory Logger(String name) {
return _cache.putIfAbsent(name, () => Logger._internal(name));
}
factory Logger.fromJson(Map<String, Object> json) {
return Logger(json['name'].toString());
}
Logger._internal(this.name);
void log(String msg) {
if (!mute) print(msg);
}
}
추상 클래스는 추상 메서드를 가질 수 있는 클래스를 의미한다.
추상 메서드란? 선언은 되어 있지만 바디가 정의되지 않은 함수를 의미한다.
추상 클래스의 특징
abstract class Person {
//추상 클래스
eat(); // 추상 메서드 바디가 없다
Person();
sleep() {
// 일반 메서드
print("zzz...");
}
}
class Man implements Person {
@override // @override는 생략가능
eat() {
print("eat");
}
sleep() {
print("zzz...");
}
}
void main() {
Man man = Man();
man.eat(); // eat
man.sleep(); // zzz...
}
extends 키워드를 활용해 하위 클래스에서 상위 클래스를 상속하며,
super 키워드를 통해 상위 클래스를 참조하는데 사용합니다.
noSuchMethod 메소드를 활용해 존재하지 않는 메서드나 인스턴스 변수를 사용하려고 할 대마다 감지하거나 반응할 수 있습니다.
class Person {
eat() {
print("입으로 먹기");
}
sleep() {
print("zzz...");
}
String run(String where) {
var runString = "$where으로 달리기";
print(runString);
return runString;
}
}
class Man extends Person {
@override // @override는 생략가능
eat() {
super.eat();
print("eat");
}
@override
String run(String where) {
return super.run(where);
}
@override
// 선언하지 않은 메서드 또는 변수를 사용하는 경우
noSuchMethod(Invocation invocation) {
print("선언하지 않은 변수를 사용 : ${invocation.memberName}");
return super.noSuchMethod(invocation);
}
}
void main() {
Man man = Man();
man.eat(); // 입으로 먹기 , eat
man.sleep(); // zzz...
man.run("한강"); // 한강으로 달리기
}
단순 열거형 : enum enumName { 열거할 데이터들...} 앞에서부터 0,1,2 값을 가진다
향상된 열거형 : 상수 인스턴스의 고정된 수로 제한되는 필드,함수 및 const 생성자가 있는 클래스를 선언 가능
// 단순 열거형
enum Color { red, green, blue }
// 향상된 열거형
enum Vehicle {
car(tires: 4, passengers: 5, carbonPerKilometer: 400), // 각각의 Enum 인스턴스 하나이상의 인스턴스가 존재해야됌
bus(tires: 6, passengers: 50, carbonPerKilometer: 800),
bicycle(tires: 2, passengers: 1, carbonPerKilometer: 0);
const Vehicle({
// 생성자 const 타입의 생성자
required this.tires,
required this.passengers,
required this.carbonPerKilometer,
});
final int tires; // 인스턴스 변수
final int passengers;
final int carbonPerKilometer;
int get carbonFootprint => (carbonPerKilometer / passengers).round(); // 메소드
}
void main(List<String> args) {
print(Vehicle.car.carbonPerKilometer);
}
믹스인은 여러 클래스 계층에서 클래스 코드를 재사용 하는 방법입니다.
mixin 키워드를 활용해 클래스를 선언하면 인스턴스 변수는 늘리되 생성자는 생성하지 않는 클래스를 만듭니다.
class A {...}
class B {...}
class C {...}
class AWithBAndC extends A with B,C {
...
}
mixin Musical {
bool canSing = true;
}
class Person extends Musical{
...
}
void main(){
print(Person().canSing); // true
}
static 키워드를 활용해 정적 변수 및 메서드를 만들 수 있습니다.
정적 변수와 메서드는 인스턴스화를 하지 않아도 접근이 가능합니다.
class Queue {
static const initialCapacity = 16;
static func(){...}
// ···
}
void main() {
assert(Queue.initialCapacity == 16);
Queue.func();
}