Dart 객체지향 프로그래밍 (Object Oriented Programming)
- 클래스 정의는 설계서를 만드는 것이고, 클래스로 결과를 만들어 낸 것은 Instance라고 한다.
void main() {
Idol blackPink = new Idol(
'BlackPink',
['지수','제니','리사','로제'],
); // new 생략가능
print(blackPink.name);
print(blackPink.members);
blackPink.sayHello();
blackPink.introduce();
Idol bts = Idol(
'BTS',
['RM','정국','뷔','지민','제이홉','슈가','진'],
);
print(bts.name);
print(bts.members);
bts.sayHello();
bts.introduce();
}
class Idol {
String name;
List<String> members;
// constructor
Idol(String name, List<String> members)
: this.name = name,
this.members = members;
void sayHello() {
print("안녕하세요 ${this.name}입니다.");
}
void introduce() {
print("저희 멤버는 ${this.members}가 있습니다.");
}
}
- 위의 생성자를 자세히보자. 아래 두개 코드는 같은 의미이다. this로 바로 값을 받아 넣을 수 있다.
Idol(String name, List<String> members)
: this.name = name,
this.members = members;
// constructor
Idol(this.name, this.members);
- 아래와 같이 named Constructor로도 선언할 수 있다.
// named constructor
Idol.fromList(List values)
: this.members = values[0],
this.name = values[1];
// named constructor 사용
Idol bts = Idol.fromList(
[
['RM','정국','뷔','지민','제이홉','슈가','진'],
'BTS',
]
);
- final로 한번 선언 이후 값을 바꿀 수 없도록 할 수 있다.
- 대부분의 상황에서 클래스의 변수를 final로 선언하는 습관을 들이자.
final String name;
- Instance 선언 시, 아래와 같이 비교하는 둘을 const로 선언하면 같은 인스턴스가 된다. (== 이 true)
// constructor
const Idol(this.name, this.members);
Idol blackPink = const Idol(
'BlackPink',
['지수','제니','리사','로제'],
);
Idol blackPink2 = const Idol(
'BlackPink',
['지수','제니','리사','로제'],
);
print(blackPink == blackPink2);
// getter
String get firstMember {
return this.members[0];
}
// setter
set firstMember(String name) {
this.members[0] = name;
}
print(blackPink.firstMember); // getter 사용 예시
blackPink.firstMember = "쩡이"; //setter 사용 예시
- private 선언을 위해서는 이름 앞에 _를 붙여준다. private은 같은 파일 내에서만 _를 사용할 수 있다.
- 상속을 받으면 부모 클래스의 모든 속성을 자식 클래스가 부여받는다.
void main() {
print('------ Idol ------');
Idol apink = Idol(name: '에이핑크', membersCount:5);
apink.sayName();
apink.sayMembersCount();
}
class Idol{
String name;
int membersCount;
Idol({
required this.name,
required this.membersCount,
});
void sayName(){
print('저는 ${this.name} 입니다.');
}
void sayMembersCount() {
print('${this.name}은 ${this.membersCount}명의 멤버가 있습니다.');
}
}
//output:
// ------ Idol ------
// 저는 에이핑크 입니다.
// 에이핑크은 5명의 멤버가 있습니다.
class BoyGroup extends Idol {
BoyGroup(
String name,
int membersCount,
) : super(name: name,
membersCount: membersCount,
); // idol class의 constructor에 전달
}
BoyGroup bts = BoyGroup("bts",7);
bts.sayName();
bts.sayMembersCount();
- 상속을 받으면 부모 클래스의 모든 속성을 자식 클래스가 부여받는다.
- @override는 같은 이름 기능을 재정의한다.
void main() {
TimesTwo tt = TimesTwo(2);
print(tt.calculate());
TimesFour tf = TimesFour(2);
print(tf.calculate());
}
class TimesTwo{
final int number;
TimesTwo(
this.number,
);
int calculate() {
return number * 2;
}
}
class TimesFour extends TimesTwo{
TimesFour(
int number,
) : super(number);
@override
int calculate() {
//return number * 4; // super.number
return super.calculate() * 2;
}
}
- static은 instance에 귀속되지 않고 class에 귀속된다.
void main() {
Employee seulgi = Employee('슬기');
Employee chorong = Employee('초롱');
// Instance에 귀속
seulgi.name = '쩡이';
seulgi.printNameAndBuilding();
chorong.printNameAndBuilding();
// class에 귀속
Employee.building = '오투타워';
}
class Employee {
static String? building;
String name;
Employee(
this.name,
);
void printNameAndBuilding(){
print('제 이름은 $name입니다. $building 건물에서 근무하고 있습니다.');
}
static void printBuilding() {
print('저는 $building 건물에서 근무중입니다. ');
}
}
void main() {
BoyGroup bts = BoyGroup('BTS');
bts.sayName();
}
// interface
class IdolInteraface {
String name;
IdolInteraface(this.name);
void sayName() {}
}
class BoyGroup implements IdolInteraface {
String name;
BoyGroup(this.name);
void sayName() {
print('제 이름은 $name 입니다.');
}
}
void main() {
Lecture<String, String> lecture1 = Lecture('123', 'lecture1');
lecture1.printIdType();
Lecture<int, String> lecture2 = Lecture(123, 'lecture2');
lecture2.printIdType();
}
class Lecture<T, X> {
final T id;
final X name;
Lecture(this.id, this.name);
void printIdType() {
print(id.runtimeType);
}
}