[Dart] Class ์ด ์ ๋ฆฌ (์์ / ์ฌ์ ์ / ์ถ์ํ)
Instance ๊ด์ ์์ Class, Singleton, Static ์์๋ณด๊ธฐ
Singleton Pattern(์ฑ๊ธํค ํจํด) ?
Factory Pattern(ํฉํ ๋ฆฌ ํจํด) ?
copyWith์ NULL ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
์ด๋ฒ ๊ธ์์๋ Flutter&Dart Class์ ๋ํ ๋ด์ฉ์ ๋ค๋ค๋ณด๋๋ก ํ๊ฒ ๋ค.
๋จผ์ Flutter๋ Dart์ธ์ด๋ฅผ ์ฌ์ฉํด ๊ฐ๋ฐ๋ FrameWork์ด๋ฉฐ, Flutter FrameWork์์๋ Dart๋ฅผ ์ฌ์ฉํด ๊ฐ๋ฐ๋์ด ์ง๊ณ ์๋ค.
Dart ์ธ์ด์์๋ ๋ชจ๋ ๊ฒ์ด ๊ฐ์ฒด(object)์ด๋ค.
Dart๋ ํด๋์ค(class)์ Mixin๊ธฐ๋ฐ์ ์์์ ์ง์ํ๋ ์์ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด(Super OOP)์ด๋ฉฐ, ๋ชจ๋ ๊ฐ์ฒด๋ ํด๋์ค(class)์ ์ธ์คํด์ค(instance)์ด๊ณ , NULL์ ์ ์ธํ ๋ชจ๋ class๋ Object์์ ๋น๋กฏ๋๋ค.
Mixin ๊ธฐ๋ฐ ์์์ ๋ชจ๋ ํด๋์ค(class)๊ฐ ํ๋์ ๊ฐ์ฒด(Object)๋ฅผ ๊ฐ์ง๊ณ ์์ง๋ง, ํด๋์ค(class)์ ๋ฐ๋๋ ๋ค์ํ ํด๋์ค(class) ๊ณ์ธต์์ ์ฌ์ฌ์ฉ ๋ ์ ์์์ ์๋ฏธํ๋ค๊ณ ๊ณต์ ๋ฌธ์์์ ์ค๋ช
ํ๊ณ ์๋ค.
" Dart is an object-oriented language with classes and mixin-based inheritance. Every object is an instance of a class, and all classes except Null descend from Object. Mixin-based inheritance means that although every class (except for the top class, Object?) has exactly one superclass, a class body can be reused in multiple class hierarchies. Extension methods are a way to add functionality to a class without changing the class or creating a subclass. Class modifiers allow you to control how libraries can subtype a class. "
์์ ์ค๋ช ์ด ์ ์ดํด๋์ง ์์ ์๋ ์๋ค. ์ดํด๊ฐ ์๋๋๋ผ๋ ์ฒ์ฒํ ์์ฃผ ๊ฐ๋ฐ์ ํ๋ค๋ณด๋ฉด ์์ฐ์ค๋ฝ๊ฒ ๊ฐ๋ ์ ์ต๋ํ ์ ์์ผ๋ ํฌ๊ฒ ๊ฑฑ์ ํ์ง ์์๋ ๋๊ณ , ์ธ์ธ ํ์๋ ์๋ค.
Dart Class๋ฅผ ๋ค๋ฃจ๊ธฐ ์ํด์ 4๊ฐ์ง ํค์๋๋ฅผ ์๊ณ ์์ด์ผ ํ๋ค.
- object
- class
- constructor
- instance
ํด๋์ค(class)์ ๋ํด์ ์์ธํ ๋ค๋ฃจ๋ฉด์ ์ถ๊ฐ์ ์ผ๋ก ์ค๋ช ํ ์์ ์ด๊ณ , ์ฐ์ ๊ฐ๋ ์ ๋๋ง ์๊ณ ์๋๋ก ํ์.
์ ์๋์ฐจ๋ฅผ ๋ง๋๋ ๊ณต์ฅ์ด๋ผ๊ณ ๊ฐ์ ํด๋ณด์.
์๋์ฐจ๋ ์ ๋ง๊ฐ์ง ๋ถํ์ ์กฐํฉ์ผ๋ก ๋ง๋ค์ด ์ง๋ค. ๋ง๋๋ ๊ฒ ์ธ์๋ ์ถ๊ณ ์ ํ
์คํธ ๊ณผ์ ๋ ๊ฑฐ์ณ์ผ ํ๋ค.
์ด๋ ๊ฒ ๋ณต์กํ ๊ตฌ์กฐ์ ์๋์ฐจ๊ฐ ๋จ ํ๋์ ๊ตฌ์กฐ๋ก ์ด๋ค์ง์ง ์๊ณ , ๋ด๋ถ์ ์ผ๋ก ์ข
๋ฅ๋ ๋ค์ํ๊ฒ ์กด์ฌํ๋ค.
๊ณต์ฅ์์๋ ๋ค์ํ ์ข
๋ฅ์ ์๋์ฐจ๋ฅผ ์์ฐํ๊ธฐ ์ํ ์์ฐํ๋ฅผ ๊ณตํตํ๋ ๊ธฐ์ค์ผ๋ก ๊ด๋ฆฌ๋ฅผ ํด์ผ ํ๋๋ฐ, ๋ถํ ์ข
๋ฅ ๋ฐ ์ฌ์ฉ๋๋ ๋ถํ ๊ฐฏ์, ํ
์คํธ ๊ณผ์ ๋ฑ์ ์งํฉ์ฒด๋ฅผ ๊ฐ์ฒด(object)๋ผ๊ณ ๋ณผ ์ ์์ผ๋ฉฐ, ์๋์ฐจ๋ฅผ ์์ฐํ๊ธฐ ์ํ ์ค๊ณ๋๊ฐ ํด๋์ค(class)์ ํด๋น ๋๋ค.
์ค๊ณ๋๋ ์์ฑ(attribute)๊ณผ ๋์(behavior)์ ๊ตฌ์ฑํ ์ ์๋๋ฐ, ์์ฑ์ ๋ฉค๋ฒ๋ณ์(member variable), ๋์์ ๋ฉ์๋(method)๋ก ํํ ๋๋ค.
์๋์ฐจ๊ฐ ์์ฐ ๋๊ธฐ ์ํด ์ปจ๋ฒ ์ด์ด ๋ฒจํธ์ ์ฌ๋ผ๊ฐ๊ธฐ ์ํด์๋ ์ค๊ณ๋์ ์์ฑ์ ์ด๊ธฐํํ๋ ๊ณผ์ ์ ๊ฑฐ์ณ์ผ ํ๋๋ฐ, ์ด ๋ ์์ฑ์๋ฅผ ์ฌ์ฉํด ์ด๊ธฐํ๋ฅผ ํ ์ ์๋ค. ์์ฑ์๊ฐ ๋ฐ๋ก constructor ์ด๋ค.
ํด๋์ค(class)๋ฅผ ํตํด ๋ง๋ค์ด์ง ๊ฐ์ฒด๋ฅผ ์ธ์คํด์ค(instance)๋ผ๊ณ ํ๋ค.
ํํ ์ธ์คํด์คํ๋ผ๊ณ ํ๋ ์๋ฏธ๊ฐ ๋ฐ๋ก ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ ค์ง๋ ์๊ฐ์ ์๋ฏธํ๋ค.
์ ์ ํ ์์์ธ์ง๋ ๋ชจ๋ฅด๊ฒ ์ง๋ง, ๊ฐ๋ณ๊ฒ๋ง ๋ณด๊ณ class๋ฅผ ๋ง๋ค๊ณ ๋ค๋ฃจ๋ฉด์ ๊ฐ๋ ์ ๋ ์ ํํ ์ตํ๋ณด๋๋ก ํ์.
๊ธ์ ์์ฃผ ๊ฒ์ํ์ง๋ง ํญ์ ๋๋ผ๋๊ฒ ๊ธ๋ก๋ง ์ค๋ช ํ๋ค๋ ๊ฒ์ ์ฐธ ํ๋ ๊ฒ ๊ฐ๋ค ...
์ด์ ํด๋์ค(class)๋ฅผ ์์ฑํ๊ณ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ์ฝ๋๋ฅผ ํตํด ์์๋ณด๋๋ก ํ์.
๊ธฐ๋ณธ์ ์ธ ํด๋์ค(class) ๊ตฌ์กฐ์ด๋ค.
ํด๋์ค(class)๋ ๋ฉค๋ฒ ๋ณ์์ ๋ฉค๋ฒ ํจ์๋ฅผ ๊ฐ์ง ์ ์์ผ๋ฉฐ, ํด๋์ค ๋ช ์ ์ ํ ๋์๋ ์ฒซ ๊ธ์๋ฅผ ๋๋ฌธ์๋ก ์์ํ๋ PascalCase ํ๊ธฐ๋ฒ์ ๊ธฐ์ค์ผ๋ก ์ฌ์ฉํด์ผ ํ๋ค.
class Person {
String name = "tyger";
}
ํด๋์ค(class)๋ฅผ ์ฌ์ฉํด ๋ณด๋๋ก ํ์.
Person ํด๋์ค๋ฅผ tyger๋ผ๋ ๋ณ์๋ก ๋ง๋ค์ด ์ฃผ๊ณ , ํด๋น object(๊ฐ์ฒด)๊ฐ ์ฌ์ฉ ๋์ด์ง ๋์ instance ๋๋ค.
(์ธ์คํด์ค)instance๋ ๋ฉ๋ชจ๋ฆฌ์ ํ ๋น ๋์ด์ง๋ ๊ฒ์ ์๋ฏธํ๋ค.
void main() {
Person tyger = Person();
print(tyger.name);
// tyger
}
์ธ์คํด์ค(instance)๋ ๋ญ๊น ?
" ์ธ์คํด์ค๋ Class๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์ฑ๋๋ฉฐ, Class์ ๊ธฐ๋ฅ๊ณผ ์์ฑ์ ๋์ผํ๊ฒ ๊ฐ์ง๊ณ ์๋ ํ๋ก๊ทธ๋๋ฐ ์์์ ์ฌ์ฉ๋๋ ๋์์ด๋ค. "
์ธ์คํด์ค(instance)๋ ํด๋์ค(class)๊ฐ Object(๊ฐ์ฒด)๋ก ์ ์ธ๋๊ณ , ์ ์ธ๋์ด์ง Object(๊ฐ์ฒด)๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ํ ๋น ๋์ด ์ค์ ์ฌ์ฉ๋ ๋๊ฐ ๋ฐ๋ก ์ธ์คํด์ค(instance)์ด๋ค.
์ฆ, Object(๊ฐ์ฒด)๋ฅผ ์ค์ฒดํํ ๊ฐ๋ ์ด๋ค
๐ฅ Instance ๊ด์ ์์ Class, Singleton, Static ์์๋ณด๊ธฐ
์๋์์ ํด๋์ค(class)์ ๊ธฐ๋ฅ๋ค์ ์ดํด๋ณด๋ฉด์, ์ธ์คํด์ค(instance)์ ๋ํ ๋ถ๋ถ์ ๊ณ์ํด์ ์ค๋ช ํ ์์ ์ด๋, ๊ฐ๋ ์ ๋๋ง ์๊ณ ์์ผ๋ฉด ๋๋ค.
์์ธํ๊ฒ ์๊ณ ์ถ๋ค๋ฉด ๊ณต์ ํ ๊ธ์ ์ฐธ๊ณ ํ์๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค.
Class์ ๊ธฐ๋ณธ ๊ตฌ์กฐ์ ๋ํด์๋ ์์ ๋ดค์ผ๋, ์ด๋ฒ์ constructor์ ๋ํด์ ์์๋ณด๋๋ก ํ์.
Constructor๋ ์์ฑ์๋ผ๊ณ ํ๋ค. ๊ทธ๋ ๋ค๋ฉด ์์ฑ์๋ ๋ฌด์์ผ๊น ?
ํด๋์ค(class)๋ ์์ฑ์๋ฅผ ๊ฐ์ง ์ ์๊ณ , ํ ๊ฐ์ ์์ฑ์ ๋ฟ๋ง ์๋๋ผ ์ฌ๋ฌ ๊ฐ์ ์์ฑ์๋ ๊ฐ๋ฅํ๋ค.
์์ฑ์๋ " ๊ฐ์ฒด๊ฐ ์์ฑ๋ ๋์ ํธ์ถ๋๋ '์ธ์คํด์ค ์ด๊ธฐํ ๋ฉ์๋' "์ด๋ค.
๋จผ์ , ์์ฑ์(constructor)์ ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ฅผ ์ดํด๋ณด์.
์ฒ์์ class์ ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ฅผ ๋ฐฐ์ธ ๋์ ํด๋์ค ๋ด๋ถ์ ๋ณ์์ ์ด๊ธฐ ๊ฐ์ ์์ฑํ์ฌ ๋ง๋ค์์๋ค.
์ด๋ฒ์๋ ์ด๊ธฐ ๊ฐ ์์ด constructor(์์ฑ์)๋ฅผ ํตํด ํด๋์ค๋ฅผ ๋ง๋ค์ด ์คฌ๋ค.
์ด ๋์ ์ฐจ์ด์ ์ ๋ญ๊น ? ์ ์์ฑ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ผ๊น ?
class Person {
final String name;
const Person(this.name);
}
์์ฑ์๊ฐ ์๋ค๋ฉด, ํด๋์ค๋ฅผ ๊ฐ์ฒด๋ก ์ธ์คํด์คํ ๋์ ์ด๊ธฐ ๊ฐ์ ๋ค๋ฅด๊ฒ ์ค ์๊ฐ ์๋ค.
์๋ฅผ ๋ค์ด, tyger์ alice๋ผ๋ ๋ ๊ฐ์ Person ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ค๊ณ ๊ฐ์ ํด ๋ณด์. ์์ฑ์๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉด ๊ฐ์ฒด๋ก ์์ฑํ ํ์ person.name์ ์ ๊ทผํ์ฌ ๊ฐ์ ๋ณ๊ฒฝํด ์ฃผ์ด์ผ ํ๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์์ฑ์๋ฅผ ์ฌ์ฉํ์ฌ ํด๋์ค๋ฅผ ์ด๊ธฐํํ์ฌ ์ฌ์ฉํด์ผ ํ๋ค.
void main() {
Person tyger = Person("tyger");
print(tyger.name);
// tyger
}
Default Constructor
class์์ ์์ฑ์๋ฅผ ์ ์ธํ์ง ์์ผ๋ฉด ๊ธฐ๋ณธ ์ฌ์ฉ์๊ฐ ์์ฑ๋๋ค๊ณ ํ๋ค.
๊ธฐ๋ณธ ์์ฑ์์ ํํ์ด๋ค. ์์ฑ์๋ ํด๋์ค๋ช ๊ณผ ๋์ผํ ์ด๋ฆ์ ๊ธฐ๋ณธ ์์ฑ์๋ก ์ฌ์ฉํ ์ ์๋ค.
Person ํด๋์ค๋ฅผ ์ธ์คํด์คํ ๋์ name, age ๋ณ์๋ฅผ ์์๋๋ก ์ ๋ฌํ์ฌ ์์ฑํ ์ ์๋ค.
์์ฑ์์์ ๋ณ์์ ์์๋๋ก ๊ผญ ๋ฃ์ ํ์๋ ์๋ค. ์ธ์คํด์คํ ๋์๋ง ์์ฑ์์์ ์ ์ํ ์์๋๋ก ๋ณ์๋ฅผ ํ ๋นํด์ฃผ๋ฉด ๋๋ค.
class Person {
final String name;
final int age;
const Person(this.name, this.age);
}
// Person("tyger", 100);
์์ ์์ฑ์๋ ๋ณ์ ์ด๋ฆ์ ์ฌ์ฉํ์ง ์์ ๋ณ์๊ฐ ๋ง์์ง๋ค๋ฉด ์์๊ฐ ํท๊ฐ๋ฆฌ๊ฒ ๋๊ธฐ ๋๋ฌธ์ "Named"๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
์์ฑ์๋ ํจ์๋ฅผ ์์ฑํ ๋์๋ Argument๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด ์์ฃผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ ์ด๋ฏ๋ก ์ต์ํ ๋ด์ฉ์ผ ๋ฏ ํ๋ค.
Named๋ก ์์ฑ์(constructor)๋ฅผ ์ ์ธํ ๊ฒฝ์ฐ ๋ฐ๋์ ์ค๊ดํธ "{}" ์์์ ๋ฑ๋กํด์ผ ํ๋ฉฐ, ํ์๋ก ์ ๋ฌ ๋ฐ์ ํ๋ผ๋ฏธํฐ๋ผ๋ฉด required ํค์๋๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
class Person {
final String name;
final int age;
const Person({
required this.name,
required this.age,
});
}
// Person(name: "tyger", age: 100);
ํผํฉํด์ ์ฌ์ฉํ ์๋ ์๋ค.
class Person {
final String name;
final int age;
const Person(
this.name, {
required this.age,
});
}
// Person("tyger", age: 100);
Named Constructor
์ด๋ฒ์๋ ์ด๋ฆ์๋ ์์ฑ์๋ฅผ ๋ง๋ค์ด ๋ณด๋๋ก ํ์.
์์์ Default Constructor์ ๋ํ ๋ด์ฉ์ ๋ค๋ฃฐ ๋์ ์์ฑ์๋ ํด๋์ค์ ์ด๋ฆ๊ณผ ๋์ผํ๊ฒ ๊ธฐ๋ณธ ์์ฑ์๋ก ์ฌ์ฉ๋๋ค๊ณ ํ์๋ค.
์ด๋ฆ์ด ์๋ ์์ฑ์๋ก๋ ๋ง๋ค์ด ์ค ์ ์์ผ๋ฉฐ, ์์ฑ ๊ท์น์ ํด๋์ค๋ช ์ ์ฉ(.)์ ์ ๋ ฅํ๊ณ ์ํ๋ ์์ฑ์ ๋ช ์ CamelCase ํ๊ธฐ๋ฒ์ผ๋ก ์์ฑํด์ฃผ๋ฉด ๋๋ค.
" ์์ฑ์๋ ํ ๊ฐ๊ฐ ์๋ ์ฌ๋ฌ ๊ฐ์ ์์ฑ์๋ฅผ ์์ ๋กญ๊ฒ ์ถ๊ฐํ์ฌ ์ฌ์ฉํ ์ ์๋ค. "
class Person {
final String name;
final int age;
// Default
const Person(this.name, this.age);
// Named
const Person.init(this.name, this.age);
}
// Person.init("tyger", 100);
์์ฑ์๋ ์ด๋ฏธ ์ต์ํ ๋ด์ฉ์ด๋ผ class์ ๋ค๋ฅธ ๋ด์ฉ ๋ค์ ๋ค๋ฃจ๋ฉด์ ๋ ์ตํ๋ณด๋๋ก ํ์.
์์์ ํด๋์ค๋ฅผ ์ค๋ช ํ ๋์ " class๋ ์์ฑ(attribute)๊ณผ ๋์(behavior)์ ๊ตฌ์ฑํ ์ ์๋๋ฐ, ์์ฑ์ ๋ฉค๋ฒ๋ณ์(member variable), ๋์์ ๋ฉ์๋(method)๋ก ํํ ๋๋ค. " ๋ผ๊ณ ํ์๋ค.
์์ฑ๊ณผ ๋์์ ๋ํด์ ์ดํด๋ณด๋๋ก ํ์.
Method
๋ณ์๋ฅผ ๋ค๋ฃจ๊ธฐ ์์ ๋์๊ณผ ๊ด๋ จ๋ ํด๋์ค ๋ด๋ถ ํจ์์ ๋ํด์ ๊ฐ๋จํ๊ฒ ์ดํด๋ณด์.
ํด๋์ค๋ ๋ด๋ถ์ Method๋ฅผ ๊ตฌ์ฑํ ์ ์์ผ๋ฉฐ, Instance Method์ Static Method๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
class Person {
final String name;
const Person(this.name);
void printName() {
print("My name is ${this.name}");
}
String returnName() => this.name;
}
Person ํด๋์ค๋ฅผ ์ธ์คํด์คํ ํ์ ๋ด๋ถ ํจ์์ ์ ๊ทผํ์ฌ ํธ์ถํด ์ฃผ๋ฉด ๋๋ค.
void main() {
Person tyger = Person("Tyger");
tyger.printName();
// My name is Tyger
print(tyger.returnName());
// Tyger
}
์ถ๊ฐ๋ก ์ ์ ๋ฉ์๋๋ ์ฌ์ฉํ ์ ์๋ค.
class Person {
final String name;
const Person(this.name);
static void test(){
print("Static Mehtod");
}
}
// Person.test();
// Static Mehtod
Member Variable
" ํด๋น ๊ธ์ ํด๋์ค(class)์ ๊ดํ ๋ด์ฉ์ผ๋ก ๋ณ์์ ํ์ ๋ฑ์ ๊ดํ ๋ด์ฉ์ ์ฌ๊ธฐ์ ๋ค๋ฃจ์ง ์์ "
์์ฑ์ ํด๋นํ๋ ๋ฉค๋ฒ๋ณ์(MemberVaribale)์ ๋ํด์ ์์๋ณด์.
๋ฉค๋ฒ ๋ณ์์๋ ๋ฉ์๋์ ๋์ผํ๊ฒ Instance Varibale์ Static Varibale์ด ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
์์์ ์ด๋ฆ์ ์ฌ์ฉํ๊ธฐ ์ํ name ๋ณ์๋ฅผ ์์ฑ ํ์๋ค. name์ ํด๋นํ๋ class์ ์์ฑ์ ๋ณ์(Varibale)๋ผ๊ณ ํ๋ค.
์๋ ์ฝ๋๋ฅผ ๋ณด๋ฉด Person ํด๋์ค์ ๋ณ์๋ฅผ ์์ฑํ ๋์ name์ ๊ธฐ๋ณธ ๊ฐ์ ์ง์ ํ์ง ์๊ณ ์์ฑํ ๋ณ์์ด๊ณ , age๋ ๊ธฐ๋ณธ ๊ฐ์ 100์ผ๋ก ์ฃผ์๊ธฐ์ ์์ฑ์๋ฅผ ํตํ ์ด๊ธฐํ ๋ณ์์ ๋ฑ๋กํ์ง ์์๋ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
class Person {
final String name;
int age = 100;
Person(this.name);
}
ํด๋์ค(class)์ ๊ธฐ๋ณธ์ ์ธ ๊ตฌ์ฑ ์์ ๋ฐ ์ฌ์ฉ ๋ฐฉ๋ฒ์ ๊ฐ๋จํ๊ฒ ์์๋ดค๋ค.
์๋ ํด๋์ค(class)์ ๋ํด์ ๋ฐฐ์ธ ๋์๋ ํด๋์ค์ ๊ตฌ์ฑ ์์๋ฅผ ๋ฐฐ์ฐ๊ณ , ์ผ๋ฐ์ ์ผ๋ก๋ ์์์ ๋ํด์ ๋ฐฐ์ฐ๊ฒ ๋๋ค. ํ์ง๋ง ์์์ ๋ฐฐ์ฐ๊ธฐ ์์ ์ถ์ ํด๋์ค์ ๋ํด์ ๋จผ์ ๋ฐฐ์ฐ๊ณ ๊ฐ๋๋ก ํ๊ฒ ๋ค.
์ Abstract Class(์ถ์ ํด๋์ค)๋ฅผ ๋จผ์ ๋ฐฐ์์ผ ํ๋์ง์ ๋ํด์ ์ค๋ช
ํ์๋ฉด, ์์์ ๋ํ ๊ฐ๋
์ ๋ฐฐ์ธ ๋์ ๋ฐ๋์ ์๊ณ ์์ด์ผ ํ๋ ์ฌ์ ์ง์ ์ค ํ๋๊ฐ ๋ฐ๋ก ์ถ์ ํด๋์ค๋ผ๊ณ ์๊ฐํด์ ์ด๋ค.
๊ฐ์ธ์ ์ผ๋ก ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ฅผ ์ ํ์ ๋์ ์ถ์ ํด๋์ค์ ๊ฐ๋
์ด ์ดํด๊ฐ ๊ฐ์ง ์๊ณ , ์์์์ ์ถ์ ํด๋์ค๊ฐ ํ๋ ์ญํ ์ ๋ํด์ ๋ฉ๋์ด ๋์ง ์์์๋ค.
์๊ณ ๋ณด๋ฉด ์ด๋ ต์ง๋ ์๊ณ , ๊ฐ๋จํ ๊ฐ๋
์ด๋ ๋น ๋ฅด๊ฒ ์ดํด๋ณด๋๋ก ํ์ !
๊ทธ๋ ๋ค๋ฉด ์ถ์(abstract) ํด๋์ค๋ ๋ญ ํ๋ ๊ฑธ๊น ?
"์ถ์ ํด๋์ค๋ ์ฝ๋๋ฅผ ์ ์งํ๊ฒ ์ ์งํ๊ณ ์ ํ์ ์์ ํ๊ฒ ์ ์งํฉ๋๋ค. ๋ชจ๋ ๊ตฌํ ํ์ ํด๋์ค๊ฐ ์ถ์ ํด๋์ค๊ฐ ์ ์ํ๋ ๋ชจ๋ ์์ฑ๊ณผ ๋ฉ์๋๋ฅผ ์ ์ํ๋๋ก ๋ณด์ฅ ํ์ง๋ง ๊ตฌํ์ ๊ฐ ํ์ ํด๋์ค์ ๋งก๊น๋๋ค."
- ์ถ์ ๋ฉ์๋๋ฅผ ํฌํจํ๋ ํด๋์ค
- ์ธ์คํด์ค(instance)ํ ์ ์๋ ํด๋์ค
- ์ถ์ ๋ฉ์๋๋ ์ ์ธ๋ง ๋๊ณ ์ ์๋ ์๋ ๋ฉ์๋
์ธ์คํด์ค(instance)ํ ์ ์๋ ํด๋์ค๋ผ๋ ์๋ฏธ์ ๋ํด์๋ ์ด๋ฏธ ์์์ ์ธ์คํด์ค์ ๋ํด์ ์ดํด ๋ดค๊ธฐ ๋๋ฌธ์, ๋ฌด์จ ์๋ฏธ์ธ์ง ์๊ณ ์์ ๊ฒ์ด๋ค.
์ถ์ ํด๋์ค๋ก ์์ฑ์ด ๋๋ฉด, ๊ฐ์ฒด๋ก ์ธ์คํด์คํ ํ ์ ์๋ค๋ ๊ฒ์ด๋ค.
์ถ์ ํด๋์ค๋ฅผ ๋ง๋ ๋ ๋ฐฉ๋ฒ์ ๊ฐ๋จํ๋ค. ๋ฐ๋ก abstract ํค์๋๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
์ด์ Person ํด๋์ค๋ ์ถ์ ํด๋์ค๋ก ์ ์ธ ๋ฌ๊ธฐ ๋๋ฌธ์, ์ธ์คํด์คํ ์ ์์ด ๋จ๋ ์ ์ผ๋ก ์ฌ์ฉ์ด ๋ถ๊ฐ๋ฅํ๊ฒ ๋์๋ค.
abstract class Person {}
๋จ๋ ์ ์ผ๋ก ์ฌ์ฉ์ด ๋ถ๊ฐ๋ฅ ํ๊ณ ์ธ์คํด์คํ ์ ์๋ค๋ฉด ์ ์ฌ์ฉํ๋ ๊ฑธ๊น ?
์ถ์(abstract) ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ ๋ชฉ์ ์ ๋ํด์ ์์๋ณด์.
์ถ์ ํด๋์ค๋ฅผ ์ฌ์ฉํ์ฌ ํ์ ํด๋์ค์์ ๊ณตํต๋ ํน์ง๊ณผ ๋์์ ์ถ์ํํ์ฌ, ๊ฐ์ ํ ์ ์์ผ๋ฉฐ ๋คํ์ฑ(polymorphism) ๋ฐ ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ์ ๋ํ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉ์ด ๋๋ค.
Person ํด๋์ค๋ฅผ introduce() ๋ฉ์๋๋ฅผ ์ถ๊ฐํ ์ถ์(abstract) ํด๋์ค๋ก ์์ฑํ์๋ค.
introduce() ๋ฉ์๋๋ฅผ ๋ณด๋ฉด ์ ์ธ์ ๋์์ง๋ง ์ ์๋ ์๋ ๊ฒ์ ์ ์ ์๋ค.
์ด์ Person ์ถ์ ํด๋์ค๋ฅผ ์ฌ์ฉํ๊ณ ์ ํ๋ ํ์ ํด๋์ค์์ ์ ์ ๋ถ๋ถ์ ๊ตฌํํ๋ฉด ๋๋ค.
abstract class Person {
void introduce();
}
์ถ์(abstract) ํด๋์ค์ ๋ํด์๋ ์ด ์ ๋๋ง ์๊ณ ์์ผ๋ฉด, ์์์ ๋ฐฐ์ฐ๋ ๋ฐ๋ ๋ฌธ์ ๊ฐ ์์ ๊ฒ ๊ฐ๋ค.
์ด์ ์ด์ด์ class์ ์์์ ๋ํด์ ์ดํด๋ณด๋๋ก ํ๊ฒ ๋ค.
๋จผ์ ์์์ ์ ํ์ํ ๊น ?
Flutter์์ ์ฌ์ฉ๋๋ Dart ์ธ์ด๋ ์์์ ์ค๋ช ํ๋ฐ๋ก ๊ฐ์ฒด ์งํฅ ์ธ์ด์ด๋ค.
๊ฐ์ฒด ์งํฅ ์ธ์ด์์์ ์์์ ์ ๋ง ์ค์ํ ๊ฐ๋ ์ด๋ฉฐ, ์์์ ํตํด ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ๊ณผ ๊ตฌ์กฐํ, ๋ชจ๋ํ ๋ฐ ํ์ฅ์ฑ์ ๋ํ์ฃผ๊ธฐ ๋๋ฌธ์ด๋ค.
๋ถ๋ชจ๋์ ์ฌ์ฐ์ ์์์๊ฒ ๋ฌผ๋ ค์ฃผ๋ ๊ฒ์ ์์์ด๋ผ๊ณ ํ๋ค. Dart์์๋ ๋์ผํ ๊ฐ๋ ์ด๋ค. ์ฆ, ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ ์์๋ฅผ ์์ ํด๋์ค(์๋ธํด๋์ค)์์ ์ฌ์ฉํ ์ ์๋๋ก ํ๋ค๋ ๊ฒ์ด๋ค.
์๋ฅผ ๋ค์ด, ์๋์ฐจ์ ์ฌ๋ฌ ๋ชจ๋ธ์ ๋ํด์ ์ค๋ช ํ๋ ๊ธฐ๋ฅ์ ๋ง๋ ๋ค๊ณ ๊ฐ์ ํ์. ์๋์ฐจ์ ๋ชจ๋ธ์ ๊ฐ๊ธฐ ๋ค๋ฅธ ์คํ์ ๊ฐ์ง๊ณ ์๊ฒ ์ง๋ง, ์๋์ฐจ๋ผ๋ ๊ด์ ์์๋ ์๋์ฐจ ์์ฒด๊ฐ ๊ฐ์ง๊ณ ์๋ ๊ณ ์ ์์ฑ์ ๋ชจ๋ ๋์ผํ ๊ฒ์ด๋ค.
์๋์ฐจ์ ๋ชจ๋ธ๋ณ ์ถ๋ ฅ๊ณผ ๋ง๋ ฅ ์ธ์๋ ๋ง์ ์คํ์์๋ ์ฐจ์ด๊ฐ ์์ ๊ฒ์ด์ง๋ง, ์๋์ฐจ๋ผ๋ ๊ฒ์ ๋ชฉ์ ์๋ ๋ชจ๋ ๋์ผํ ์์ฑ์ ๊ฐ์ง๊ฒ ๋๋ค. ๋ฐํด๊ฐ 4๊ฐ ๋ผ๋์ง, ์ถ๋ ฅ ๋๋ ํ ํฌ๋ผ๋ ๊ฐ์ ๊ฐ์ง๊ณ ์๋์ง .. ๋ฑ๋ฑ
์ด๋ฐ ๋ถ๋ถ์ ๊ณตํต์ ์ผ๋ก ์ฌ์ฉํ ์ ์๋๋ก ์๋์ฐจ์ ์์ฑ์ ๋ด๊ณ ์๋ Car๋ผ๋ ํด๋์ค๋ฅผ ์์ฑํด, ๊ฐ ์๋์ฐจ ๋ชจ๋ธ๋ณ Car ํด๋์ค๋ฅผ ์์ ๋ฐ๊ฒ ํ๋ฉด ๊ณตํต์ ์ธ ์์ฑ์ ๋ํด ๋ฐ๋ณต์ ์ผ๋ก ์ฝ๋๋ฅผ ์์ฑํ ํ์๊ฐ ์์ด ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ๋ ๋์์ง๊ณ , ๋ชจ๋ํ๋ฅผ ํ์ฌ ๊ด๋ฆฌํ ์ ์๊ฒ ๋๋ค.
Flutter์์ ์์ ๋ฐฉ๋ฒ์ ์ผ๋ฐ์ ์ผ๋ก extends, implements, mixin ์ด๋ ๊ฒ 3๊ฐ์ง์ ํค์๋๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
์ธ ๊ฐ์ง ๋ฐฉ๋ฒ ๋ชจ๋ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)๋ฅผ ์์๋ฐ์ ์์ ํด๋์ค(์๋ธํด๋์ค)๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ด์ง๋ง, ์ฐจ์ด๊ฐ ์์ผ๋ ๊ฐ ์ฐจ์ด์ ๋ํด์ ์ดํด๋ณด๋ฉด์ ์์์ ๋ํด์ ์์๋ณด์.
์ฒซ ๋ฒ์งธ๋ก extends ์์ ํค์๋์ ๋ํด์ ์์๋ณด์.
extends ํค์๋๋ฅผ ์ฌ์ฉํ ์์์์๋ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ ๋ฉค๋ฒ๋ณ์, ๋ฉ์๋, ์์ฑ์ ์์๋ฅผ ๊ทธ๋๋ก ์์ ๋ฐ์์ ๊ตฌํ ์์ด ์ฌ์ฉ ๊ฐ๋ฅํ๋ฉฐ, ํ์์ ๋ฐ๋ผ ์ฌ์ ์ ํ ์๋ ์๋ค.
Car ํด๋์ค์ ๋ฉค๋ฒ๋ณ์๋ก name์ ์ ์ธ ํด์ฃผ๊ณ , ์์ฑ์๋ฅผ ํตํด ์ด๊ธฐํํ ์ ์๋๋ก ํด์ฃผ๊ณ printName() ์ด๋ผ๋ name์ ์ถ๋ ฅํด์ฃผ๋ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ์ฌ ์์ฑํด ๋ณด์.
class Car {
final String name;
const Car(this.name);
void printName() => print("์๋์ฐจ ์ด๋ฆ์ $name ์
๋๋ค");
}
์ด์ G70์ด๋ผ๋ ํด๋์ค๋ฅผ ์์ฑํ์ฌ extends ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ Car ํด๋์ค๋ฅผ ์์ ๋ฐ๋๋ก ํด์ฃผ์.
์ด๋ ๊ฒ ์์ ๋ฐ๊ฒ ๋๋ฉด, ์๋ฌ๊ฐ ๋ฐ์ํ ๊ฒ์ด๋ค.
class G70 extends Car {}
์๋ฌ๊ฐ ๋ฐ์ํ๋ ์ด์ ๋ Car ํด๋์ค์์ name์ ์ด๊ธฐํํ๊ธฐ ์ํ ์์ฑ์๋ฅผ ์ถ๊ฐ ํ์๊ธฐ ๋๋ฌธ์ ๋ฐ์ํ๋ ์ด์ ์ด๋ค.
Car ํด๋์ค์ ์์ฑ์๋ฅผ ์์ ํด๋์ค(์๋ธํด๋์ค)์์ ์ด๊ธฐํ ํด์ฃผ์ด์ผ ํ๋ค (์์ฑ์๊ฐ ์๋ค๋ฉด ์๊ด์๋ค)
class G70 extends Car {
const G70(super.name);
}
์ด์ G70 ํด๋์ค๊ฐ Car ํด๋์ค๋ฅผ ์์ ๋ฐ์๋์ง ํ์ธํด ๋ณด์. ์ ์์ ์ผ๋ก ์์์ ๋ฐ์๋ค.
void main() {
final G70 g70 = G70("G70");
g70.printName();
// ์๋์ฐจ ์ด๋ฆ์ G70 ์
๋๋ค
}
Car ํด๋์ค๋ก ๋ถํฐ ์์ ๋ฐ์ ๋ฉ์๋์ธ printName()์ ์ถ๋ ฅ ๋ฌธ๊ตฌ๋ฅผ ์์ ํ๊ณ ์ถ์ด์ก๋ค. ์ด๋ด ๋ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ ๋ฉ์๋๋ฅผ ์์ ํด์ผ๋ง ํ๋ ๊ฑธ๊น ?
๊ทธ๋ด ํ์ ์๋ค. ์ฌ์ ์(override) ํด์ฃผ๋ฉด ๋๋ค.
์ฌ์ ์(override)๋ Dart annotation ๋ฌธ๋ฒ์ ์ฌ์ฉํ๋ ํค์๋๋ก ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ ๋ฉ์๋๋ฅผ ์์ ํด๋์ค(์๋ธํด๋์ค)์์ ๋ค์ ์ ์ํ ์ ์๋๋ก ํด์ฃผ๋ ๊ธฐ๋ฅ์ด๋ค.
์ฌ์ ์(override)์ ๋ํด์๋ ์ด๋ฏธ ์ต์ํ๊ฒ ์์ฃผ ๋ดค์ ๊ฒ์ด๋ค. StatelessWidget์ build ๋ถ๋ถ์ ์ฌ์ ์๊ฐ ๋ฐ๋ก build๋ฅผ ๋ค์ ์ ์ ํ๊ฒ ๋ค๋ ์๋ฏธ์ด๋ค.
์ฌ์ ์(override)ํ๋ ๋ฐฉ๋ฒ์ ๋งค์ฐ ์ฌํํ๋ค. ๋ฐ๋ก "@override" annotation์ ์ถ๊ฐํด ์ค ๋ค, ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ ๋ฉ์๋๋ฅผ ๋ค์ ์ ์ํด ์ฃผ๋ฉด ๋๋ค.
class G70 extends Car {
const G70(super.name);
void printName() => print("$name ์
๋๋ค");
}
์ด์ ๋ค์ ์ถ๋ ฅํด๋ณด๋ฉด, ์ฌ์ ์๋ ๋ฉ์๋๊ฐ ์คํ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ฌ๊ธฐ์ ๊ถ๊ธํ์ค ์ ์๋ ๋ถ๋ถ์ด ๋ฐ๋ก "@override" annotation์ ๊ผญ ๋ฃ์ด์ค์ด์ผ ํ๋ ๊ฑด์ง์ ๋ํด์๋ค. ์๋ํ๋ฉด ์ฌ์ค annotation์ ์ถ๊ฐํ์ง ์์๋ ์ฌ์ ์๊ฐ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ด๋ค. ํ์ง๋ง Dart ์ธ์ด์ ๋ฌธ๋ฒ์ด์ ๊ท์น์ด๊ธฐ ๋๋ฌธ์, ๊ฐ๋ฐ์๋ค์ ์ฝ๋๋ฅผ ๋ณด๊ณ ์ฃผ์๋ฌธ์ด ์์ผ๋ฉด ํด๋น ๋ฉ์๋๋ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ ๋ฉ์๋๋ฅผ ์ฌ์ ์ํ ๊ฒ์ธ๊ฐ๋ฅผ ๋ฐ๋ก ์ ์ ์๊ธฐ ๋๋ฌธ์, ๋ฐ๋์ ์ด๋ ธํ ์ด์ ์ ์ถ๊ฐํ๋ ์ต๊ด์ ๊ฐ์ ธ์ผ ํ๋ค.
"annotation์ ์ฌ์ ์ ์๋ฏธ๋ก๋ ์ฃผ์์ด์ง๋ง, ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉํ๋ ์ฃผ์์ด ์๋ ํ๋ก๊ทธ๋จ์๊ฒ ์ถ๊ฐ์ ์ธ ์ ๋ณด์ธ ๋ฉํ๋ฐ์ดํฐ(metadata)๋ฅผ ์ ๋ฌํ๊ธฐ ์ํด ์ถ๊ฐํ๋ ๋ฌธ๋ฒ"
G80 ํด๋์ค๋ Car ํด๋์ค๋ฅผ ์์ ๋ฐ์ ์์ฑํด์ฃผ์.
class G80 extends Car {
const G80(super.name);
}
G80 ํด๋์ค๋ ์ฌ์ ์ ํด์ฃผ์ง ์์๊ธฐ ๋๋ฌธ์, ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ ๋ฉ์๋๊ฐ ์ถ๋ ฅ์ด ๋๋ค.
void main() {
final G70 g70 = G70("G70");
final G80 g80 = G80("G80");
g70.printName();
// G70 ์
๋๋ค
g80.printName();
// ์๋์ฐจ ์ด๋ฆ์ G80 ์
๋๋ค
}
Car ํด๋์ค์ ์ ์ํ ๋ฉค๋ฒ๋ณ์ hp๋ฅผ ์ถ๊ฐํด ์ฃผ๊ณ , getHorsePower() ๋ผ๋ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ์ฌ ์์ฑํด ์ฃผ๋๋ก ํ์.
class Car {
final int hp;
final String name;
const Car(this.name, this.hp);
void getHorsePower() => print("$name ๋ง๋ ฅ : $hp");
}
์ด์ ๊ธฐ์กด G70, G80 ํด๋์ค์์๋ ์ฝ๋๋ฅผ ์ถ๊ฐํ๋ผ๋ ์๋ฌ๊ฐ ๋ณด์ผ ๊ฒ์ด๋ค. hp๋ฅผ ์ด๊ธฐํ ํ์ฌ์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ด๋ฒ์๋ ์์ ํด๋์ค(์๋ธํด๋์ค)๋ฅผ ์ธ์คํด์คํ ๋์ ์์ฑ์(constructor)๋ฅผ ํตํด์ ์ด๊ธฐํ ๊ฐ์ ๋ฐ์์ค์ง ์๊ณ , ์ด๊ธฐํ ๊ฐ์ ๋ด๋ถ์ ์ ์ธํ์ฌ ์ธ์คํด์ค์ ๊ฐ์ ๋ฐ์์๋ ๋๊ณ ๋ฐ์์ค์ง ์์๋ ๋ ์ ์๋๋ก ์์ฑ์๋ฅผ ๋ง๋ค์ด ์ฃผ๋๋ก ํ์.
์ผ๋ฐ์ ์ผ๋ก ํด๋์ค์์ ์์ฑ์(constructor)์ ๋ฐ์ดํฐ๋ฅผ ์ต์ ๋๋ก ๋ฃ์ผ๋ ค๋ฉด ์๋ ์ฝ๋์ฒ๋ผ ํด์ฃผ๋ฉด ๋๋ค.
class Test {
final String name;
const Test({this.name = ""});
}
ํ์ง๋ง G70 ํด๋์ค์์ ์์ฑ์(constructor)๋ฅผ ์ต์ ๋ํ๊ฒ ๋ฃ์ผ๋ ค๊ณ ํ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
๊ทธ ์ด์ ๋ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ ์์ฑ์์๋ ๊ธฐ๋ณธ ๊ฐ ์์ด ์์ฑ์๊ฐ ๊ตฌํ๋์ด ์๊ธฐ ๋๋ฌธ์, ์์ ๋ฐ์ ์์ ํด๋์ค(์๋ธํด๋์ค)๋ ์์ฑ์์ ๋ฐ์ดํฐ๋ฅผ ์ต์ ๋ํ๊ฒ ์์ฑํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ ์์ฑ์๋ฅผ ์ต์ ๋๋ก ๋ณ๊ฒฝํด์ฃผ๊ณ , ๋์ ๊ธฐ๋ณธ ๊ฐ์ ๋ฐ๋์ ๋ฃ์ด์ผ ํ๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ ๊ฐ์ ์์ฑํด์ฃผ๋ฉด ๋๋ค.
class Car {
final int hp;
final String name;
const Car({this.name = "", this.hp = 0});
void getHorsePower() => print("$name ๋ง๋ ฅ : $hp");
}
์ด์ ์์ ํด๋์ค(์๋ธํด๋์ค)์์๋ ๋ฉค๋ฒ ๋ณ์๋ฅผ ์ด๊ธฐํํ ํ์๊ฐ ์์ผ๋ฏ๋ก, ์์ฑ์(constructor)๋ ์ ํ ์ฌํญ์ด ๋๋ฏ๋ก ์์ฑ์๊ฐ ์์ด๋ ๋๊ณ ์์ด๋ ๋๋ค.
G80 ํด๋์ค์ ์์ฑ์ ์์์ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ ๋ฉค๋ฒ๋ณ์๋ฅผ ์ต์ ๋ํ๊ฒ ์ฒ๋ฆฌํ ์ ์๊ฒ ๋๋ค.
class G80 extends Car {
const G80({super.name = "G80", super.hp = 250});
}
์ด์ G80 ํด๋์ค๋ฅผ ์ธ์คํด์คํ ๋์ Default ์์ฑ์๋ฅผ ์ต์ ๋ํ๊ฒ ๋ฐ์์ฌ ์ ์๊ฒ ๋์๋ค.
void main() {
G80 g80 = G80();
g80.getHorsePower();
// G80 ๋ง๋ ฅ : 250
}
์์ ํด๋์ค(์๋ธํด๋์ค)์์ ๋ฉค๋ฒ๋ณ์๋ฅผ ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์ดํด๋ณด๋๋ก ํ์.
G80 ๋ชจ๋ธ์๋ ์ธ๋จํ ํ์ ์ ๋ชจ๋ธ๋ง ์์ง๋ง, G70 ๋ชจ๋ธ์๋ ์ธ๋จํ๊ณผ ์๊ฑดํ ๋ ๊ฐ์ง ์ ํ์ ๋ชจ๋ธ์ด ์๋ค. ์ด๋ฌํ ์ ํ์ ๋ํ๋ด๊ธฐ ์ํด subName์ด๋ผ๋ ๋ฌธ์์ด ๋ณ์๋ฅผ ์ถ๊ฐํ๋ ค๊ณ ํ๋ค. ์ด๋ฐ ๊ฒฝ์ฐ Car ํด๋์ค์ ๋ณ์๋ฅผ ์ถ๊ฐํด์ผ ํ๋๊ฒ ๋ง์๊น ? ์๋๋ค.
G80 ๋ชจ๋ธ์๋ ํ์๊ฐ ์๊ณ , G70 ๋ชจ๋ธ์๋ง subName ๋ณ์๊ฐ ํ์ํ๊ธฐ ๋๋ฌธ์, ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ธ Car ํด๋์ค์ ๋ณ์๋ฅผ ์ถ๊ฐํ์ง ์๊ณ ์์ ํด๋์ค(์๋ธํด๋์ค)์ธ G70 ํด๋์ค์๋ง ์ถ๊ฐํด์ ์ฌ์ฉํ๋๊ฒ ๋ง๋ค.
class G70 extends Car {
final String subName;
}
๋ฉค๋ฒ๋ณ์ subName๋ ์์ฑ์(constructor)๋ฅผ ํตํด ์ด๊ธฐํ ํด์ฃผ๋๋ก ํ๊ฒ ๋ค.
๊ธฐ๋ณธ ์ด๊ธฐํ ๊ฐ์ ์ฃผ์ง ์์๊ธฐ์ required๋ฅผ ์ฌ์ฉํด ํ์๋ก ์ธ์คํด์ค์ ๊ฐ์ ๋ฐ์์ฌ ์ ์๊ฒ ํด์ฃผ์๋ค.
๊ธฐ์กด ํด๋์ค ์์ฑํ๋ ๋ฐฉ๋ฒ๊ณผ ๋์ผํ๊ฒ ์ฌ์ฉํ๋ฉด ๋๋ค.
class G70 extends Car {
final String subName;
const G70({
super.name = "G70",
super.hp = 230,
required this.subName,
});
}
์ฌ๊ธฐ์ super?, this? ์ ๊ถ๊ธ์ค์ด ์๊ฒผ์๊ฑฐ๋ค. ์ฐจ์ด์ ์ ๋ํด์ ์์๋ณด์.
super์ this๋ ๊ฐ๋จํ ๋ฌธ๋ฒ์ด๋ค.
this๋ ํ์ฌ ํด๋์ค์ ์ธ์คํด์ค๋ ์๋ฏธ์ด๋ค. ์ฌ๊ธฐ์๋ ํ์ฌ ํด๋์ค์ธ ์์ ํด๋์ค(์๋ธํด๋์ค)์ ๋ฉค๋ฒ๋ณ์ ์ง์ ์ ์ํด ์ฌ์ฉ๋๋ ํค์๋์ด๋ค.
super๋ ์์ ๋ฐ์ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ ๋ฉค๋ฒ๋ณ์๋ฅผ ์ฐธ์กฐํ ์ ์๋๋ก ํด์ฃผ๋ ํค์๋์ด๋ค.
Dart ์ธ์ด์์๋ super ํค์๋ ์์ด ์ฌ์ฉ์ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์์ ์์ ๋ฐ์ ๋ฉค๋ฒ๋ณ์๋ฅผ ์ฐธ์กฐํ์ง๋ง, this์ ์ํฅ์ผ๋ก ์ธํ์ฌ ์์ ํด๋์ค(์๋ธํด๋์ค)์์ ์ฌ์ ์ ๋์๋ค๋ฉด ์์ ํด๋์ค(์๋ธํด๋์ค)์ ๋ฉค๋ฒ๋ณ์๋ฅผ ์ฐธ์กฐํ๊ฒ ๋๋ค.
Person ํด๋์ค๋ฅผ ๋ฉค๋ฒ๋ณ์๋ก name์ ์ถ๊ฐํ ํด๋์ค๋ฅผ ๋ง๋ค์ด ์ฃผ์.
class Person {
final String name = "Empty";
}
Tyger ํด๋์ค๋ Person ํด๋์ค๋ฅผ ์์ ๋ฐ๋๋ก ํด์ฃผ๊ณ , Tyger ํด๋์ค ๋ด๋ถ์ ๋ฉค๋ฒ๋ณ์๋ก name์ ์ถ๊ฐํด ์ฃผ๋๋ก ํ์.
super.name์ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ธ Person ํด๋์ค์ name์ด๋ค. this ํค์๋๋ ์๋ต ๊ฐ๋ฅํ๋ค.
class Tyger extends Person {
final String name = "Tyger";
void log() => print("Person name: ${super.name}, Tyger name: ${this.name}");
}
Tyger ํด๋์ค๋ฅผ ์ธ์คํด์คํ๊ณ , log() ๋ฉ์๋๋ฅผ ํธ์ถํด ๋ณด์.
void main() {
Tyger tyger = Tyger();
tyger.log();
// Person name: Empty, Tyger name: Tyger
}
super, this ๊ธฐ๋ฅ๋ ๋ ์ฐพ์๋ณด๋ฉด ๊น๊ฒ ๋ฐฐ์์ผ ํ๋ ๋ด์ฉ์ด ๋ง์ง๋ง ํฌ๊ฒ ๊ฐ๋ ์ ์ฐจ์ด์ ์ ๋ํด์๋ง ์๊ณ ์์ผ๋ฉด ๋ฌธ์ ๊ฐ ์๊ธฐ ๋๋ฌธ์, ๋ํ ์ผํ๊ฒ ์๊ณ ์ถ์ผ์ ๋ถ๋ค์ ๋๊ธ ๋จ๊ฒจ์ฃผ์๋ฉด ๋ณ๋๋ก ์์ฑํด ๋ณด๋๋ก ํ๊ฒ ๋ค.
์ง๊ธ๊น์ง ์์ ํค์๋ ์ค extends์ ๋ํด์ ๋ฐฐ์๋ดค๋ค.
์์ง ์ดํด๊ฐ ์ ๋์ง ์์ ์๋ ์์ผ๋, ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ๋ํด์ ์ดํด๋ณด๋ฉด์ ๋ ์์๊ฐ ๋ณด๋๋ก ํ์.
์ด๋ฒ์ ๋ฐฐ์ฐ๊ฒ ๋ ์์ ๋ฐ๋ ๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ธ implements์ ๋ํด์ ์์๋ณด์.
implements ํค์๋๋ฅผ ์ฌ์ฉํ๋ ์์์์๋ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ ๋ฉค๋ฒ๋ณ์, ๋ฉ์๋ ๋ฑ์ ์์๋ฅผ ์์ ํด๋์ค(์๋ธํด๋์ค)์์ ํ์์ ์ผ๋ก ๋ชจ๋ ๊ตฌํํ์ฌ ์ฌ์ฉํ๋ ์์ ๋ฐฉ๋ฒ์ด๋ค.
์ฐจ์ด์ ์ ๋ณด์๋ฉด extends ์์์ ์์ ํด๋์ค(์๋ธํด๋์ค)์์ ์์์ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ ์์๋ฅผ ๊ตฌํํ ํ์ ์์ด ์ฌ์ฉ์ด ๊ฐ๋ฅํ ๋ฐ๋ฉด, implements ์์์ ์์ ๋ฐ์ ์์๋ฅผ ํ์์ ์ผ๋ก ์์ ํด๋์ค(์๋ธํด๋์ค)์์ ๊ตฌํํ์ฌ ์ฌ์ฉํ๋ค๋ ๋ถ๋ถ์์ ๊ฐ์ฅ ํฐ ์ฐจ์ด์ ์ด ์๋ค.
์์ ์ค๋ช ์ด ์ฝ๊ฒ ์ดํด๋์ง ์์ ์๋ ์์ผ๋, ์ฝ๋๋ฅผ ์์ฑํด์ ํ์ธํด ๋ณด๋๋ก ํ์.
Test ํด๋์ค๋ฅผ log()๋ผ๋ ๋ฉ์๋๋ง ์ถ๊ฐํ์ฌ ์์ฑํด ์ฃผ๋๋ก ํ์.
class Test {
void log() => print("Test !!");
}
extends
๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค) Test๋ฅผ extends ๋ฐฉ๋ฒ์ผ๋ก ์์ ๋ฐ๋ TestExtends ํด๋์ค๋ฅผ ๋ง๋ค์ด ์ฃผ์.
ํฐ ๋ฌธ์ ์์ด ์ ์์ฑ์ด ๋์๋ค.
class TestExtends extends Test {}
implements
์ด๋ฒ์๋ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค) Test๋ฅผ implements ๋ฐฉ๋ฒ์ผ๋ก ์์ ๋ฐ๋ TestImplements ํด๋์ค๋ฅผ ์์ฑํ์๋ค.
์ฌ๊ธฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค. TestImplements์ ์๋ฌ ๋ผ์ธ์ด ํ์๋์๋ค.
class TestImplements implements Test {}
์๋ฌ ๋ถ๋ถ์์ ๋น ๋ฅธ ์์ ๊ธฐ๋ฅ์ ์ฌ์ฉํด ๋ณด๋ฉด "Create 1 missing override" ๋ผ๋ ์์ ์ด ๋์ค๋ ๊ฒ์ ์ ์ ์๋ค.
์์ ์ ํด๋ณด๋ฉด ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ log() ๋ฉ์๋๋ฅผ override ํ๋ผ๊ณ ๋์จ๋ค.
void log() {
// TODO: implement log
}
์์์ implements ์์ ๋ฐฉ๋ฒ์์ ์ค๋ช ํ "๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ ๋ฉค๋ฒ๋ณ์, ๋ฉ์๋ ๋ฑ์ ์์๋ฅผ ์์ ํด๋์ค(์๋ธํด๋์ค)์์ ํ์์ ์ผ๋ก ๋ชจ๋ ๊ตฌํ" ํด์ผ ํ๋ค๊ณ ์ ์ํ ๊ฒ์ฒ๋ผ ์์ฑ์๋ฅผ ์ ์ธํ๊ณ ์์ ํด๋์ค(์๋ธํด๋์ค)์์ ์ฌ์ ์(override) ํ์ฌ ์ฌ์ฉํ๋ ์์ ๋ฐฉ๋ฒ์ด๋ค.
์ฐ์ implements๋ฅผ ์ฌ์ฉํ ์์์ ์ตํ๋ณด๋๋ก ํ์.
Car ํด๋์ค์ getHorsePower() ๋ผ๋ ์๋์ฐจ ๋ชจ๋ธ์ ๋ง๋ ฅ์ ์ถ๋ ฅํ ์ ์๋ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ์ฌ ์์ฑํด ์ฃผ์.
class Car {
void getHorsePower(int hp) => print("๋ง๋ ฅ์ $hp ์
๋๋ค.");
}
Car ํด๋์ค๋ฅผ implements๋ฅผ ์ฌ์ฉํด ์์๋ฐ๋ G70 ํด๋์ค๋ฅด ๋ง๋ค์ด ์ฃผ์.
์์ ํด๋์ค(์๋ธํด๋์ค)์์ ์ฌ์ ์(override)ํด์ผ ํ๋๋ฐ, ์ฐ์ ์๋ฌด๊ฒ๋ ์์ฑํ์ง ์๋๋ก ํ์.
class G70 implements Car {
void getHorsePower(int hp) {}
}
G70 ํด๋์ค๋ฅผ ์ธ์คํด์คํ ํ์ getHorsePower ๋ฉ์๋๋ฅผ ํธ์ถํด๋ณด์.
๋น์ฐํ ๊ฒฐ๊ณผ๋ ์๋ฌด๊ฒ๋ ์ถ๋ ฅ๋์ง ์๋๋ค. ์์ ํด๋์ค(์๋ธํด๋์ค)์์ ๋ฉ์๋๋ฅผ ์์ฑํ์ง ์์๊ธฐ ๋๋ฌธ์ด๋ค.
void main() {
G70 g70 = G70();
g70.getHorsePower(250);
}
๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ ๋ฉค๋ฒ๋ณ์๋ฅผ ์์ ๋ฐ์ผ๋ฉด ์ด๋ป๊ฒ ๋ ๊น ?
๋ฌธ์์ด name ๋ณ์๋ฅผ ์ถ๊ฐํด ์ฃผ์.
class Car {
final String name;
const Car(this.name);
void getHorsePower(int hp) => print("๋ง๋ ฅ์ $hp ์
๋๋ค.");
}
๋ฉค๋ฒ๋ณ์๋ ๋ง์ฐฌ๊ฐ์ง๋ก ์ฌ์ ์(override) ํด์ผ ํ๋ค.
class G70 implements Car {
String get name => "G70";
void getHorsePower(int hp) {}
}
์ด์ฏค ๋๋ฉด ๋๋์ฒด ์ implements ์์์ ์ฌ์ฉํ๋ ๊ฑธ๊น ? ๊ทธ๋ฅ extends ์์์ ์ฌ์ฉํ๋ฉด ๋๋๊ฑฐ ์๋๊ฐ ?
์ฌ๊ธฐ์ ๋ฐ๋ก ์ฌ์ ์ง์์ผ๋ก ์ดํด๋ณธ ์ถ์(abstract)ํด๋์ค์ ๊ธฐ๋ฅ์ ํ์ฉํ๋ฉด, ์ implements ์์์ ์ฌ์ฉ ํ๋์ง ์ดํดํ ์ ์๋ค.
ํน์๋ผ๋ ์ถ์(abstract)ํด๋์ค์ ๋ํด์ ๋ชจ๋ฅด์๊ฑฐ๋ ์์ ์์ฑ๋ ๊ธ์ ๋ณด์ง ์์ผ์ ๋ถ์ ํ ๋ฒ์ ๋ณด์๊ธธ ์ถ์ฒ ํฉ๋๋ค.
์์ง ์์ ํ ์ดํด๊ฐ ๋์ง ์๋๋ผ๋ ๊ฑฑ์ ํ์ง ์์ผ์
๋ ๋๋ค.
์ถ์(abstract)ํด๋์ค๋ ์์ ์ค๋ช ํ๋ฏ์ด ๋จ๋ ์ ์ผ๋ก๋ ์ธ์คํด์ค(instance) ํ ์ ์๋ ํด๋์ค์ด๋ฉฐ, ์ ์ธ๋ง ๋๊ณ ์ ์๋ ์๋ ๋ฉ์๋๋ผ๊ณ ํ์๋ค.
์ฌ๊ธฐ์ ์ค์ํ ๋ถ๋ถ์ ๋ฐ๋ก "์ ์๋ ์๋ ๋ฉ์๋" ๋ผ๋ ๋ถ๋ถ์ด๋ค. ์ด ๋ง์ ์๋ฏธ๋ ์ ์ธ๋ง ํ๋ฉด ๋๋ค๋ ๊ฒ์ด๋ค.
implements ์์์ ๋ณด๋ฉด, ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์์ ์ ์ธํ๊ณ ์ ์๋ฅผ ํด๋ ์์ ํด๋์ค(์๋ธํด๋์ค)์์ ํ์์ ์ผ๋ก ์ฌ์ ์(override) ํด์ผ ๋๋ ๋ถ๋ถ์ด ์ implements ์์์ ์ฌ์ฉํด์ผ ํ๋์ง ์๋ฌธ์ด์๋ ๋ถ๋ถ์ด๋ค.
์ถ์(abstract)ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ฉด ์ ์ธ๋ง ํ๋ฉด ๋๊ณ implements ์์ ํ์ ์ ์๋ฅผ ๊ตฌํํด์ฃผ๋ฉด ๋๋ค.
Car ํด๋์ค๋ฅผ ์ถ์(abstract)ํด๋์ค๋ก ์์ฑํ๊ณ getHorsePower ๋ฉ์๋๋ ์ ์ธ๋ง ํด์ฃผ๋๋ก ํ์.
abstract class Car {
void getHorsePower(int hp);
}
์ด์ G70 ํด๋์ค์์ Car ํด๋์ค๋ฅผ implements ์์์ ์ฌ์ฉํด ์์ ๋ฐ๋๋ก ํ์.
์์ ๋ฐ์ G70 ํด๋์ค์์ ๋ฉ์๋๋ฅผ ์ ์ํด ์ฃผ๋ฉด ๋๋ค. ๊ฐ๋จํ๋ค.
class G70 implements Car {
void getHorsePower(int hp) => print("๋ง๋ ฅ์ $hp");
}
์ฌ์ ์(override)ํ ๋ฉ์๋๊ฐ ์ ์์ ์ผ๋ก ์คํ์ด ๋๋ค.
void main() {
G70 g70 = G70();
g70.getHorsePower(250);
// ๋ง๋ ฅ์ 250
}
์ด๋ฒ์๋ ๋ฉค๋ฒ๋ณ์๋ฅผ ์ถ์(abstract)ํด๋์ค์ ์ ์ธํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ๋์ง ์์๋ณด์.
์ฐ์ ์ถ์(abstract)ํด๋์ค์์์ ๋ฉค๋ฒ๋ณ์๋ฅผ ์ด๋ป๊ฒ ์ ์ธํ๋์ง์ ๋ฐ๋ผ ์ฌ์ฉ ๋ฐฉ๋ฒ์ด ๋ค์ํ๋ค.
์ผ๋ฐ์ ์ผ๋ก๋ Getter๋ฅผ ์ฌ์ฉํด ์ ์ธํด ์ค๋ค.
๋ฉค๋ฒ๋ณ์๋ ๋ฉ์๋์ ๋์ผํ๊ฒ ์ ์ธ๋ง ํด์ฃผ๋ฉด ๋๋ค. ์ ์๋ ํ์ ์๋ค.
abstract class Car {
String get name;
}
G70 ํด๋์ค์์๋ Getter๋ฅผ ์ฌ์ฉํ ์ ์๋ฅผ ํ๋ฉด ๋๋ค.
class G70 implements Car {
final String _name;
const G70(this._name);
String get name => _name;
}
์ง๊ธ๊น์ง ์์ ๋ฐฉ๋ฒ ์ค extends, implements ์์ ๋ฐฉ๋ฒ์ ๋ํด์ ์์ ๋ดค๋ค.
๋์ผํ ์์ ๊ธฐ๋ฅ์ด๋ผ ์๊ฐํ ์ ์๊ฒ ์ง๋ง, ์ฌ์ค ์ ํ ๋ค๋ฅธ ์์ ๋ฐฉ๋ฒ์ธ ๊ฒ์ด๋ค.
์ฌ๊ธฐ์ ๊ถ๊ธ์ ์ด ์์ ์ ์๋๋ฐ, ์ถ์(abstract)ํด๋์ค๋ฅผ extends ์์ํ๊ฒ ๋๋ฉด ์ด๋ป๊ฒ ๋ ๊น ?
์ถ์(abstract)ํด๋์ค์ ๋ฉ์๋๊ฐ ์ ์๊ฐ ๋ ์ํ๋ผ๋ฉด extends ์์์ ํด๋ ์ฌ์ ์(override) ํ ํ์๊ฐ ์์ง๋ง, ์ ์๊ฐ ๋์ง ์๊ณ ์ ์ธ๋ง ๋์๋ค๋ฉด extends ๋ฐฉ๋ฒ๋ implements ์์๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ์ฌ์ ์(override) ํด์ฃผ์ด์ผ ํ๋ค.
abstract class Person {
void printName(String name);
}
์์ ํด๋์ค(์๋ธํด๋์ค)์์ ์ฌ์ ์(override)ํด์ผ ํ๋ค.
class Tyger extends Person {
void printName(String name) => print("์ด๋ฆ์ Tyger !");
}
์์ง ์ดํด๊ฐ ์ ๋์ง ์์ ์๋ ์์ง๋ง, ์ฌ๋ฌ๊ฐ์ง ํด๋์ค๋ฅผ ๊ตฌ์ถํ๋ค ๋ณด๋ฉด ์์ฐ์ค๋ฝ๊ฒ ์ตํ์ง๋ ๋ถ๋ถ์ด๋ ์ฒ์ฒํ ๋ฐฐ์๊ฐ๋ฉด ๋๋ค.
extends ์์์ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ ๋ฉค๋ฒ๋ณ์, ๋ฉ์๋ ๋ฑ์ ์์๋ฅผ ์ ๋ถ ์์ ๋ฐ์ ์ฌ์ฉํ๋ ๋ฐ๋ฉด implements ์์์ ์ถ์(abstract)ํด๋์ค๋ฅผ ํ์ฉํ์ฌ ์์ ํด๋์ค(์๋ธํด๋์ค) ์์ ์ฌ์ ์(override)ํ์ฌ ์ฌ์ฉํ๋ค๊ณ ์ดํดํ๋ฉด ๋๋ค.
extends, implements ์ค ์ด๋ค ์์ ๋ฐฉ๋ฒ์ ์ ํํด์ผ ํ๋์ง์ ๋ํด์ ์์ ๋ฅผ ํตํด ์ข ๋ ์์๋ณด๋๋ก ํ๊ฒ ๋ค.
์ํผ ํ์ด๋ก์ ๋ํ ์ ๋ณด๋ฅผ ๋ณด์ฌ์ฃผ๋ ๊ธฐ๋ฅ์ ๋ง๋ ๋ค๊ณ ๊ฐ์ ํด๋ณด์.
์ํผ ํ์ด๋กํํ ๋ ๊ณต๊ฒฉ๋ ฅ๊ณผ ๋ฐฉ์ด๋ ฅ์ ๋ํ๋ด์ฃผ๋ ๋ฉ์๋๊ฐ ์กด์ฌํด์ผ ํ๋ค.
๋ง๋ธ ํ์ด๋ก์๊ฒ๋ tier ๋ผ๋ ๋ฑ๊ธ์ ๊ฐ๋ ๋ฉค๋ฒ๋ณ์๋ฅผ ์ถ๊ฐํ์๋ค. tier๋ 1~9๊น์ง์ ์์๋ก 1์ด ๊ฐ์ฅ ๋์ ๋ฑ๊ธ์ธ๋ฐ, ๊ณต๊ฒฉ๋ ฅ์ด๋ผ๋ getAttack ๋ฉ์๋๋ 10์์ tier๋ฅผ ๋นผ์ค ๊ฐ์ ๊ณฑํ๊ธฐ 100์ ํด์ฃผ๊ณ ๋ฐฉ์ด๋ ฅ์ 20์ ๊ณฑํด์ฃผ๊ธฐ๋ก ํ์๋ค.
class Hero {
final String name;
final int tier;
const Hero({
required this.tier,
required this.name,
});
int getAttack() => (10 - tier) * 100;
int getDefence() => (10 - tier) * 20;
}
์ด์ ๋ง๋ธ ํ์ด๋ก์ธ ์์ด์ธ๋งจ๊ณผ ํํฌ์ ํด๋์ค๋ฅผ ์์ฑํ ๊ฒ์ธ๋ฐ, Hero ํด๋์ค๋ฅผ extends ์์์ ๋ฐ๋๋ก ํ๊ฒ ๋ค.
์์ด์ธ๋งจ์ tier๋ 9๋ฑ๊ธ ์ด๊ณ , ํํฌ์ tier๋ 7๋ฑ๊ธ์ผ๋ก ํด์ฃผ์๋ค.
class IronMan extends Hero {
const IronMan({super.tier = 9, super.name = "IronMan"});
}
class Hulk extends Hero {
final String name = "Hulk";
const Hulk({super.tier = 7, super.name = "Hulk"});
}
์ด์ ํด๋์ค๋ฅผ ์ธ์คํด์ค(instance)ํ ํ์ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค) ๋ฉ์๋๋ฅผ ํธ์ถํด ์ฃผ์.
void main() {
IronMan ironMan = IronMan();
Hulk hulk = Hulk();
print(
"${ironMan.name}์ ๊ณต๊ฒฉ๋ ฅ์ ${ironMan.getAttack()}, ๋ฐฉ์ด๋ ฅ์ ${ironMan.getDefence()}์ด๋ค.");
// IronMan์ ๊ณต๊ฒฉ๋ ฅ์ 100, ๋ฐฉ์ด๋ ฅ์ 20์ด๋ค.
print("${hulk.name}์ ๊ณต๊ฒฉ๋ ฅ์ ${hulk.getAttack()}, ๋ฐฉ์ด๋ ฅ์ ${hulk.getDefence()}์ด๋ค.");
// Hulk์ ๊ณต๊ฒฉ๋ ฅ์ 300, ๋ฐฉ์ด๋ ฅ์ 60์ด๋ค.
}
extends ์์์ ์ฌ์ฉํด ๊ฐ๋จํ๊ฒ ๊ธฐ๋ฅ์ ๋ง๋ค์๋ค.
๊ทธ๋ฐ๋ฐ ์ฌ๊ธฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค. DC ํ์ด๋ก๊ฐ ์๋กญ๊ฒ ์ถ๊ฐ ๋์๋๋ฐ, DC ํ์ด๋ก๋ tier๋ผ๋ ๋ฑ๊ธ์ด ์๋ ์ํ์ด๋ฉฐ, ๊ณต๊ฒฉ๋ ฅ๊ณผ ๋ฐฉ์ด๋ ฅ์ ๊ณ์ฐํ๋ ์์ด ๋ง๋ธ ํ์ด๋ก์ ๋ค๋ฅด๋ค.
ํ์ง๋ง ๊ณต๊ฒฉ๋ ฅ๊ณผ ๋ฐฉ์ด๋ ฅ์ ๋ง๋ธ ํ์ด๋ก, DC ํ์ด๋ก ๋ชจ๋์๊ฒ ํ์ํ ๋ฉ์๋์ด๋ค.
์ ์ด๋ด ๊ฒฝ์ฐ extends ์์์ด ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ผ๊น ? ํด๋์ค์ ์์๋ฅผ ๊ฐ์ ํ๊ณ ์ถ์๋ฐ, ์์ ํด๋์ค(์๋ธํด๋์ค)์์ ์ ๋ถ ์ฌ์ ์ ํ๊ฒ ํด์ผํ ๊ฒ์ด๋ค.
์ด๋ ๋์ implements ์์์ผ๋ก ๊ตฌํํด ๋ณด๋๋ก ํ์.
Hero ํด๋์ค์์ name ๋ณ์์ getAttack, getDefence๋ฅผ ์ถ์(abstract)ํด๋์ค๋ฅผ ์ถ์ํํ์ฌ ์ ์ธ๋ง ํ์๋ค.
์ด๋ ๊ฒ ๋๋ฉด Hero๋ฅผ ์์ ๋ฐ๋ ์์ ํด๋์ค(์๋ธํด๋์ค)์์๋ Hero์ ํด๋์ค ์์๋ฅผ ์ ๋ถ ๊ฐ์ ํ ์ ์๊ฒ ๋์๋ค.
abstract class Hero {
final String name;
const Hero(this.name);
int getAttack();
int getDefence();
}
์ฝ๋๊ฐ ๊ธธ์ด์ ธ ์์ด์ธ๋งจ๊ณผ ์ํผ๋งจ๋ง ํด๋์ค๋ฅผ ์์ฑํ์๋ค.
class IronMan implements Hero {
final int tier = 9;
int getAttack() => (10 - tier) * 100;
int getDefence() => (10 - tier) * 20;
String get name => "IronMan";
}
class SuperMan implements Hero {
int getAttack() => 1000;
int getDefence() => 100;
String get name => "SuperMan";
}
์ด์ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํด ๋ณด๋๋ก ํ์.
void main() {
IronMan ironMan = IronMan();
SuperMan superMan = SuperMan();
print(
"${ironMan.name}์ ๊ณต๊ฒฉ๋ ฅ์ ${ironMan.getAttack()}, ๋ฐฉ์ด๋ ฅ์ ${ironMan.getDefence()}์ด๋ค.");
// IronMan์ ๊ณต๊ฒฉ๋ ฅ์ 100, ๋ฐฉ์ด๋ ฅ์ 20์ด๋ค.
print(
"${superMan.name}์ ๊ณต๊ฒฉ๋ ฅ์ ${superMan.getAttack()}, ๋ฐฉ์ด๋ ฅ์ ${superMan.getDefence()}์ด๋ค.");
// SuperMan์ ๊ณต๊ฒฉ๋ ฅ์ 1000, ๋ฐฉ์ด๋ ฅ์ 100์ด๋ค.
}
์ด์ extends, implements ์์์ ๋ํด์๋ ์ดํดํ์ ๊ฑฐ๋ผ ์๊ฐํ๋ค.
์์ ์์ ๋ฅผ ๋ณด๋ฉด, ์์ง๋ ๋ญ๊ฐ ๋ถ์กฑํ ๋๋์ด๊ณ ๋ถํธํ๋ค. ๋ง๋ธ ํ์ด๋ก์ธ ๊ฒฝ์ฐ๋ tier๊ฐ ๋ฐ๋์ ์กด์ฌํ๋๋ฐ, DC ํ์ด๋ก์ tier๊ฐ ์๋ค๋ ์ด์ ๋๋ฌธ์, ์์ ํด๋์ค(์๋ธํด๋์ค)์์ tier ๋ณ์๋ฅผ ์ถ๊ฐํด์ ์ฌ์ฉํด์ผ๋ง ํ๊ณ , ์ด๋ฌํ ํด๋์ค๊ฐ 100๊ฐ 1000๊ฐ๊ฐ ๋๋ค๊ณ ๊ฐ์ ํด ๋ณด๋ฉด ๋๋ฌด ๊ท์ฐฎ์ ์ผ์ด ๋ฐ์ํ๋ค.
์ฌ๋ฌ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)๋ฅผ ์์ ๋ฐ์ ์ ์์๊น ?
์ด์ ๋ถํฐ ํ ๊ฐ์ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)๊ฐ ์๋ ์ฌ๋ฌ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)๋ฅผ ์์ ๋ฐ๋ ๋ค์ค์์์ ๋ํด์ ์ดํด๋ณด๋๋ก ํ๊ฒ ๋ค.
Dart ์ธ์ด๊ฐ ๊ฐ์ฒด์งํฅ์ธ์ด(OOP)๋ผ๋ ๊ฒ์ ์ด๋ฏธ ์๊ณ ์๋ ๋ด์ฉ์ด๋ค. ๊ฐ์ฒด์งํฅ์ธ์ด์ ์ฅ์ ์ค ํ๋๋ ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ์ธ๋ฐ, ์ฌ๋ฌ ๊ณ์ธต์ ํด๋์ค(class)๋ฅผ ๋ค์ค์ผ๋ก ์์ ๋ฐ์ ์ฌ์ฉํ๊ณ ์ถ์ ๊ฒฝ์ฐ๊ฐ ์์ ๊ฒ์ด๋ค.
ํ์ง๋ง ๋์ฒด์ ์ผ๋ก OOP์์ ๋ค์ค์์์ ์ง์ํ์ง ์๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ด ์๋๋ฐ, ์ด๋ OOP ๋ค์ค์์์ ์์ด ์ฃฝ์์ ๋ค์ด์๋ชฌ๋ ๋ฌธ์ ๋๋ฌธ์ด๋ค.
์ฃฝ์์ ๋ค์ด์๋ชฌ๋ ๋ฌธ์ ๋ ์์ ์ด๋ฏธ์ง์ฒ๋ผ A ํด๋์ค๋ฅผ B, C๊ฐ ์์์ ๋ฐ๊ณ D ํด๋์ค์์ ๋ค์ค์์์ผ๋ก B, C๋ฅผ ์์ ๋ฐ์๋ค๋ฉด, ์ด๋ฏธ์ง์ ๊ฐ์ ๋ค์ด์๋ชฌ๋ ๊ตฌ์กฐ๊ฐ ํ์ฑ๋๊ฒ ๋๋ค.
์ด ๋์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋๋ฐ, B, C์์ ์ฌ์ ์(override)๋ print() ๋ฉ์๋๋ฅผ D ํด๋์ค์์ ํธ์ถ์ ํ๋ค๋ฉด ์ด๋ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์์ ์ ์๋ ๋ฉ์๋๊ฐ ํธ์ถ์ด ๋์ด์ผ ํ ๊น ? ์ด๋ฐ ๋ชจํธ์ฑ์ผ๋ก ์ถฉ๋์ด ๋ฐ์ํ๊ฒ ๋๋๋ฐ, ์ด๊ฒ์ ์ฃฝ์์ ๋ค์ด์๋ชฌ๋ ๋ฌธ์ ๋ผ๊ณ ํ๋ค.
Dart ์ธ์ด์์ ์ด๋ฌํ ๋ชจํธ์ฑ์ ํด๊ฒฐํ์ฌ ๋ค์ค์์์ ์ด๋ป๊ฒ ๊ตฌํํ๋์ง ์์๋ณด๋๋ก ํ์.
์ฐ์ ๋ค์ค์์ ๋ฐฉ๋ฒ์ ์์๋ณด๊ธฐ์ ์์, extends ์์์ ๋ค์ค์์์ด ๋ถ๊ฐ๋ฅํ๋ค.
Flutter 3 ๋ฒ์ ์ด ๋์ค๊ธฐ ์ ์๋ extends์์๋ ๋ค์ค์์์ with ํค์๋๋ฅผ ์ฌ์ฉํด ๊ตฌํํ ์ ์์๋ค. ํ์ง๋ง Flutter 3 ๋ถํฐ๋ ๋ค์ค์์์ ํ๊ธฐ ์ํด์๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ฌ์ฉํด์ผ ํ๋ค.
๊ทธ๋ ๋ค๋ฉด implements๋ ๋ค์ค ์์์ด ๊ฐ๋ฅํ ๊น ? implements ์์์ ์์ ํด๋์ค(์๋ธํด๋์ค)์์ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ ์์๋ฅผ ์ฌ์ ์(override)ํด์ผ ํ๊ธฐ ๋๋ฌธ์, ์ฌ๋ฌ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)๋ฅผ ์์ ๋ฐ์ ์ ์๋ค.
Hero์ ๊ณต๊ฒฉ๋ ฅ๊ณผ ๋ฐฉ์ด๋ ฅ์ ๊ฐ์ง๋ ๋ฉ์๋๊ฐ ์๋ ํด๋์ค์, ๋ง๋ธ ํ์ด๋ก์ ์์์ธ tier๋ฅผ ๊ฐ์ง๋ MarvelHero ํด๋์ค๋ฅผ ์์ฑํด ์ฃผ์.
abstract class Hero {
int getAttack();
int getDefence();
}
abstract class MarvelHero {
final int tier;
const MarvelHero(this.tier);
}
Hero, MarvelHero ํด๋์ค๋ฅผ ๋ค์ค์์์ผ๋ก ์์ ๋ฐ๋ IronMan ํด๋์ค๋ฅผ ์์ฑํ ๋ค, ์ฌ์ ์(override) ํด์ฃผ๋ฉด ๋๋ค.
class IronMan implements Hero, MarvelHero {
int getAttack() => (10 - tier) * 100;
int getDefence() => (10 - tier) * 20;
int get tier => 9;
}
๋ง์ฝ์ MarvelHero ํด๋์ค์ Hero์ ์๋ ๋์ผํ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ๊ฒ ๋๋ฉด ์ด๋ป๊ฒ ๋ ๊น ?
๊ฒฐ๊ณผ๋ ๋์ผํ ๋ฉ์๋๊ฐ ์ถ๊ฐ ๋๋๋ผ๋, ์์ ํด๋์ค(์๋ธํด๋์ค)์์ ์ฌ์ ์(override) ํ ๋ฉ์๋๊ฐ ์คํ๋๊ธฐ ๋๋ฌธ์ ๋์ผํ ๋ฉ์๋๊ฐ ์กด์ฌํด๋ ์๊ด์๋ค.
class MarvelHero {
final int tier;
int getAttack() => 100;
int getDefence() => 100;
const MarvelHero(this.tier);
}
ํด๋์ค ํ๋๋ฅผ ๋ ์์ฑํด์ ์ด ์ธ๊ฐ์ ํด๋์ค๋ฅผ ์์ ๋ฐ๋๋ก ํด์ฃผ์.
class Actor {
final String name;
const Actor(this.name);
}
Actor ํด๋์ค๋ฅผ ์ถ๊ฐํ๋๋ผ๋ ๋ฌธ์ ๊ฐ ์๋ค. ์ฌ์ ์(override)๋ง ํด์ฃผ๋ฉด ๋๋ค.
implements ์์์์๋ ๋จ์ผ ํด๋์ค๋ฅผ ์์ ๋ฐ๋ ๋ค์ค์์์ ๋ฐ๋ ๋์ผํ๊ฒ ์ฌ์ฉํ๋ฉด ๋๋ค.
class IronMan implements Hero, MarvelHero, Actor {
int getAttack() => (10 - tier) * 100;
int getDefence() => (10 - tier) * 20;
int get tier => 9;
String get name => "Robert John Downey Jr";
}
์์์ extends ์์์ ๋ค์ค์์์ด ๋ถ๊ฐ๋ฅํ๊ณ , ๋ค์ค์์์ ๊ตฌํํ๊ธฐ ์ํด์๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ฌ์ฉํด์ผ ํ๋ค๊ณ ํ๋๋ฐ, ๊ทธ ๋ฐฉ๋ฒ์ด ๋ฐ๋ก mixin ์์ ์ด๋ค.
์ด์ด์ ํ ๊ฐ์ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)๊ฐ ์๋ ์ฌ๋ฌ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)๋ฅผ extends ์์์ ์ฌ์ฉํด ์์ ๋ฐ๋ ๋ฐฉ๋ฒ์ธ mixin์ ๋ํด์ ์์๋ณด๋๋ก ํ์.
์์์ ๋ํ ๋ถ๋ถ์ ์ค๋ช ํ ๋์ extends, implements, mixin ์ด๋ ๊ฒ ์ธ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค๊ณ ํ์๋ค.
์ง๊ธ๊น์ง๋ mixin์ ๋ํ ์ค๋ช ์ ํ์ง๋ ์๊ณ , extends, implements์ ๋ํด์๋ง ์ค๋ช ํ์๋๋ฐ, ๊ทธ ์ด์ ๊ฐ ๋ฐ๋ก mixin์ ๋จ์ผ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)๋ฅผ ์์ ๋ฐ๋ ๊ฒ์ด ์๋, ์ฌ๋ฌ ๊ฐ์ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)๋ฅผ extends ์์์ ์ฌ์ฉํด ๋ค์ค์์ ๋ฐ๋ ๋ฐฉ๋ฒ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
์์ ์ค๋ช ํ๋ฏ์ด Flutter 3์์ ์ ๊ทธ๋ ์ด๋๋ ๋ถ๋ถ์ด ๋ฐ๋ก mixin์ด๋ค. ์ด์ ์๋ with ํค์๋๋ฅผ ์ฌ์ฉํด ๋ค์ค์์ ๊ธฐ๋ฅ์ ๋ง๋ค ์ ์์๋๋ฐ, 3 ๋ฒ์ ์ผ๋ก ๋์ด์ค๋ฉด์, mixin์ ์ฌ์ฉํด์๋ง ๋ค์ค์์์ด ๊ฐ๋ฅํด ์ก๋ค.
์ด์ ๋ฒ์ ์ ๋ค์ค์์ ๊ธฐ๋ฅ์ธ with์ ๋ํด์ ๊ถ๊ธํ์๋ค๋ฉด ์๋ ๊ธ์ ์ฐธ๊ณ ํ์๊ธธ ๋ฐ๋๋ค.
- [Dart] Class ์ด ์ ๋ฆฌ (์์ / ์ฌ์ ์ / ์ถ์ํ)
์ฌ๊ธฐ์๋ mixin์ ์ฌ์ฉํ ๋ค์ค์์๋ง ๋ค๋ฃจ๋๋ก ํ๊ฒ ๋ค.
Dart์์ mixin์ ๋ํ ์ค๋ช ์ ๋ญ๋ผ๊ณ ํ๊ณ ์์๊น ?
"๋ค์์ ํด๋์ค ๊ณ์ธต์์ ํด๋์ค์ ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค."
์ด์ ์๋ with๋ฅผ ์ฌ์ฉํด ๋ค์ค์์์ ํ ์ ์์์๋ค.
class A {}
class B {}
class C extends A with B {}
์ด์ ๋ค์ค์์์ ํ๊ธฐ ์ํด์๋ mixin์ ํด์ฃผ๋ฉด ๋๋ค.
class A {}
mixin B {}
class C extends A with B {}
์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก mixin์ ๋ํด์ ์์ธํ ๋ค๋ค๋ณด๋๋ก ํ์. ์ฐธ๊ณ ๋ก ๊ธฐ๋ฅ์ด ์๊ฐ๋ณด๋ค ๋ง๋ค.
๋จผ์ mixin ํด๋์ค๋ฅผ ์์ ํด๋์ค(์๋ธํด๋์ค)์์ ์ฌ์ฉํ ๋์๋ with ํค์๋๋ฅผ ์ฌ์ฉํด ๋ค์ค์์ ํ ์ ์๋ค.
์ฌ๊ธฐ์ with๋ mixin์ ์ํ ํค์๋๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค. mixin์ผ๋ก ์์ฑ๋ ํด๋์ค๋ฅผ ์์ ๋ฐ๊ธฐ ์ํด์๋ ๋ฐ๋์ with ํค์๋๊ฐ ์์ด์ผ๋ง ์์์ด ๊ฐ๋ฅํ๋ค.
A ํด๋์ค๋ ์ผ๋ฐ ํด๋์ค์ด๊ณ , B๋ mixin์ผ๋ก ์์ฑํ์๋ค.
C ํด๋์ค์์ ๋ค์ค์์์ ์ํด ์ผ๋ฐ ํด๋์ค์ธ A ํด๋์ค๋ฅผ extends ์์์ ๋ฐ๊ณ , with ํค์๋๋ฅผ ์ฌ์ฉํด mixin์ผ๋ก ์์ฑํ B๋ฅผ ์์ ๋ฐ๊ฒ ๋๋ฉด C ํด๋์ค๋ A์ ์์์ B์ ์์๋ฅผ ๋ชจ๋ ์์ ๋ฐ์ ์ ์๊ฒ ๋๋ค.
class A {
void logA() => print("A Class");
}
mixin B {
void logB() => print("B Mixin");
}
class C extends A with B {}
C ํด๋์ค๋ A์ B์ ๋ฉ์๋๋ฅผ ๋ชจ๋ ์ฌ์ฉํ ์ ์๊ฒ ๋์๋ค.
void main() {
C c = C();
c.logA();
// A Class
c.logB();
// B Mixin
}
์ฐธ๊ณ ๋ก mixin ํด๋์ค๋ก ์์ฑ๋ ํด๋์ค๋ฅผ implements ์์์์๋ ์ฌ์ฉํ ์ ์๋๋ฐ, with ํค์๋ ์์ด ์ฌ์ฉํ๋ฉด ๋๋ค.
ํ์ง๋ง implements ์์์ผ๋ก mixin ํด๋์ค๋ฅผ ์์ ๋ฐ๋๋ผ๋, ์์ ํด๋์ค(์๋ธํด๋์ค)์์ ๋น์ฐํ ์ฌ์ ์(override)ํด์ผ ํ๋ค.
mixin A {
void logA();
}
mixin B {
void logB();
}
mixin ํด๋์ค๋ก ์์ฑ๋ A, B ํด๋์ค๋ฅผ ๋จ์ผ ํด๋์ค๋ง ์์ ๋ฐ์๋ ๋๊ณ , ๋ค์ค์์ ๋ฐ์๋ ๋๋ค.
class C implements A, B {
void logA() => print("A mixin");
void logB() => print("B mixin");
}
๋ค์ extends๋ฅผ ์ฌ์ฉํ ๋ค์ค์์์ ์ํ mixin ์์์ผ๋ก ๋์์ค์.
์ฟ๋ฐ ํด๋์ค๊ฐ ์์ด mixin ํด๋์ค๋ง ๋ค์ค์์ํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น ?
with ํค์๋๋ก extends ์์ด๋ ๋ค์ค์์์ด ๊ฐ๋ฅํ๋ค.
mixin A {
void logA() => print("A mixin");
}
mixin B {
void logB() => print("B mixin");
}
class C with A, B {}
์ฌ๊ธฐ์ ํ ๊ฐ์ง ์๋ฌธ์ ์ด ๋ฐ์ํ๋ค. ๋ง์ผ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ ๋ฉ์๋๊ฐ ๋์ผํ๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น ?
A,B ํด๋์ค๋ ๊ฐ๊ฐ log() ๋ผ๋ ๋์ผํ ๋ฉ์๋๊ฐ ์กด์ฌํ๋ค. ๋ ๊ฐ์ ํด๋์ค ์ค ์ด๋ ๋ฉ์๋๊ฐ ์คํ์ด ๋ ๊น ? ์๋๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ ๊น ?
mixin A {
void log() => print("A mixin");
}
mixin B {
void log() => print("B mixin");
}
class C with A, B {}
์ ๋ต์ B์ ๋ฉ์๋๊ฐ ์คํ์ด ๋์๋ค.
void main() {
C c = C();
c.log();
// B mixin
}
mixin ๋ค์ค์์์ ๋์ผ ๋ฉ์๋์ ๋ํด ์ฐ์ ์์๊ฐ ์ ํด์ ธ ์๋ค.
๋ฐ๋ก with ํค์๋์ ๊ฐ์ฅ ๋ง์ง๋ง mixin ํด๋์ค ๋ถํฐ ์ฐ์ ์์๋ฅผ ๊ฐ๊ฒ ๋๋ค.
ํ ์คํธ๋ฅผ ํด๋ณด์. D mixin ํด๋์ค๋ฅผ ์ถ๊ฐ๋ก ์์ฑํด๋ณด์.
mixin D {
void log() => print("D mixin");
}
D mixin ํด๋์ค๊ฐ ๊ฐ์ฅ ์ฐ์ ์์๊ฐ ๋๋๋ก ๋ค์ค์์์ ํ๋๋ก ํ์.
class C with A, B, D {}
์์๋๋ก D์ ๋ฉ์๋๊ฐ ์คํ์ด ๋์๋ค.
void main() {
C c = C();
c.log();
// D mixin
}
๋์ผํ ๊ตฌ์กฐ์์ A ํด๋์ค๋ง ์ผ๋ฐ ํด๋์ค๋ก ๋ณ๊ฒฝํด ์ฃผ์.
class A {
void log() => print("A mixin");
}
class C extends A with B, D {}
๊ฒฐ๊ณผ๋ ๋์ผํ๊ฒ with ํค์๋์ ๊ฐ์ฅ ๋ง์ง๋ง mixin ํด๋์ค์ ๋ฉ์๋๊ฐ ์คํ์ด ๋๋ค.
void main() {
C c = C();
c.log();
// D mixin
}
mixin ๋ค์ค์์์์๋ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ ์์๋ฅผ ๊ธฐ์ค์ผ๋ก ์ฐ์ ์์๊ฐ ์ ํด์ง๊ธฐ ๋๋ฌธ์, with ํค์๋์ ๋ฐ๋ฅธ ์์๋ฅผ ์ฃผ์ํด์ ์ฌ์ฉํด์ผ ํ๋ค.
๋ฉ์๋ ์ธ์๋ ๋ฉค๋ฒ๋ณ์์ ์ฐ์ ์์๋ ๋์ผํ๋ค.
mixin A {
final String name = "A";
}
mixin B {
final String name = "B";
}
class C with A, B {}
void main() {
C c = C();
print(c.name);
// B
}
on ํค์๋์ ๋ํด์๋ ์์๋ณด๋๋ก ํ์.
mixin ์์๋ on ํค์๋์ ๋ํ ์ค๋ช ์ด๋ค.
Sometimes you might want to restrict the types that can use a mixin.
For example, the mixin might depend on being able to invoke a method
that the mixin doesnโt define.
As the following example shows, you can restrict a mixinโs use
by using the on
keyword to specify the required superclass:
on ํค์๋๋ mixin์ ์ฌ์ฉ์ ํน์ ํด๋์ค ๋ด์์ ์ ํํ๊ณ ์ถ์ ๋ ์ฌ์ฉํ ์ ์๋ ํค์๋์ด๋ค.
mixin์ผ๋ก ์์ฑ๋ ํด๋์ค์ ์์์ ํน์ ํด๋์ค๋ฅผ ์์ ๋ฐ์์ ๋์๋ง, ์์์ด ๊ฐ๋ฅํ๋๋ก ์ ์ดํ ์ ์๋ค๋ ์๋ฏธ๋ค.
์ฝ๋๋ฅผ ํตํด ์ด๋ป๊ฒ ํน์ ํด๋์ค์์๋ง ์ฌ์ฉ ๊ฐ๋ฅํ๋๋ก mixin ํด๋์ค๋ฅผ ์์ฑํ ์ ์๋์ง ์์๋ณด์.
๋๋ฐ์ด์ค์ ์ฌ์ฉํ ์ ์๋ ๊ธฐ๋ฅ์ ๋ง๋ ๋ค๊ณ ๊ฐ์ ํด ๋ณด์.
ํ์ง๋ง ๋๋ฐ์ด์ค๋ง๋ค ์ฌ์ฉ ๊ฐ๋ฅํ ๊ธฐ๋ฅ์ด ์๊ณ , ์ฌ์ฉํ ์ ์๋ ๊ธฐ๋ฅ์ด ์์ ๊ฒ์ด๋ค.
Phone๊ณผ PC ํด๋์ค๋ฅผ ์์ฑํ๊ณ , ๋ฉค๋ฒ๋ณ์๋ก name์ ์ถ๊ฐํด ์ฃผ์๋ค.
abstract class Phone {
String get name;
}
abstract class PC {
String get name;
}
์ด์ ๊ธฐ๋ฅ๋ค์ ์์ฑํด ์ฃผ๋๋ก ํ๊ฒ ๋ค. Photo ํด๋์ค๋ ์ฌ์ง์ฒฉ ๊ธฐ๋ฅ์ ๊ฐ์ง๊ณ ์๊ณ , Lock ํด๋์ค๋ ๋๋ฐ์ด์ค ์ ๊ธ์ ๋ํ ๊ธฐ๋ฅ์ ๊ฐ์ง๊ณ ์๋ค.
mixin Photo {
void openPhotos() => print("์ฌ์ง์ฒฉ ์คํ !");
}
mixin Lock {
void unLock() => print("์ ๊ธ ํด์ !");
}
๊ทธ๋ฐ๋ฐ, ์ฌ๊ธฐ์ ์ถ๊ฐ๋ก ์นด๋ฉ๋ผ๋ก ์ฌ์ง์ ์ฐ๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ Camera ํด๋์ค๋ฅผ ์ถ๊ฐํ๋๋ก ํ์. ๋ค๋ง, ์นด๋ฉ๋ผ ๊ธฐ๋ฅ์ PC ํด๋์ค์์๋ ์์๋ฐ์ง ๋ชปํ๊ฒ ํ๊ณ , Phone ํด๋์ค์์๋ง ์์ ๋ฐ์ ์ ์๋๋ก ํด์ฃผ์.
์ด๋ด ๋ ์ฌ์ฉํ๋ ํค์๋๊ฐ ๋ฐ๋ก on ํค์๋์ด๋ค.
์ด์ Camera ํด๋์ค๋ Phone ํด๋์ค๋ฅผ ์์ ๋ฐ์ ์์ ํด๋์ค(์๋ธํด๋์ค)์์๋ง ์ฌ์ฉ ํ๋๋ก ์ ํ์ด ๋์๋ค.
mixin Camera on Phone {
void takePicture() => print("์ฌ์ง ์ดฌ์ !");
}
๊ธฐ๋ฅ์ ๋ํ ํด๋์ค๋ ๋ชจ๋ ์์ฑ ํ์ผ๋, ์ด์ IPhone ํด๋์ค๋ฅผ ์์ฑํ๊ณ ๋ค์ค์์์ผ๋ก Phone, Photo, Lock, Camera ํด๋์ค๋ฅผ ๋ฐ๋๋ก ํ์.
class IPhone extends Phone with Photo, Lock, Camera {
String get name => "iPhone 15";
}
์ด๋ฒ์๋ Macbook ํด๋์ค๋ฅผ ์์ฑํ๊ณ PC, Photo, Lock ํด๋์ค๋ฅผ ๋ค์ค์์ ๋ฐ๋๋ก ํ์.
class Macbook extends PC with Photo, Lock {
String get name => "Macbook";
}
Macbook ํด๋์ค์ ์ถ๊ฐ๋ก Camera ํด๋์ค๋ฅผ ์์์ ์ถ๊ฐํด๋ณด์.
class Macbook extends PC with Photo, Lock, Camera {
String get name => "Macbook";
}
์ด๋ ๊ฒ ๋๋ฉด Camera ํด๋์ค์ ์๋ฌ๊ฐ ๋ฐ์ํ ๊ฒ์ด๋ค.
'Camera' can't be mixed onto 'PC' because 'PC' doesn't implement 'Phone'.
Try extending the class 'Camera'.
Phone ํด๋์ค์์๋ง ์์ ๋ฐ์ ์ ์๋ค๋ ๋ด์ฉ์ด๋ค.
Camera ํด๋์ค๋ Phone์ ์์ ๋ฐ์์ผ์ง๋ง ์ฌ์ฉ ๊ฐ๋ฅํ๋๋ก ์ ํ ํ์๊ธฐ ๋๋ฌธ์, ๋ฐ๋์ Phone ํด๋์ค๋ฅผ ์์ ๋ฐ๊ฒ ๋์ด์๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์, Phone ํด๋์ค์ ๋ฉค๋ฒ๋ณ์(member variable), ๋ฉ์๋(method)์ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๊ฒ ๋๋ค.
mixin Camera on Phone {
void takePicture() => print("$name ์ฌ์ง ์ดฌ์ !");
}
์ผ๋ฐ ํด๋์ค๋ง ์์์ ์ ํํ ์ ์๋ ๊ฒ์ ์๋๊ณ , mixin ํด๋์ค๋ ๊ฐ๋ฅํ๋ค.
mixin A {}
mixin B on A{}
on ํค์๋์๋ ์ฌ๋ฌ ๊ฐ์ mixin ์ ์ถ๊ฐํ์ฌ๋ ๋๋ค. ๋จ ์ด๋ ๊ฒ ๋๋ฉด ์ถ๊ฐ๋ ๋ชจ๋ mixin์ ๋จผ์ ์์ ๋ฐ์์ผ๋ง ํ๋ค.
mixin A {}
mixin B {}
mixin C on A, B {}
์๋ ์ฝ๋๋ A, B ํด๋์ค์์๋ง ์ฌ์ฉ ๊ฐ๋ฅํ๋๋ก C ํด๋์ค๋ฅผ ์ ํ ํ์๋๋ฐ, B ํด๋์ค๊ฐ ์์๋์ง ์์๊ธฐ ๋๋ฌธ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
class Test with A, C {}
์๋ ์ผ์ด์ค๋ B๋ฅผ ์ถ๊ฐ ํ์๋๋ฐ๋ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค. ์ฌ์ฉ์ด ๋ถ๊ฐ๋ฅํ ์ฝ๋๋ค.
์์ ์ผ์ด์ค์์๋ B๋ฅผ ์ถ๊ฐํ์ง ์์๊ธฐ ๋๋ฌธ์ ์๋ฌ๊ฐ ๋ฐ์ ํ์๋๋ฐ, ์๋ ์ฝ๋๋ ์ ์๋ฌ๊ฐ ๋ฐ์ํ ๊น ?
class Test with A, C, B {}
์ด์ ๋ ์์์ ์๋ค. C ํด๋์ค๋ฅผ A, B ํด๋์ค๊ฐ ์์๋ ๊ฒฝ์ฐ์๋ง ์์ ๊ฐ๋ฅํ๋๋ก ์ ํ ํ์๊ธฐ ๋๋ฌธ์, ์์ ์ด๋ฃจ์ด์ง๋ ์์ ํด๋์ค(์๋ธํด๋์ค)์์๋ on ํค์๋๋ก ์ ํํ ํด๋์ค๋ฅผ ๋จผ์ ์์ ๋ฐ์์์ผ๋ง ํ๊ฒ ๋๋ค.
A, B ํด๋์ค๊ฐ ๋จผ์ ์์์ ์ถ๊ฐํด์ผ C ํด๋์ค๋ฅผ ์์ ๋ฐ์ ์ ์๊ฒ ๋๋ค.
class Test with A, B, C {}
์ด๋ฒ์๋ ์ข ๋ ๋ณต์กํ๊ฒ ๋ค์ค์์์ ์ ํํ๋๋ก ํด๋ณด์.
A๋ฅผ ์์ฑํ๊ณ , B๋ Aํด๋์ค๊ฐ ์์๋ ๊ฒฝ์ฐ์๋ง ์์์ด ๊ฐ๋ฅํ๋๋ก ํ๊ณ , C๋ B์ ์์์ด ์ด๋ฃจ์ด์ ธ์ผ๋ง ์์์ด ๊ฐ๋ฅํ๋๋ก ํด์ฃผ์๋ค.
ํด๋น ์ผ์ด์ค์์ A๋ฅผ ์ ์ธํ๊ณ ๋ ์ ๋ถ ํน์ ํด๋์ค์์๋ง ์์์ด ๊ฐ๋ฅํ๊ฒ ๋์๋ค.
mixin A {}
mixin B on A {}
mixin C on B {}
A ํด๋์ค๋ ์ ํ์ด ์๊ธฐ ๋๋ฌธ์ ๋น์ฐํ ์์์ด ๊ฐ๋ฅํ๋ค.
class Test with A {}
C ํด๋์ค๋ฅผ ์์ ๋ฐ์๋ณด์. C๋ B ํด๋์ค๊ฐ ์์ ๋์ด์ผ๋ง ๊ฐ๋ฅํ๊ธฐ์ B๋ฅผ ๋จผ์ ์์ํด ์ฃผ๋๋ก ํ์๋ค.
ํ์ง๋ง ์ญ์๋ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค. B๋ A ํด๋์ค๊ฐ ์์๋ ์ํ์์๋ง ์์์ด ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ด๋ค.
class Test with B, C {}
๊ฒฐ๊ตญ on ํค์๋๋ก ์ ํ๋ ํด๋์ค์์์ ์์์ ๊ตฌํํ ๋์๋ ๊ตฌ์กฐ์ ์ค๊ณ์ ๋ํด ๊ณ ๋ฏผ์ ํด๋ด์ผ ํ ๊ฒ์ด๋ค.
class Test with A, B, C {}
๋ณต์กํ๋๋ผ๋ on ํค์๋๋ก ํน์ ํด๋์ค์์๋ง ์์์ด ๊ฐ๋ฅํ๋๋ก ์ ํํ๊ฒ ๋๋ฉด, ์๋ชป๋ ์์์ ์ฌ์ ์ ์ ์ดํ ์ ์๊ฒ ๋๋ค.
mixin์ ์ฌ์ฉํ ๊ฐ๋จํ ์์ ๋ฅผ ๋ง๋ค์ด๋ณด์.
ํฌ๋ฅด์ ์๋์ฐจ์ ํน์ง ๋ฐ ์์ฑ์ ๋ํ ๊ธฐ๋ฅ์ ๋ง๋ ๋ค๊ณ ๊ฐ์ ํด๋ณด์.
๋จผ์ , ์๋์ฐจ์ ์ข ๋ฅ๋ฅผ ๋ํ๋ด๋ ElectircCar(์ ๊ธฐ์ฐจ), EngineCar(๋ด์ฐ๊ธฐ๊ด์ฐจ), HybridCar(ํ์ด๋ธ๋ฆฌ๋์ฐจ) ํด๋์ค๋ฅผ ๊ฐ๊ฐ ์ถ์(abstract)ํด๋์ค๋ก ์์ฑํด ์ฃผ์.
abstract class ElectricCar {}
abstract class EngineCar {}
abstract class HybridCar {}
์๋์ฐจ์ ์ข ๋ฅ๋ฅผ ์์ฑํ์๊ณ , ๋ค์์ผ๋ก๋ ๋ถํ์ด๋ ์์ฑ๋ค์ ๋ํ ํด๋์ค๋ฅผ ๋ง๋ค์ด๋ณด๋๋ก ํ์.
์๋์ฐจ์ ์ฌ์ฉ๋ ๋๋ ฅ์์ธ Electric(์ ๊ธฐ), Engine(์์ง)์ mixin ํด๋์ค๋ก ์์ฑํด ์ฃผ์๋ค.
mixin Electric {}
mixin Engine {}
์ฐ๋ฃ ๋ถ๋ถ์ ๋ง๋ค์ด ์ค ๊ฒ์ธ๋ฐ, Fuel(์ฐ๋ฃ) ํด๋์ค๋ ๋ฐ๋์ Engine(์์ง) ํด๋์ค๋ฅผ ์์ ๋ฐ์ ํด๋์ค์์๋ง ์ฌ์ฉ ๊ฐ๋ฅํ๋๋ก ํด์ฃผ์๋ค.
์ฐ๋ฃ์ ์ข ๋ฅ์ธ Gasoline(ํ๋ฐ์ ), Diesel(๊ฒฝ์ ) ํด๋์ค๋ Fuel(์ฐ๋ฃ), Engine(์์ง) ํด๋์ค๋ฅผ ์์ ๋ฐ์์ผ๋ง ์ฌ์ฉ ๊ฐ๋ฅํ๋๋ก ์ ํ ํ์๋ค.
mixin Fuel on Engine {}
mixin Gasoline on Engine, Fuel {}
mixin Diesel on Engine, Fuel {}
์ด๋ฒ์๋ Battery ํด๋์ค๋ฅผ ์์ฑํ๋๋ฐ, ๋๋ ฅ์์ธ Electric(์ ๊ธฐ) ํด๋์ค์์๋ง ์์ ๋ฐ๋๋ก ์ ํํ๊ณ , ๋ฐฐํฐ๋ฆฌ๋ฅผ ์ถฉ์ ํ Charger(์ถฉ์ ๊ธฐ) ๋ถํ์ Electric, Battery ํด๋์ค๋ฅผ ์์ ๋ฐ์ ํด๋์ค์์ ์ฌ์ฉ์ ์ ํํ์๋ค.
mixin Battery on Electric {}
mixin Charger on Electric, Battery {}
๋ง์ง๋ง ๋ถํ์ผ๋ก DPF(์ฐ๋ฃ์ ๊ฐ์ฅ์น) ํด๋์ค๋ฅผ ์์ฑํ๋๋ฐ, ํด๋น ๋ถํ์ Engine(์์ง), Fuel(์ฐ๋ฃ), Diesel(๊ฒฝ์ ) ์์ฑ์ ์์ ๋ฐ์์ผ๋ง ์ฌ์ฉ์ด ๊ฐ๋ฅํ๊ณ , ๋ง์ผ Gasoline(ํ๋ฐ์ )๋ฅผ ์ฐ๋ฃ๋ก ์ฌ์ฉํ๋ฉด, ์์ ๋ฐ์ ์ ์๋๋ก ํด์ฃผ์๋ค.
mixin DPF on Engine, Fuel, Diesel {}
์ ์ด์ ์๋์ฐจ์ ์ข ๋ฅ ๋ถํฐ ๋ถํ๊น์ง ์ถ์ํ๋ฅผ ํ์์ผ๋, ๊ฐ ๋ชจ๋ธ๋ง๋ค ํน์ง ๋ฐ ์์ฑ์ ๋ค์ค์์ ๋ฐ์ ์ ์๋๋ก ํด์ฃผ์
class Boxter extends EngineCar with Engine, Fuel, Gasoline {}
class Taycan extends ElectricCar with Electric, Battery, Charger {}
class Cayenne extends EngineCar with Engine, Fuel, Diesel, DPF {}
class PanameraHybrid extends HybridCar with Engine, Electric, Fuel, Gasoline, Battery, Charger {}
์ฝ๊ณ ๊ฐ๋จํ๊ฒ mixin์ ์ฌ์ฉํด ์ฌ๋ฌ ํด๋์ค์ ํน์ง์ด๋ ์์ฑ๋ค์ ๋ค์ค์์ ๋ฐ์ ์ฌ์ฌ์ฉ์ฑ์ ๋ํ๋ฉด์, ํ์ฅ์ฑ ์๋ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค ์ ์๋ค.
๋๋์ด ์์์ ๋ํ ๋ถ๋ถ์ด ๋์ด ๋ฌ๋ค.
๋จ์ผ ํด๋์ค๋ฅผ ์์ ๋ฐ๋ ๋ฐฉ๋ฒ ๋ถํฐ ๋ค์ค์์ ๊น์ง๋ฅผ ์ดํด ๋ดค์ผ๋ฉฐ, extends, implements, mixin์ ์ฌ์ฉํ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์ ์์ฑ์ ์์ ํด๋์ค(์๋ธํด๋์ค)์์ ์์ ๋ฐ๋ ๋ฐฉ๋ฒ ๋ฐ ์ฌ์ฉ ๋ฐฉ๋ฒ ๋ฐ ํน์ง์ ๋ํด์๋ ์์๋ดค๋ค.
์์ ๋ถ๋ถ์ ์ต์ํ์ง ์์ผ๋ฉด, ์ด๋ ค์ด ๋ด์ฉ์ด๋ ์ต์ํด์ง ๋๊น์ง ์ฐ์ต์ ๋ง์ด ํด๋ณด์๊ธธ ๋ฐ๋๋ค.
Flutter๋ก ํด๋์ค(class)๋ฅผ ๋ค๋ฃจ๋ค ๋ณด๋ฉด ์์ฃผ ์ ํ๋ ํค์๋ ์ค์ ํ๋๊ฐ ๋ฐ๋ก factory ํค์๋์ด๋ค.
factory ํค์๋์ ๋ํ์ ์ธ ์ฌ์ฉ์ JSON ์ง๋ ฌํ๋ฅผ ์์ฑํ ๋์ ์ฌ์ฉ๋๊ธฐ์ ๋ฏ์ ํค์๋๋ ์๋ ๊ฒ์ด๋ค.
๊ทธ๋ ๋ค๋ฉด factory๋ ๋ญ๊น ?
์ฉ์ด์ ํด์์ผ๋ก ๋ณด๋ฉด, ๊ณต์ฅ์ ๋ ์ฌ๋ฆด ์๊ฐ ์์ด ์ธ์คํด์ค๋ฅผ ์์ฐํด๋ด๋ ๊ณต์ฅ์ด๋ผ๊ณ ์๊ฐํ ์ ์์ง๋ง, ๊ณต์ฅ๋ณด๋ค๋ ์ฐฝ๊ณ (warehouse)์ ๊ธฐ๋ฅ์ ๊ฐ์ง๊ณ ์๋ค๊ณ ๋ณด๋ ๊ฒ์ด ๋ ์ ํฉํ๋ค.
๋ํ factory๋ ํค์๋์ด๊ธฐ๋ ํ๊ณ , ํจํด(Pattern) ์ด๊ธฐ๋ ํ๋ค.
๋จผ์ ํค์๋๋ก factory์ ์ญํ ์ด ๋ฌด์์ธ์ง ์์๋ณด๋๋ก ํ์.
factory ํค์๋๋ ์์ฑ์(constructor)์ ์ ์ฌํด ๋ณด์ด์ง๋ง ์์ ํ ๋ค๋ฅธ ์ญํ ๊ณผ ํน์ง์ ๊ฐ์ง๊ณ ์๋๋ฐ, ์์ฑ์(constructor)๊ฐ ํธ์ถ์๋ง๋ค ์ธ์คํด์ค(instance)๋ฅผ ์์ฐํ๋ ๊ฒ๊ณผ๋ ๋ค๋ฅด๊ฒ factory๋ ์ด๋ฏธ ์์ฐ๋ ์ธ์คํด์ค(instance)๊ฐ ์๋ค๋ฉด ์ด๋ฅผ ๋ฐํํ์ฌ ์ฌ์์ฐ ํ๋ค๋ ํน์ง์ด ์๋ค. ๋ํ ์๋ธํด๋์ค์ ์ธ์คํด์ค(instance)๋ฅผ ๋ฐํํ ์ ์๋ ์ญํ ์ ๋ง๋ค์ด ์ค ์ ์๋ค.
์์ ์ค๋ช ์ค ์ธ์คํด์ค(instance)๊ฐ ์๋ค๋ฉด ์ด๋ฅผ ๋ฐํํ์ฌ ์ฌ์์ฐ ํ๋ค๋ ํน์ง์ ์ฑ๊ธํค ํจํด(Singleton Pattern) ์ผ๋ก ์ดํดํ๊ณ ์ค๋ช ํ๋ ๊ธ๋ค์ด ๋ง์๋ฐ, factory๋ ์ฑ๊ธํค ํจํด(Singleton Pattern) ๋ด์์ ์ฌ์ฉ๋ ๋์๋ง ์ธ์คํด์ค(instance)๋ฅผ ์์ฐํ์ง ์๋๋ก ์ ์ดํ ์ ์๊ณ , ์ผ๋ฐ ํด๋์ค ๋ด์์๋ ์ฌ๋ฌ ์ ํ์ ์ธ์คํด์ค(instance)๋ฅผ ์์ฐํ๊ณ ์ ์ดํ ์ ์๋ ํน์ง์ ๊ฐ์ง๋ค๋ผ๊ณ ์ดํดํ๋ฉด ๋๋ค.
์ฑ๊ธํค ํจํด(Singleton Pattern) ์ ๋ํด์๋ ์๋์์ ์์ธํ ๋ค๋ฃจ๊ฒ ๋ ๊ฒ์ด๋ค.
์ง๊ธ๊น์ง ์ค๋ช ์ผ๋ก๋ ์ดํด๊ฐ ์๋๊ฒ ์ง๋ง, ์ ํ ๋ณต์กํ ๋ด์ฉ์ด ์๋๋ค.
Device ํด๋์ค๋ฅผ ์์ฑํด์ฃผ์.
class Device {
final int id;
final String name;
const Device(this.id, this.name);
}
factory๋ฅผ ์์ฑํด์ฃผ์.
factory๋ ๋ฐ๋์ ํด๋น ํด๋์ค๋ฅผ ๋ฐํํ ์ ์๊ณ , ๋ค๋ฅธ ์ ํ์ ํ์ ์ ๋ฐํํ ์ ์๋ค.
class Device {
final int id;
final String name;
const Device({required this.id, required this.name});
factory Device.test() => Device(id: 1, name: "name");
}
Device ํด๋์ค์ ์ธ์คํด์ค(instance)๋ฅผ ์์ฑ์(constructor)๋ฅผ ์ฌ์ฉํ์ง ์๊ณ , factory๋ฅผ ์ฌ์ฉํด ์ธ์คํด์ค(instance)๋ฅผ ํ ์ ์๋ค.
void main() {
Device test = Device.test();
print(test.name);
// name
}
factory์ ์ ์ฉํ ๋ฐฉ๋ฒ ์ค ํ๋๊ฐ ์ฌ๋ฌ ์ธ์คํด์ค(instance) ์ ํ์ ๋ง๋ค์ด ์ค ์ ์๋ค๋ ๊ฒ์ด๋ค.
Device ํด๋์ค๋ฅผ iPhone, Mac, watch ์ด๋ ๊ฒ 3๊ฐ์ ๊ฐ์ฒด๋ก ๋ง๋ ๋ค๊ณ ๊ฐ์ ํด๋ณด์.
์ด๋ ๊ฒ ๊ฐ๊ฐ ์์ฑํด์ผ ํ๋๋ฐ, ๋ฌธ์ ๋ ํด๋์ค(class)์ ๋ฉค๋ฒ๋ณ์๊ฐ ๋ ๋ง๋ค๋ฉด ๋ถํ์ํ ์ฝ๋๋ฅผ ์์ฑํด์ผ ํ ์๋ ์๋ค.
void main() {
Device iPhone = Device(id: 0, name: "iPhone");
Device mac = Device(id: 1, name: "Mac");
Device watch = Device(id: 2, name: "Watch");
}
์ด๋ด ๋์ factory ํค์๋๋ฅผ ์ฌ์ฉํ ํด๋์ค(class)๋ด์ ์ฌ๋ฌ ์ ํ์ ์ธ์คํด์ค(instance)๋ฅผ ์ถ๊ฐํ ์ ์๋ ๊ธฐ๋ฅ์ ํ์ฉํ๋ฉด ์ข๋ค.
class Device {
final int id;
final String name;
const Device({required this.id, required this.name});
factory Device.iPhone() => Device(id: 0, name: "iPhone");
factory Device.mac() => Device(id: 1, name: "Mac");
factory Device.watch() => Device(id: 2, name: "Watch");
}
๊ฐ๋จํ๊ฒ ์ฌ๋ฌ ์ ํ์ ์ธ์คํด์ค(instance)๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
void main() {
Device iPhone = Device.iPhone();
Device mac = Device.mac();
Device watch = Device.watch();
}
factory ํค์๋๋ฅผ ์ ๊ฐ ์ฃผ๋ก ํ์ฉํ๋ ๋ถ๋ถ์ ๋ฐ๋ก ๊ธฐ๋ณธ ํด๋์ค๋ฅผ ๋ฏธ๋ฆฌ ์์ฑํด์ฃผ๋ ๊ธฐ๋ฅ์ด๋ค.
ํด๋์ค๋ฅผ Nullable๋ก ์ฌ์ฉํ๊ณ ์ถ์ง ์๊ณ , ๊ธฐ๋ณธ ๊ฐ์ ๊ฐ์ง๋ ํด๋์ค๋ฅผ ์์ฑํด์ ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด, factory๋ฅผ ํ์ฉํด ์ฃผ๋ฉด ๋๋ค.
class Device {
final int id;
final String name;
const Device({required this.id, required this.name});
factory Device.empty() => Device(id: 0, name: "");
}
์ด๋ฒ์๋ factory์ ์ฃผ์ ํน์ง ์ค ํ๋์ธ ์๋ธํด๋์ค์ ์ธ์คํด์ค(instance)๋ฅผ ๋ฐํํ ์ ์๋ ํน์ง์ ๋ํด์ ์์๋ณด๊ฒ ๋ค.
Device ํด๋์ค๋ฅผ ์์ฑํด ์ฃผ์.
class Device {
final int id;
const Device(this.id);
}
Phone ํด๋์ค๋ฅผ ์์ฑํ๋๋ฐ, ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)๋ก Device ํด๋์ค๋ฅผ ์์ ๋ฐ๋๋ก ํ์.
class Phone implements Device {
final String model;
const Phone(this.model);
int get id => 0;
}
์ด์ ๋ค์ Device ํด๋์ค๋ก ์์, ์๋ธํด๋์ค์ ์ธ์คํด์ค(instance)๋ฅผ ์์ฑํ ์ ์๋๋ก ์ฝ๋๋ฅผ ์ถ๊ฐํด ์ฃผ์.
Device ํด๋์ค์์ ์๋ธํด๋์ค์ธ Phone ํด๋์ค์ ์ธ์คํด์ค(instance)๋ฅผ ๋ฐํํ ์ ์๊ฒ ๋์๋ค.
class Device {
final int id;
const Device(this.id);
factory Device.phone() => Phone("iPhone");
}
ํฉํ ๋ฆฌ ํจํด(factory Pattern)์ ์์ ๋ฐฐ์ ๋ factory ํค์๋์ ํน์ง์ ํ์ฉํ ๋์์ธ ํจํด ์ค ํ๋๋ก์จ, ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์์ ์๋ ค์ง์ง ์์ ๊ตฌ์ฒด ํด๋์ค๋ฅผ ์์ ํด๋์ค(์๋ธํด๋์ค)์์ ๊ฒฐ์ ํ๊ฒ ํ๋ ํจํด์ด๋ค.
Flutter์์ ํฉํ ๋ฆฌ ํจํด(factory Pattern)์ ์ฃผ๋ก UI ์์ ์ ์ฃผ๋ก ์ฌ์ฉ์ด ๋๊ณ ์๋ค.
Flutter๋ ์ฌ๋ฌ ์ข ๋ฅ์ ํ๋ซํผ์ ๊ฐ๋ฐํ๋ ๋ฉํฐ ํ๋ซํผ ํ๋ ์์ํฌ์ด๋ค ๋ณด๋, UI ์์๋ฅผ ๋ง๋ค ๋์๋ ๊ฐ ํ๋ซํผ ๋ง๋ค ์๋๋๊ฑฐ๋ ๊ตฌํ๋๋ ๋ถ๋ถ์ ๋ค๋ฅด๊ฒ ๊ฐ๋ฐํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ ํฉํ ๋ฆฌ ํจํด(factory Pattern)์ ํ์ฉํ๊ณ ์๋ค. ๋ฌผ๋ก ํฉํ ๋ฆฌ ํจํด(factory Pattern)์ด ํ์์ ์ธ ์์๋ ์๋๋ค. ์ฌ์ฉํ์ง ์๊ณ ๋ ์ผ๋ง๋ ์ง ๊ตฌํ ํ๋๋ฐ๋ ๋ฌธ์ ๊ฐ ์๋ค.
๊ฐ๋จํ ์์ ๋ฅผ ๋ง๋ค์ด๋ณด์.
ํ๋ซํผ๋ณ๋ก ๋ค๋ฅธ ๋์์ ํ๋ ์ปดํฌ๋ํธ๋ค์ ํฉํ ๋ฆฌ ํจํด(factory Pattern)์ ์ฌ์ฉํด ๋ง๋ค์ด๋ณด๋๋ก ํ์.
ํด๋น ๊ธ์ Dart ์ธ์ด๋ง ์ฌ์ฉ๋๊ณ ์๊ณ , Flutter๋ฅผ ์ฌ์ฉํ์ง ์๊ธฐ์ ํ ์คํธ๋ก๋ง ๊ตฌํํ๋๋ก ํ๊ฒ ๋ค.
PlatformComponent ์ถ์(abstract)ํด๋์ค๋ฅผ ์์ฑํด ์ฃผ๋๋ก ํ์.
abstract class PlatformComponent {
void onTap();
}
ํด๋น ํด๋์ค๋ฅผ ์์ ๋ฐ๋ ๊ฐ๊ฐ์ ๋ฒํผ์ ์์ฑํด์ฃผ๋๋ก ํ์.
class AndroidButton implements PlatformComponent {
void onTap() => print("์๋๋ก์ด๋ ๋ฒํผ");
}
class IOSButton implements PlatformComponent {
void onTap() => print("iOS ๋ฒํผ");
}
class WebButton implements PlatformComponent {
void onTap() => print("์น ๋ฒํผ");
}
์ด์ PlatformComponent ์ถ์(abstract)ํด๋์ค์ ํฉํ ๋ฆฌ ํจํด(factory Pattern)์ ์ถ๊ฐํด๋ณด์.
UI ์ปดํฌ๋ํธ ์ค ๋ฒํผ์ ๋ง๋ค์ด ์ค ๊ฒ์ธ๋ฐ, ํ๋ซํผ์ ๊ณ ์ id๋ฅผ ๊ธฐ์ค์ผ๋ก ํ๊ฒ ๋ค. ์ผ๋ฐ์ ์ผ๋ก Flutter์์๋ enum(์ด๊ฑฐํ) ์ ์ฌ์ฉํ๋๋ฐ, Dart ์ธ์ด์๋ enum(์ด๊ฑฐํ) ๊ฐ๋ ์ด ์์ด ์ ์ํ์ ์ฌ์ฉํ์๋ค.
๊ฐ๊ฐ ํ๋ซํผ ๋ณ๋ก ์์ฑํ ๋ฒํผ์ ํฉํ ๋ฆฌ ํจํด(factory Pattern)์ ํตํด ์์ ํด๋์ค(์๋ธํด๋์ค)๊ฐ ๊ธฐ๋ฅ์ ๊ฒฐ์ ํ ์ ์๋๋ก ํ์๋ค.
abstract class PlatformComponent {
void onTap();
factory PlatformComponent.button(int type) {
return switch (type) {
0 => IOSButton(),
1 => AndroidButton(),
2 => WebButton(),
_ => IOSButton(),
};
}
}
๊ฐ ํ๋ซํผ ๋ณ๋ก ๊ณ ์ ์ ๋ฒํผ์ ์ฌ์ฉํ์ง๋ง, ๋์ผํ๊ฒ ๋ถ๋ชจ ํด๋์ค(์ํผํด๋์ค)์์ ์ธ์คํด์ค(instance) ํ ์ ์๊ฒ ๋์๋ค.
void main() {
PlatformComponent button = PlatformComponent.button(0);
button.onTap();
// iOS ๋ฒํผ
}
ํฉํ ๋ฆฌ ํจํด(factory Pattern)์ ๊ตฌํํ ๋์ factory ํค์๋๋ ์ฌ์ฉํ์ง ์์๋ ๋๋ฉฐ, ์ ์ ๋ฉ์๋(StaticMethod)๋ก๋ ํจํด์ ๋ง๋ค์ด ์ค ์๋ ์๋ค.
์์ ๊ณผ์ ๊ณผ ํท๊ฐ๋ฆด ์๋ ์์ง๋ง, factory์ ํน์ง์ธ ์ฌ๋ฌ ์ ํ์ ์ธ์คํด์ค(instance)๋ฅผ ์ ์ดํ ์ ์๋ค๋ ๊ฒ๊ณผ ์๋ธํด๋์ค์ ์ธ์คํด์ค(instance)๋ฅผ ๋ฐํํ๋ค๋ ํน์ง์ ํ์ํ ๋์์ธ ํจํด์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค.
UI ์ปดํฌ๋ํธ ๊ด๋ฆฌ๋ฅผ ํฉํ ๋ฆฌ ํจํด(factory Pattern)์ ์ฌ์ฉํด ๊ตฌํํด๋ณด๋ฉด ๋ ์ฝ๊ฒ ์ดํดํด ๋ณผ ์ ์๊ณ , UI์์ ํฉํ ๋ฆฌ ํจํด(factory Pattern)์ ์ฅ์ ์ ๋ฐํํ ์ ์๋ ๋ด์ฉ์ ๋ํด์๋ ๋ณ๋๋ก ๊ธ์ ์์ฑํด ๋ณด๋๋ก ํ๊ฒ ๋ค.
ํฉํ ๋ฆฌ ํจํด(factory Pattern)์ ์ํด์ OOP(Object Oriented Programming)์ ๋ํ์ ์ธ ๋์์ธ ํจํด ์ค ํ๋์ธ ์ฑ๊ธํค ํจํด(Singleton Pattern)์ ๋ํด์ ์์๋ณด๋๋ก ํ๊ฒ ๋ค.
์ฑ๊ธํค ํจํด(Singleton Pattern)์ ๊ผญ!! ๋ฐ๋์!! ์๊ณ ์์ด์ผ ํ๋ ๋์์ธ ํจํด์ด๊ธฐ ๋๋ฌธ์, ๊ฐ๋ ์ ํ์คํ ์ดํด์๊ธธ ๋ฐ๋๋ค.
์์ ํฉํ ๋ฆฌ ํจํด(factory Pattern)์ ๋ํด์ ์ดํด๋ณผ ๋์, ์ ์ ์ฑ๊ธํค ํจํด(Singleton Pattern)์ ๋ํด์ ์ธ๊ธํ ์ ์ด ์์๋ค.
์ฑ๊ธํค์ด๋ ํด๋์ค์ ์ธ์คํด์ค์์ ํธ์ถ๋๋ ํด๋์ค์ ๊ฐ์ฒด๋ฅผ ์ฌ๋ฌ ๊ฐ ์์ฑํ์ง ์๊ณ , ์ด๋ฏธ ์์ฑ๋ ์ธ์คํด์ค(instance)๋ฅผ ๋ฐํํ์ฌ ๋จ ํ๋์ ์ธ์คํด์ค(instance)๋ง ์์ฑํ ์ ์๋๋ก ํ๋ ๋ฐฉ๋ฒ์ด๊ณ , ์ฑ๊ธํค ํจํด(Singleton Pattern)์ ์ด๋ฌํ ์ฑ๊ธํค์ ๊ฐ๋ ์ ์ฌ์ฉํ ๋์์ธ ํจํด์ด๋ผ๊ณ ํ ์ ์๋ค.
์ ๊ทธ๋ ๋ค๋ฉด ์ฑ๊ธํค์ผ๋ก ์์ฑ๋ ํด๋์ค์ ์ผ๋ฐ ํด๋์ค์ ์ฐจ์ด์ ์ด ๋ญ๊น ?
์ฐจ์ด์ ์ ํ์ธํ๊ธฐ ์ํด ๊ฐ๋จํ Person ํด๋์ค๋ฅผ ๊ฐ๊ฐ ์ผ๋ฐ ํด๋์ค๋ฅผ ์ฌ์ฉํ GeneralPerson๊ณผ ์ฑ๊ธํค์ผ๋ก ์์ฑํ SingletonPerson ํด๋์ค๋ฅผ ๋ง๋ค์ด ์ฃผ๋๋ก ํ๊ฒ ๋ค.
class GeneralPerson {}
์ผ๋ฐ ํด๋์ค๋ก ์์ฑ๋ GeneralPerson ํด๋์ค์ ์ธ์คํด์ค(instance)๋ฅผ 2๊ฐ๋ฅผ ๋ง๋ค์ด ์ฃผ๋๋ก ํ๊ฒ ๋ค.
void main() {
GeneralPerson general1 = GeneralPerson();
GeneralPerson general2 = GeneralPerson();
}
์ง๊ธ๊น์ง ๊ฒ์๊ธ์ ์ ๋ณด์ จ์ผ๋ฉด, general1 ๊ฐ์ฒด์ general2 ๊ฐ์ฒด๋ ๋์ผ ๊ฐ์ฒด๊ฐ ์๋๋ผ๋ ๊ฒ์ ์ดํดํ์ จ์ ๊ฑฐ๋ค.
์์ง ์ดํด๊ฐ ๋์ง ์์ผ์ จ๋ค๋ฉด, ์ ๋ค๋ฅธ๊ฐ ์๋ฌธ์ด ์๊ธธ ์๋ ์๋๋ฐ, ํด๋์ค๋ฅผ ํตํด ์์ฑ๋ ๊ฐ์ฒด(object)๋ฅผ ์ธ์คํด์ค(instance)๋ผ๊ณ ํ๊ณ , ์์ ๊ณผ์ ์ ์ธ์คํด์คํ๋ผ๊ณ ํ๊ฒ ๋๋ค. ์ฆ, ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ์ฌ๋ ค์ง๊ฒ ๋๋ค๋ ๊ฒ์ธ๋ฐ, ์ธ์คํด์ค(instance)๋ ๊ฐ์ฒด๋ ๊ณ ์ ์ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ํ ๋น ๋ฐ๋๋ค๋ ๊ฒ์ด๋ค.
์ฆ, ๋ฉ๋ชจ๋ฆฌ ์์ญ์ด ์๋ก ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ general1๊ณผ general2๋ ๋น์ฐํ ์๋ก ๋ค๋ฅธ ์ธ์คํด์ค(instance)๊ฐ ๋๋ค. ํ์ธ์ ํด๋ณด์.
ํด๋์ค๋ ๋์ผ ํด๋์ค์ด์ง๋ง, ์ธ์คํด์ค(instance)๋ ๋ค๋ฅธ ๊ฒ์ด๋ค.
void main() {
GeneralPerson general1 = GeneralPerson();
GeneralPerson general2 = GeneralPerson();
print(general1.hashCode);
// 820663644
print(general2.hashCode);
// 26539618
}
๋น๊ต ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ์ฌ๋ ์๋ก ๋ค๋ฅด๋ค๋ ๊ฒ์ ์ ์ ์๋ค.
print(general1 == general2);
// false
๊ทธ๋ ๋ค๋ฉด ์ฑ๊ธํค์ผ๋ก ์์ฑ๋ ์ธ์คํด์ค(instance)๋ ์ด๋ค ์ฐจ์ด์ ์ด ์๋์ง๋ ํ์ธํด ๋ณด์.
์ฑ๊ธํค์ ๋ง๋๋ ์ฝ๋๋ ์๋์์ ์ค๋ช ํ ๊ฒ์ด๋ค. ์ฐ์ ์ฐจ์ด์ ๋ง ํ์ธํด ๋ณด์.
class SingletonPerson {
static final SingletonPerson instance = SingletonPerson._internal();
factory SingletonPerson() => instance;
SingletonPerson._internal();
}
๋์ผํ๊ฒ singleton1, singleton2 2๊ฐ์ ์ธ์คํด์ค(instance)๋ฅผ ์์ฑํด๋ณด์.
void main() {
SingletonPerson singleton1 = SingletonPerson();
SingletonPerson singleton2 = SingletonPerson();
}
์ฑ๊ธํค์ผ๋ก ์์ฑ๋ ์ธ์คํด์ค(instance)์ hashCode๋ฅผ ์ถ๋ ฅํด๋ณด๋ฉด, ๋์ผํ ๊ฐ์ด ๋ฐํ๋๋ ๊ฒ์ ์ ์ ์๊ณ , ๋น๊ต ์ฐ์ฐ์์์๋ true๋ฅผ ๋ฐํํ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ฆ ๋์ผ ์ธ์คํด์ค(instance)์ธ ๊ฒ์ด๋ค.
void main() {
print(singleton1.hashCode);
// 96990887
print(singleton2.hashCode);
// 96990887
print(singleton1 == singleton2);
// true
}
์์ง ์ดํด๊ฐ ๋์ง ์์ผ์ จ๋ค๋ฉด ๋ ๋ค๋ฅธ ์์ ๋ฅผ ๋ง๋ค์ด๋ณด์. ํด๋์ค์ ์ ์ํ count ๋ณ์๋ฅผ ๋ฃ์ด์ฃผ๊ณ , ๊ฐ์ ์ฆ๊ฐ ์์ผ๋ณด๋ฉด์ ์ง๊ด์ ์ผ๋ก ์ฐจ์ด์ ์ ํ์ธํด ๋ณผ ๊ฒ์ด๋ค.
GeneralCount ํด๋์ค๋ฅผ ์์ฑํด์ฃผ์.
class GenralCount {
int count = 0;
}
count1, count2 2๊ฐ์ ์ธ์คํด์ค(instance)๋ฅผ ์์ฑํ๊ณ count1์ count ๊ฐ์ 1 ์ฆ๊ฐํด๋ณด์.
count1 ๊ฐ์ฒด์ count ๊ฐ์ ๋น์ฐํ 1์ด ์ฆ๊ฐ๋ 1๋ก ์ถ๋ ฅ์ด๋๊ณ , count2 ๊ฐ์ฒด๋ ์๋ฌด๊ฒ๋ ํด์ฃผ์ง ์์์ผ๋ 0์ผ๋ก ์ถ๋ ฅ์ด ๋๋ค.
void main() {
GenralCount count1 = GenralCount();
GenralCount count2 = GenralCount();
count1.count = count1.count + 1;
print(count1.count);
// 1
print(count2.count);
// 0
}
๋์ผ ๊ธฐ๋ฅ์ ์ฑ๊ธํค์ผ๋ก ๋ง๋ค์ด๋ณด์.
class SingletonCount {
static final SingletonCount instance = SingletonCount._internal();
factory SingletonCount() => instance;
SingletonCount._internal();
int count = 0;
}
์ด๋ฒ์๋ count1 ๊ฐ์ฒด์ count ๊ฐ๋ง 1 ์ฆ๊ฐ ์์ผฐ๋ค. ๊ฒฐ๊ณผ๋ count2 ๊ฐ์ฒด์ count๋ 0์ด ์๋ 1๋ก ์ถ๋ ฅ์ด๋๋ค.
count1, count2์ ์ธ์คํด์ค(instance)๊ฐ ๋์ผํ๊ธฐ ๋๋ฌธ์ด๋ค.
void main() {
SingletonCount count1 = SingletonCount();
SingletonCount count2 = SingletonCount();
count1.count = count1.count + 1;
print(count1.count);
// 1
print(count2.count);
// 1
}
์ฑ๊ธํค์ ๋ํด ์ดํด๊ฐ ๋์ จ์๊ฑฐ๋ผ ์๊ฐํ๋ค.
์ด์ ์ฑ๊ธํค ํด๋์ค๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์ดํด๋ณด๋๋ก ํ์.
๊ธฐ๋ณธ์ด ๋๋ ์ฑ๊ธํค ๊ตฌ์กฐ์ด๋ค.
class Singleton {
static final Singleton _instance = Singleton._internal();
factory Singleton() => _instance;
Singleton._internal();
}
๋จผ์ ํด๋์ค๋ฅผ ๋ง๋ค์ด ์ฃผ๊ณ , ์ ์ ๋ฉ์๋(static)๋ฅผ ์ฌ์ฉํด ํด๋์ค์ ์ธ์คํด์ค(instance)์ ๊ท์๋ ์ ์๋๋ก ํด์ค๋ค.
Singleton._internal() ์ ์์ฑ์์ธ๋ฐ, ์์ฑ์ ์ด๋ฆ์ private(_) ์์ฑ์๋ก๋ง ๋ง๋ ๋ค๋ฉด, ์ด๋ค ์ด๋ฆ๋ ์๊ด ์๋ค. Dart ์ธ์ด์์๋ ์ด๋ฆ ์๋ ์์ฑ์๋ฅผ ์ ์ธํ ๊ฒฝ์ฐ ์๋์ผ๋ก public ์์ฑ์๊ฐ ๋ง๋ค์ด์ง๊ธฐ์ ์ด๋ฅผ ๋ง๊ธฐ ์ํด์ Dart์ private์ ๋ง๋๋ ์ธ๋๋ฐ(_) ํค์๋๋ฅผ ์ฌ์ฉํด์ฃผ๋ฉด ๋๋ค.
์ฐธ๊ณ ๋ก ์์ฑ์๋ฅผ public ์์ฑ์๋ก ๋ง๋ค๊ฒ ๋๋ฉด, public ์์ฑ์๊ฐ ํธ์ถ๋ ๋๋ง๋ค ์๋ก์ด ์ธ์คํด์ค(instance)๊ฐ ์์ฑ๋๊ธฐ ๋๋ฌธ์ ์ฑ๊ธํค ํด๋์ค๊ฐ ์๋, ์ผ๋ฐ ํด๋์ค๊ฐ ๋๋ค.
์ถ์(abstract)ํด๋์ค๋ฅผ ์ฌ์ฉํด ์ธ์คํด์ค(instance)๋ฅผ ๋ฐํํด์ฃผ๋ฉด ๋๋ค.
์ฑ๊ธํค ํจํด(Singleton Pattern)์ ์ฌ์ฉํ๋ฉด, ์ธ์คํด์ค(instance)๋ฅผ ๋จ ํ๋์ ์ธ์คํด์ค๋ง ์์ฑํ ์ ์์ด ๊ณ ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ฒ ๋๊ณ , ์ฌ๋ฌ ์์ญ์์ ์ธ์คํด์ค๋ฅผ ๊ณต์ ํ๊ณ ์ถ์ ๋์๋, ๋์ผ ์ธ์คํด์ค๋ฅผ ๋ณด์ฅํ ์ ์๋ค๋ ์ฅ์ ์ด ์๋ค. ํ์ง๋ง ๋ฉํฐ์ฐ๋ ๋ฉ ํ๊ฒฝ์ ๊ตฌ์ถํ๊ณ ์ถ์ ๋์, ๋์์ฑ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ผ๋ฉฐ ํ ์คํธ๊ฐ ์ด๋ ต๋ค๋ ๋จ์ ์ด ์๋ค.
ํ๋ก๊ทธ๋๋ฐ ์คํ ๋ถํฐ ์ข ๋ฃ๊น์ง ์ฑ๊ธํค ํจํด(Singleton Pattern)์ผ๋ก ๊ตฌํ๋๋ ํจํด์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํด์ ํ๊ณ , ๊ฐ์ฉ์ํ๋ก ์ ํํด์ฃผ๋ GC(Garbage Collector)์ ๋์์ด ์๋๊ธฐ ๋๋ฌธ์, ์ด์์๋ ์ธ์คํด์ค๋ก ๋จ๊ฒ๋๋ค.
Flutter ๊ฐ๋ฐ์ ํ๋ค๋ณด๋ฉด, ์ฑ๊ธํค ํจํด(Singleton Pattern)์ ๋๋ฆฌ ์ฌ์ฉ๋๋ ๊ธฐ๋ณธ์ ์ธ ํจํด์ด๊ธฐ์ ์์๋๋ฉด ๋ถ๋ช ํ ์ฌ์ฉ ๊ฐ์น๊ฐ ์๋ ๊ธฐ๋ฅ์ด๋ค.
To allow an instance of your Dart class to be called like a function, implement the call() method.
The call() method allows an instance of any class that defines it to emulate a function. This method supports the same functionality as normal functions such as parameters and return types.
Dart ์ธ์ด์ ํด๋์ค๋ฅผ ์ฌ์ฉํด ๋ณด๋ฉด์, call ๋ฉ์๋์ ๋ํด์ ์ฌ์ฉํด ๋ณด์ จ๊ฑฐ๋ ๋ค์ด๋ณธ ์ ์ด ์์ ๊ฒ์ด๋ค.
call ๋ฉ์๋๋ ํด๋์ค(class)์ ์ธ์คํด์ค(instance)๋ฅผ ํจ์ ์ฒ๋ผ ํธ์ถํ ์ ์๋ ๋ฉ์๋์ด๊ณ , ์ผ๋ฐ ํจ์์ ๋์ผํ๊ฒ ๋งค๊ฐ๋ณ์, ๋ฐํ ํ์ ๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ ์ง์ํ๋ค.
์ธ์คํด์ค๋ฅผ ํจ์ ์ฒ๋ผ ํธ์ถํ๋ค๋ ๊ฒ์ ์ด๋ค ์๋ฏธ์ผ๊น ?
User ํด๋์ค๋ฅผ ์์ฑํ๊ณ call ๋ฉ์๋๋ฅผ ๊ตฌํ ํ๋๋ฐ, ๋งค๊ฐ๋ณ์ name์ ์ ๋ ฅ ๋ฐ์ ๋ฌธ์์ด(String)์ ๋ฐํํด ์ฃผ๋๋ก ํด์ฃผ์.
class User {
String call(String name) => "์ฌ์ฉ์ ์ด๋ฆ์ $name ์
๋๋ค";
}
User ํด๋์ค์ ์ธ์คํด์ค user๋ฅผ ํจ์ ํํ๋ก ํธ์ถ์ ํด๋ณด์. ๊ฒฐ๊ณผ๋ ์ ์์ ์ผ๋ก call ๋ฉ์๋๋ฅผ ์คํ์์ผฐ๋ค.
void main() {
User user = User();
String name = user("Tyger");
print(name);
// ์ฌ์ฉ์ ์ด๋ฆ์ Tyger ์
๋๋ค
}
User ํด๋์ค์ call ๋ฉ์๋๊ฐ ์ ์ธ๋์ด ์์ง ์์๋ค๋ฉด, ์ด๋ป๊ฒ ๋ ๊น ? ๋น์ฐํ ์ธ์คํด์ค๋ฅผ ํจ์๋ก ํธ์ถํ๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅํ๊ณ , ์๋ฌ๊ฐ ๋ฐ์ํ๊ฒ ๋๋ค.
call ๋ฉ์๋ ๊ตฌํ์ ๋ฉ์๋ ๋ค์์ ๋ฐ๋์ call() ์ด์ด์ผ ํ๊ณ , call ๋ฉ์๋๋ ํ ๊ฐ๋ง ๋ฑ๋ก์ด ๊ฐ๋ฅํ์ง๋ง ์์ ๊ด๊ณ์ธ ๊ฒฝ์ฐ ํด๋์ค ๋ง๋ค ํธ์ถ ๊ฐ๋ฅํ call ๋ฉ์๋๋ฅผ ๊ตฌํํ ์ ์๋ค.
์ผ๋ฐ ํจ์์ ๋์ผํ๊ฒ ๋งค๊ฐ๋ณ์, ๋ฐํ ํ์ ์ ์ฌ์ฉํ ์ ์๋ค.
class Calculator {
int call(int a, int b, int c) => a + b + c;
}
void main() {
Calculator calculator = Calculator();
int add = calculator(20, 3, 45);
print(add);
// 68
}
User ํด๋์ค์ ๋ฉค๋ฒ๋ณ์๋ก name์ ์ถ๊ฐํด ๋ณด๋๋ก ํ์.
class User {
final String name;
const User(this.name);
}
User ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ์ถ๋ ฅํด๋ณด๋ฉด, "Instance of 'User'" ๋ผ๊ณ ์ถ๋ ฅ์ด ๋๋๋ฐ, call ๋ฉ์๋ ๊ธฐ๋ฅ์ ์ฌ์ฉํด ํด๋์ค์ ๊ตฌ์ฑ ์์๋ฅผ ์ถ๋ ฅํ ์ ์๋๋ก ํ ์๋ ์๋ค.
void main() {
User name = User("Tyger");
print(name);
// Instance of 'User'
}
call ๋ฉ์๋์ ๋ฉค๋ฒ๋ณ์๋ฅผ ์ถ๋ ฅํ ์ ์๋๋ก ํด์ฃผ์.
class User {
final String name;
const User(this.name);
void call() => print(name);
}
์ธ์คํด์ค ๋ค์์ ํจ์๋ก ํธ์ถ๋ง ํ๋ฉด ๋๋ค.
void main() {
User name = User("Tyger");
name();
// Tyger
}
์ด๋ฒ์๋ ์ข ๋ ์ค์ฉ์ ์ธ ์์ ๋ฅผ ์ฌ์ฉํด call ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ๋ณด์.
DateTime ํ์ ์ผ๋ก ๋ ์ง๋ฅผ ์ ๋ ฅ ๋ฐ์ ์ํ๋ ํํ๋ก ํฌ๋งทํ ํ ๋ฌธ์์ด(String) ํ์ ์ ๋ฐํํ๋ call ๋ฉ์๋๋ฅผ ๋ง๋ค๋๋ก ํ๊ฒ ๋ค.
class Watch {
String call(DateTime date) {
return "${date.month.toString().padLeft(2, "0")}์ ${date.day.toString().padLeft(2, "0")}์ผ, ${date.year}๋
";
}
}
watch ์ธ์คํด์ค๋ฅผ ํจ์๋ก ํธ์ถํด ๋ณด๋ฉด ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๊ฒ ๋๋ค.
void main() {
Watch watch = Watch();
String message = watch(DateTime(2000, 1, 1));
print(message);
// 01์ 01์ผ, 2000๋
}
call ๋ฉ์๋๋ ์ฃผ๋ก ๊ตฌํํ๋ ํด๋์ค์ ๊ธฐ๋ฅ์ ์๋์ง๋ง ์์ ๊ด๊ณ์ ํด๋์ค ๊ณ์ธต์์ ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ ๋ฐ ์ ์ฐ์ฑ์ ๋ํ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉ๋๊ธฐ๋ ํ๋ call ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ์ธ์คํด์ค๊ฐ ํจ์๋ก ํธ์ถ์ด ๊ฐ๋ฅ ํ๋ค๋ ๋ถ๋ถ์ ๊ธฐ์ตํ์๋ฉด ๋์์ด ๋ ๊ฒ์ด๋ค.
ํด๋์ค(class)๋ฅผ ๋ค๋ฃฐ ๋์ ์์ฃผ ์ธ๊ธ๋๊ณ ์ ์ธ๋๋ ๋ด์ฉ์ ์ฝ๋๊ฐ ๋ฐ๋ก JSON ์ง๋ ฌํ(serialize)์ด๋ค.
JSON์ ๋ํ ๊ฐ๋ ์ ์๊ธฐ ์ํด์๋ ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์ ํต์ ํ๋ ๋ฐฉ๋ฒ์ธ REST API์ ๋ํ ๊ฐ๋ ๋ ์ ํ ๋์ด์ผ ํ์ง๋ง, ์ฌ๊ธฐ์๋ ์ง๋ ฌํ๋ฅผ ์ํ Dart ํด๋์ค ๊ฐ๋ ๋ฐ ์ฌ์ฉ ๋ฐฉ๋ฒ์ ์ดํดํ๋ ๊ฒ์ ์ง์คํด์ ์ค๋ช ํ ์์ ์ด๋ค.
JSON์ด๋, JavaScriptObjectNotation์ ์ฝ์๋ก ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด ํ๊ธฐ๋ฒ ์ด๋ผ๊ณ ํด์ํ ์ ์๋ค.
ํด๋ผ์ด์ธํธ ์ธก์์ ์๋ฒ๋ก ๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๊ฑฐ๋ ๋ฐ์ดํฐ๋ฅผ ์์ ๋ฐ์๋์ JSON ๊ตฌ์กฐ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๊ฒ ๋๋ค.
JSON ๊ตฌ์กฐ๋ key-value ํํ์ ๊ตฌ์กฐ๋ก Dart ์ธ์ด์ Map ํ์ ๊ณผ ๋น์ทํ ๊ตฌ์กฐ์ด๋ค.
๋ชจ๋ฐ์ผ ํ๋ก๊ทธ๋๋ฐ์์๋ REST API๋ก ์๋ฒ์ ํต์ ์ ํ ๋์, JSON ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๋ค. ๋ฌผ๋ก JSON ์ธ์๋ xml ๊ตฌ์กฐ๋ ์๋ค.
์๋ฒ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๊ธฐ ์ํด Object(๊ฐ์ฒด)๋ฅผ JSON ๊ตฌ์กฐ๋ก ๋ณํํ๋ ๊ณผ์ ์ ์ง๋ ฌํ(serialization)๋ผ๊ณ ํ๊ณ ์๋ฒ๋ก ๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ์์ ๋ฐ์ JSON ๊ตฌ์กฐ๋ฅผ Object(๊ฐ์ฒด)๋ก ๋ณํํ๋ ๊ฒ์ ์ญ์ง๋ ฌํ(deSerialization)๋ผ๊ณ ํ๋ค.
Flutter์์ JSON ์ง๋ ฌํ๋ฅผ ๋ ์ฝ๊ฒ ํ๋ ๋ฐฉ๋ฒ์ ํจํค์ง๋ฅผ ์ฌ์ฉํด์ ํ ์๋ ์๊ณ , ํด๋์ค ๊ตฌ์กฐ๋ฅผ ๊ฐ๋จํ๊ฒ Code Generator๋ฅผ ์ฌ์ฉํด ์๋์ผ๋ก ์ ์ธํด์ฃผ๋ ๊ธฐ๋ฅ์ ์ฌ์ฉํด์๋ ์ฝ๊ฒ ๊ตฌํ์ด ๊ฐ๋ฅํ๋ค.
ํ์ง๋ง ์ด๋ค ๊ณผ์ ์ผ๋ก JSON ์ง๋ ฌํ๋ฅผ ๊ตฌ์ฑํ ์ ์๋์ง ๊ฐ๋
์ ๋๋ ์๊ณ ์์ด์ผ ํ๊ณ , ์ฌ์ง์ด๋ ํจํค์ง ์์ด๋ ๊ตฌ์ฑํ ์ ์์ด์ผ ํจํค์ง๋ฅผ ๋ ์ ์ฌ์ฉํ๊ณ ํ์ฉํ ์ ์๋ค๊ณ ์๊ฐํ๋ค.
๋จผ์ , Dart ๊ฐ์ฒด(object)๋ฅผ ์๋ฒ๋ก ์ ์กํ๊ธฐ ์ํด JSON์ผ๋ก ๋ณํํ๋ ์ฝ๋์ ๋ํด์ ์์ฑํด๋ณด๋๋ก ํ์.
ํด๋์ค๋ฅผ ์์ฑํด๋ณด๋๋ก ํ์.
class Person {
final int id;
final String name;
final DateTime birthday;
final bool gender;
const Person({
required this.id,
required this.name,
required this.birthday,
required this.gender,
});
}
๊ฐ์ฒด(object)๋ฅผ JSON์ผ๋ก ๋ณํํ ์ ์๋๋ก ์ฝ๋๋ฅผ ์ถ๊ฐํด ์ฃผ์.
toJson ๋ฉ์๋๋ฅผ ์ ์ธํด์ฃผ์
class Person {
...
Map<String, dynamic> toJson() {
return {};
}
}
toJson ๋ฉ์๋์์ ๋ฐํ ํ์ ์ผ๋ก Dart key-value ๊ตฌ์กฐ์ธ Map ํ์ ์ ์ฌ์ฉํ๋ฉด ๋๋ค.
Map<String, dynamic> toJson() {
return {
"id": id,
"name": name,
"birthday": birthday,
"gender": gender,
};
}
Person ํด๋์ค์ ์ถ๊ฐํ toJson ๋ฉ์๋๋ฅผ ์ฌ์ฉํด JSON ๊ตฌ์กฐ๋ก ๋ณํํ์ฌ ์๋ฒ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์กํด์ฃผ๋ฉด ๋๋ค.
void main() {
Person person = Person(
id: 0,
name: "tyger",
birthday: DateTime(2000, 1, 1),
gender: true,
);
Map<String, dynamic> data = person.toJson();
print(data);
}
์ฌ๊ธฐ์ Person ํด๋์ค์์ ๊ฐ์ฒด(object) ํ์ ์ด ์๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น ?
์ฃผ์ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์๋ Address ํด๋์ค๋ฅผ ๋ง๋ค์ด๋ณด์.
class Address {
final int postCode;
final String address;
final String detail;
const Address({
required this.postCode,
required this.address,
required this.detail,
});
}
Person ํด๋์ค์ Address ํ์ ์ ๋ณ์๋ฅผ ์ถ๊ฐํด์ฃผ๊ณ , toJson ๋ฉ์๋์๋ address ํ๋๋ฅผ ์ถ๊ฐํด ์ฃผ๋๋ก ํ์.
class Person {
final int id;
final String name;
final DateTime birthday;
final bool gender;
final Address address;
const Person({
required this.id,
required this.name,
required this.birthday,
required this.gender,
required this.address,
});
Map<String, dynamic> toJson() {
return {
"id": id,
"name": name,
"birthday": birthday,
"gender": gender,
"address" : address,
};
}
}
๋ค์ toJson ๋ฉ์๋๋ฅผ ์คํํด ์๋ฒ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น ? ์ ์ก์ ๋ฌธ์ ๊ฐ ์์ด ๋ณด์ด์ง๋ง, ์๋ก ์ถ๊ฐํ Address ๊ฐ์ฒด๋ฅผ JSON ๊ตฌ์กฐ๋ก ๋ณํํ์ง ์๊ณ , ๊ฐ์ฒด(object) ์์ฒด๊ฐ ์ ์ก์ด ๋๊ธฐ ๋๋ฌธ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
void main() {
Person person = Person(
id: 0,
name: "tyger",
birthday: DateTime(2000, 1, 1),
gender: true,
address: Address(
postCode: 15000, address: "๋ํ๋ฏผ๊ตญ ์์ธํน๋ณ์ ...", detail: "XX์ํํธ 101๋ 101ํธ"),
);
Map<String, dynamic> data = person.toJson();
print(data);
}
Address ํด๋์ค์๋ toJson ๋ฉ์๋๋ฅผ ์ถ๊ฐํ์.
class Address {
...
Map<String, dynamic> toJson() {
return {
"postCode": postCode,
"address": address,
"detail": detail,
};
}
}
์ด์ Person ํด๋์ค์ toJson ๋ฉ์๋๋ฅผ ์์ ํด์ฃผ๋๋ก ํ๊ฒ ๋ค.
Map<String, dynamic> toJson() {
return {
"id": id,
"name": name,
"birthday": birthday,
"gender": gender,
"address": address.toJson(),
};
}
์ด๋ฒ์๋ ์๋ฒ๋ก ๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ๋์ JSON ๊ตฌ์กฐ๋ฅผ ๊ฐ์ฒด(object)๋ก ๋ณํํ ์ ์๋ ์ฝ๋๋ฅผ ์์ฑํด ๋ณด๊ฒ ๋ค.
๊ณต์ฅ์์ ์ฃผ๋ฌธ์ ๊ด๋ฆฐํ๊ธฐ ์ํ Order ํด๋์ค๋ฅผ ์์ฑํด๋ณด์.
class Order {
final int id;
final String name;
final DateTime orderAt;
final bool isPreOrder;
const Order({
required this.id,
required this.name,
required this.orderAt,
required this.isPreOrder,
});
}
์ด์ ์๋ฒ๋ก ๋ถํฐ ์ ๋ฌ ๋ฐ๋ JSON ๊ตฌ์กฐ๊ฐ ๊ฐ์ฒด(object)๋ก ๋ณํ๋ ์ ์๋๋ก ์ด๋ฏธ ์์ฐ๋ ์ธ์คํด์ค(instance)๋ฅผ ๋ฐํํ๋ ํฉํ ๋ฆฌ(factory) keyword๋ฅผ ์ฌ์ฉํด fromJson ๋ฉ์๋๋ฅผ ์ถ๊ฐํด ๋ณด๋๋ก ํ์.
toJson ๋ฉ์๋์๋ ๋ค๋ฅด๊ฒ fromJson ๋ฉ์๋๋ ๋งค๊ฐ๋ณ์๋ก ์๋ฒ๋ก ๋ถํฐ ์ ์ก ๋ฐ์ JSON ๊ตฌ์กฐ๋ฅผ ๋ฐ์์ฌ ์ ์๋๋ก ํด์ฃผ์ด์ผ ํ๋ค.
class Order {
...
factory Order.fromJson(Map<String, dynamic> json) => null;
}
JSON ๊ตฌ์กฐ๋ฅผ Map ํ์ ์ผ๋ก ๋ฐ์์จ ํ ๊ฐ์ฒด(object)๋ก ์ธ์คํด์ค(instance)๋ฅผ ๋ฐํ ํด์ฃผ๋ฉด ๋๋ค.
factory Order.fromJson(Map<String, dynamic> json) {
return Order(
id: json["id"],
name: json["name"],
orderAt: json["orderAt"],
isPreOrder: json["isPreOrder"],
);
}
์ด์ ์๋ฒ๋ก ๋ถํฐ ์ ๋ฌ ๋ฐ์ JSON ๋ฐ์ดํฐ๋ฅผ fromJson์ ์ฌ์ฉํด ๊ฐ์ฒด(obejct)๋ก ๋ณํํด ์ฃผ๋ฉด ๋๋ค.
void main() {
Order order = Order.fromJson(data);
print(order);
}
Car ํด๋์ค๋ฅผ ์๋ก ์์ฑํด์ฃผ๊ณ , Order ํด๋์ค์ ๋ณ์๋ก ์ถ๊ฐํด ์ฃผ์.
class Car {
final String name;
final int colorType;
const Car({required this.name, required this.colorType});
factory Car.fromJson(Map<String, dynamic> json) {
return Car(
name: json["name"],
colorType: json["colorType"],
);
}
}
์ถ๊ฐํ Car ํด๋์ค๋ฅผ ์๋์ ๊ฐ์ ๊ตฌ์กฐ๋ก ๋ณํํ ์ ์๋ค. ์ด์ ๋ ์ด๋ฏธ toJson ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ๋ณด๋ฉด์ ์๊ณ ์์ ๊ฒ์ด๋ค. Car ํด๋์ค๋ ๋์ผํ๊ฒ fromJson ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค.
class Order {
...
final Car car;
const Order({
...
required this.car,
});
factory Order.fromJson(Map<String, dynamic> json) {
return Order(
id: json["id"],
name: json["name"],
orderAt: json["orderAt"],
isPreOrder: json["isPreOrder"],
car: json["car"],
);
}
}
JSON์ Dart Map ํ์ ์ ์๋๊ธฐ ๋๋ฌธ์ as ํค์๋๋ฅผ ์ฌ์ฉํด Map ํ์ ๋ณํ์ ์ถ๊ฐํ์ฌ fromJson ๋ฉ์๋์ ์ ๋ฌํด์ฃผ์ด์ผ ํ๋ค.
factory Order.fromJson(Map<String, dynamic> json) {
return Order(
id: json["id"],
name: json["name"],
orderAt: json["orderAt"],
isPreOrder: json["isPreOrder"],
car: Car.fromJson(json["car"] as Map<String, dynamic>),
);
}
์ด๋ฒ์ ๋ฐฐ์ด์ ์ด๋ป๊ฒ JSON์์ ๊ฐ์ฒด(object)๋ก ๋ณํํ ์ ์๋์ง ์ดํด๋ณด์.
Car ํด๋์ค๋ฅผ ๋ฐฐ์ด ํํ๋ก ๋ณ๊ฒฝํด ๋ณด์. ์ด์ ์์ ์์ฑํ fromJson ๋ฉ์๋์ ์๋ฌ๊ฐ ๋ฐ์ํ ๊ฒ์ด๋ค.
class Order {
...
final List<Car> cars;
const Order({
...
required this.cars,
});
}
๋ฆฌ์คํธ ํ์ ์ผ๋ก ์ ๋ฌ ๋ฐ๋ JSON ๊ตฌ์กฐ๋ ๋ฐฐ์ด ์์ ๋ด๊ธด ๊ฐ๊ฐ์ JSON ๊ตฌ์กฐ๋ฅผ map ๋ฉ์๋๋ฅผ ํ์ฉํด ์ํ์ ์ผ๋ก ๊ฐ์ฒด(object)๋ก ๋ณํํ์ฌ ํ์ฑํ๋ฉด ๋๋ค.
factory Order.fromJson(Map<String, dynamic> json) {
return Order(
...
cars: List<Car>.from(json["cars"])
.map((e) => Car.fromJson(e as Map<String, dynamic>))
.toList(),
);
}
ํด๋์ค(class)๋ฅผ ์ ๊ทผํ ์ ์๋ getter, setter์ ๋ํด์ ์์๋ณด์.
getter, setter์ ๋ํด ์ดํด ๋ณด๊ธฐ์ ์ ๊ทผ ์ง์ ์์ ๋ํด์ ์์์ผ ํ๋ค.
Dart ์ธ์ด์์ ํด๋์ค(class)์ ๋ฉค๋ฒ๋ฅผ ์ ์ธํ ๋์๋ ๋ฉค๋ฒ์ ์ ๊ทผ์ด ๊ฐ๋ฅํ์ง ๋ถ๊ฐ๋ฅํ์ง์ ๋ํด ์ ๊ทผ์ ๊ถํ์ ๋ถ์ฌํ๋ ์ ๊ทผ ์ง์ ์๊ฐ ์๋ค.
Dart ์ธ์ด์์ ์ ๊ทผ ์ง์ ์๋ private, public ๋ ๊ฐ์ง์ ๊ฐ๋
์ ์ฃผ๋ก ์ฌ์ฉํ๋๋ฐ, private์ผ๋ก ๋ฉค๋ฒ๋ฅผ ์ ์ธํ๊ฒ ๋๋ฉด ๋์ผ ํ์ผ ๋ด์์๋ง ์ ๊ทผ์ด ๊ฐ๋ฅํ๊ฒ ๋๋ค.
private์ผ๋ก ์ ์ธํ๋ ๋ฐฉ๋ฒ์ ์ธ๋์ค์ฝ์ด(_)๋ฅผ ์ฌ์ฉํ๋ฉด ๋๊ณ , ๊ทธ ์ธ์ ๋ชจ๋ ๋ฉค๋ฒ๋ public์ด ๋๋ค.
์ด์ด์ ๊ฐ์ฒด ์งํฅ์ 4๊ฐ์ง ์ค์ํ ํน์ง๋ ๊ฐ๋ณ๊ฒ ์์๋ณด๋๋ก ํ์.
- ์ถ์ํ
- ์บก์ํ
- ์์
- ๋คํ์ฑ
์ง๊ธ๊น์ง ํด๋์ค(class)์ ๋ํด ์ค๋ช ํ๋ฉด์, ๊ฐ์ฒด ์งํฅ์ ํน์ง์ ๋ํด์๋ ์ดํด๋ณด์ง ์์์๋ค. ๊ฐ์ฒด ์งํฅ์ ํน์ง์ ์ค๋ช ํ๊ธฐ์๋ ๊ธ์ ๋ด์ฉ์ด ๋๋ฌด ๊ธธ์ด์ ธ ๋ค๋ฃจ์ง ์์์์ง๋ง, getter, setter๋ฅผ ๋ค๋ฃจ๊ธฐ ์ํด ํน์ง ์ค ์บก์ํ์ ์ ๋ณด ์๋์ ๊ฐ๋ ์ ์ค๋ช ํด์ผ ํ ๊ฒ ๊ฐ๋ค.
์บก์ํ๋ ์ฐ๊ด๋ ๋ชฉ์ ์ ๊ฐ์ง๋ ๊ฐ์ฒด(object)์ ์์ฑ(attribute)์ด๋ ๋์(behavior)์ ํ๋์ ์งํฉ์ผ๋ก ์ ์ ํ ๋ฌถ๋๋ค๋ ๊ฐ๋ ์ด๊ณ , ์ ๋ณด ์๋์ด๋ ์ด๋ ๊ฒ ๋ฌถ์ธ ํด๋์ค(class)์ ๋ด๋ถ ์ ๋ณด๋ฅผ ํจ๋ถ๋ก ๊ณต๊ฐํ์ง ์์์ผ ํ๋ค๋ ๊ฐ๋ ์ด๋ค.
public์ผ๋ก ์ ์ธ๋๋ฉด, ์๋ฌด ๊ณณ์์๋ ์ ๊ทผ์ด ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ์์ํ์ง ๋ชปํ ์๋ฌ๊ฐ ๋ฐ์ํ ์ ์๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๊ฐ์ฒด ์งํฅ์ ์บก์ํ์ ๋ฐ๋ผ ์ ๋ณด๋ฅผ private์ ์ฌ์ฉํด ์๋ํ์ฌ ์ธ์คํด์ค๋ฅผ ์ธ๋ถ์์ ์ ๊ทผํด ๋ณ๊ฒฝํ ์ ์๋๋ก ํ๊ฒ๋๋ค.
private์ ๋ฉค๋ฒ๋ฅผ ์ด๋ป๊ฒ ์ ๊ทผํ๊ณ ๋ณ๊ฒฝํ ์ ์์๊น ?
์ด๊ฑธ ๊ฐ๋ฅํ๊ฒ ํด์ฃผ๋ ๊ธฐ๋ฅ์ด ๋ฐ๋ก getter์ setter์ด๋ค.
์ด๋ฆ๋ง์ผ๋ก ์ง์ํด๋ ์ด๋ค ๊ธฐ๋ฅ์ธ์ง๋ ๋์ถฉ ์ ์ ์์ ๊ฒ์ด๋ค.
getter๋ ํด๋์ค(class)์ ๋ฉค๋ฒ๋ณ์(MemberVaribale)๋ฅผ ๊ฒ์ ํ๋๋ฐ ์ฌ์ฉํ๋ ๊ธฐ๋ฅ์ด๊ณ Dart์์๋ get ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌํํ ์ ์๊ณ , setter๋ ๋ฉค๋ฒ๋ณ์(MemberVaribale)๋ฅผ ๋ณ๊ฒฝ ํ๋๋ฐ ์ฌ์ฉํ๋ ๊ธฐ๋ฅ์ด๋ค.
getter, setter๋ ํด๋์ค(class) ๋ด์ ๋ฉค๋ฒ์ ์ฌ์ฉํ๋ ๊ธฐ๋ฅ์ด๋ผ ์ ๊ทผ ์ง์ ์๊ฐ ํด๋์ค์ ์ข ์๋ ๊ฒ์ด๋ผ ์๊ฐํ ์ ์์ง๋ง, Dart ์์๋ ๋์ผ ํ์ผ ๋ด์์๋ private์ ์ ๊ทผํ ์ ์๋ค.
MotoCycle ํด๋์ค๋ฅผ ์์ฑํ๋๋ฐ, ๋ณ์ name์ ์ธ๋์ค์ฝ์ด(_)๋ฅผ ์ฌ์ฉํ์ฌ private๋ก ์์ฑํด์ฃผ์.
class MotoCycle {
final String _name;
const MotoCycle(this._name);
}
์ด์ MotoCycle ํด๋์ค๋ฅผ ์ธ์คํด์ค ํด์ฃผ๊ณ , ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํด private ๋ณ์๋ก ์ง์ ํ _name์ ์ ๊ทผํด๋ณด์.
void main() {
MotoCycle vehicle = MotoCycle("R1");
print(vehicle._name);
}
์๋์ ๊ฐ์ ์๋ฌ๊ฐ ๋ฐ์ํ๊ฒ ๋๋ค.
The getter '_name' isn't defined for the type 'MotoCycle'.
Try importing the library that defines '_name', correcting the name to the name of an existing getter, or defining a getter or field named '_name'.
get ํค์๋๋ฅผ ์ฌ์ฉํด getter๋ฅผ ๋ฑ๋กํด์ฃผ์.
class MotoCycle {
final String _name;
const MotoCycle(this._name);
String get name => _name;
}
์ด์ ๋ค์ MotoCycle ํด๋์ค์ ์ธ์คํด์ค์์ _name์ผ๋ก ์ ๊ทผํ๋ ๊ฒ์ด ์๋ getter์ ์ ์ธํ name์ผ๋ก ์ ๊ทผํ๋ฉด ์ ๊ทผ์ด ๊ฐ๋ฅํ ๊ฒ์ ์ ์ ์๋ค.
void main() {
MotoCycle vehicle = MotoCycle("R1");
print(vehicle.name);
}
์ฌ๊ธฐ์ ์ค์ํ ๋ถ๋ถ์ด ๋ฉค๋ฒ๋ณ์์ getter์ ๋ค์ด๋ฐ ๊ท์น์ธ๋ฐ, ์ผ๋ฐ์ ์ผ๋ก ์ธ๋์ค์ฝ์ด๋ฅผ ์ ๊ฑฐํ์ฌ ์ฌ์ฉํด์ผ ํ๋ค.
์ด๋ ๊ฒ getter์ ๋ค์ด๋ฐ์ ์์ ๋กญ๊ฒ ์ง์ ํด๋ ์๋์๋ ๋ฌธ์ ๊ฐ ์๋ค.
String get motoCycleName => _name;
getter์๋ ๋ฐ๋์ ๋ฉค๋ฒ๋ณ์๋ง์ ๋ฐํํ์ง ์์๋ ๋๋ค.
์ด๋ฒ์ brand๋ผ๋ ๋ณ์๋ฅผ private์ผ๋ก ์ถ๊ฐํด์ฃผ๊ณ , name์ ๋ฐํํ ๋์ brand ๋ณ์๋ฅผ ๋ถ์ฌ์ ๋ฐํํ๋๋ก ์์ ํด ๋ณด์.
class MotoCycle {
final String _name;
final String _brand;
const MotoCycle(this._name, this._brand);
String get name {
return "$_brand : $_name";
}
}
getter๋ฅผ ์ฌ์ฉํ๋ฉด, ํด๋์ค(class)์ ์ ๋ณด๋ฅผ ์ํ๋ ํํ๋ก ์ ๊ณตํ ์ ์๋ค.
void main() {
MotoCycle vehicle = MotoCycle("R1", "Yamaha");
print(vehicle.name);
// Yamaha : R1
}
getter์ ๋ํด์ ์ดํด๋ดค๋๋ฐ, ํ ๊ฐ์ง ์๋ฌธ์ ์ด ์๊ธด๋ค.๋ฉค๋ฒ๋ณ์๋ฅผ private๋ก ์ ์ธํ์ฌ ์ ๋ณด์๋์ ํ์์ง๋ง, getter๋ฅผ ์ฌ์ฉํด ์ด๋์๋ ์ ๊ทผํ๊ฒ ๋๋ฉด, ๊ฐ์ฒด์งํฅ์ ํน์ง์ธ ์บก์ํ์ ์๋ฏธ๊ฐ ์๋ ๊ฒ์ด ์๋๊ฐ ? ์ ๋ณด๊ฐ ์๋๋์๋ค๊ณ ํ ์ ์๋๊ฐ ?
์ด๋ฐ ์๋ฌธ์ ์ด ๋ฐ๋ก getter ์ฌ์ฉ์ ์ง์ํด์ผ ํ๋ค๊ณ ํ๋ ์ด์ ๋ค. ์ ๋ณด์๋์ ์๋ฏธ๊ฐ ์์ด์ง๊ธฐ ๋๋ฌธ์ด๋ค.
๋จ์ํ ๋ฉค๋ฒ๋ณ์์ ์ํ๋ฅผ ์ ๋ฌํ๊ณ ์ ํ ๋์๋ง ์ฌ์ฉํ๊ณ ๋ฌด๋ถ๋ณํ getter์ฌ์ฉ์ ์ง์ํ๋ ๊ฒ์ด ์ข๋ค.
์ด์ด์ setter์ ๋ํด์ ์ดํด๋ณด๋๋ก ํ์.
์ ๋ setter ๋ฅผ ๊ฑฐ์ ์ฌ์ฉํ์ง ์๋๋ค. ์ด์ ์ ๋ํด์๋ ์ฐ์ setter๊ฐ ๋ญ์ง์ ๋ํด์ ๋ถํฐ ํ์คํ ์๊ณ ์ค๋ช
ํ๋๋ก ํ๊ฒ ๋ค.
setter๋ ๋ฉค๋ฒ๋ณ์์ ์ํ๋ฅผ ๋ณ๊ฒฝํ๊ณ ์ ํ ๋์ ์ฌ์ฉํ๋ ๊ธฐ๋ฅ์ด๋ค.
setter์ getter๋ ์ค๋ณต๋ ์ด๋ฆ์ ์ฌ์ฉํ ์ ์์ด์ ์ผ๋ฐ์ ์ผ๋ก๋ getter์ ๋ค์ด๋ฐ ๊ท์น์ ๋ฐ๋ผ์ ์์ฑํ๊ฒ ๋๋ค.
set ํค์๋๋ฅผ ์ฌ์ฉํด ๋ณ๊ฒฝํ๊ณ ์ ํ๋ ์ํ๋ฅผ ๋ฐ์์ ๋ฉค๋ฒ๋ณ์์ ํ ๋นํด์ฃผ๋ฉด ๋๋ ๊ฐ๋จํ ๊ตฌ์กฐ์ด๋ค.
class MotoCycle {
String _name;
MotoCycle(this._name);
String get name => _name;
set name(String value) => _name = value;
}
setter ์ฌ์ฉ์ public์ผ๋ก ์์ฑ๋ ๋ฉค๋ฒ๋ณ์์ ์ํ๋ฅผ ๋ณ๊ฒฝํ๊ณ ์ ํ ๋์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๊ณผ ๋์ผํ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
void main() {
MotoCycle vehicle = MotoCycle("R1");
print(vehicle.name);
// R1
vehicle.name = "R6";
print(vehicle.name);
// R6
}
setter์ ๊ธฐ๋ฅ ๋ฐ ์ญํ ์ ์์์ผ๋, ์ ์ฌ์ฉ์ ์ง์ํด์ผ ํ๋์ง ์ดํด๋ณด์.
์ฐ์ setter ์ฌ์ฉ์ ์ํด์๋ ์์(final)๋ก ์ ์ธํ ์๊ฐ ์๊ณ , ๋ฌด์๋ณด๋ค ์ค์ํ ์ ์ ๊ฐ์ ๋ณ๊ฒฝํ๊ณ ์ ํ๋ ์๋๋ฅผ ํ์
ํ๊ธฐ๊ฐ ์ด๋ ต๊ฒ ๋๋ค.
์๋๋ฅผ ํ์
ํ๊ธฐ ์ด๋ ต๊ธฐ ๋๋ฌธ์ ์ํ๊ฐ ์ ? ์ด๋ป๊ฒ ? ์ด๋์ ? ๋ณ๊ฒฝ์ ์๋ํ๋์ง ํ์
์ ํ๊ธฐ ์ํด ์ญ์ถ์ ์ ํด์ผ๋ง ํ๋ค.
๋ ํ๋์ ๋ฌธ์ ๋ ๊ฐ์ฒด(object)์ ์ผ๊ด์ฑ์ ์ ์งํ๊ธฐ ์ด๋ ต๋ค. ์ด ๋ถ๋ถ์ getter์ ๋ฌธ์ ์ ๊ณผ ๋์ผํ ๋ฌธ์ ๋ก ๋ชจ๋ ์์ญ์์ ์ ๊ทผํ ์ ์๋ ์ํ๊ฐ ๋๊ธฐ ๋๋ฌธ์ด๋ค.
getter, setter์ ๋ํด์ ์์๋ดค๋๋ฐ, ์ง์ํ๋ผ๋ ๊ฒ์ ๋จ๋ฐํ์ง ์์์ผ ํ๋ค๋ ๊ฒ์ด์ง ์์ ์ฌ์ฉ ์์ฒด๋ฅผ ํ์ง ๋ง์์ผ ํ๋ค๋ ์๋ฏธ๊ฐ ์๋๋ค.
ํ์์ ์ํด์ ๋น์ฐํ getter, setter๊ฐ ํ์ํ ์๊ฐ์ ์๋ค.
์ถ๊ฐ๋ก Dart ํด๋์ค(class)๋ ๋ฉค๋ฒ๋ณ์์ ๋ํด ์๋ฌต์ ์ผ๋ก getter, setter๊ฐ ์์ฑ์ด ๋๊ณ , ๋ฉค๋ฒ๋ณ์๊ฐ ์์์ธ ๊ฒฝ์ฐ์ getter๋ง ์์ฑ์ด ๋๊ธฐ ๋๋ฌธ์, private์ด ์๋๋ผ๋ฉด ๋ณ๋๋ก getter, setter๋ฅผ ๊ตฌํํ์ง ์์์์๋ ๋ฉค๋ฒ๋ณ์์ ๋ํ ์ ๊ทผ์ด ๊ฐ๋ฅํ ๊ฒ์ด์๋ค.
setter๋ฅผ ์ฌ์ฉํด ๊ฐ์ฒด(object)์ ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ดค์๋ค.
setter ์ฌ์ฉ์ ์์(final)๋ก ์ ์ธํ ์๊ฐ ์๋ค๊ณ ์์ ์ธ๊ธ ํ๋๋ฐ, ์ด ๋ถ๋ถ์ setter ์ฌ์ฉ์ ์ง์ํด์ผ ํ๋ค๋ ์ด์ ์ค ํ๋๋ก ์ค๋ช
ํ๊ธฐ๋ ํ์๋ค.
๊ทธ๋ ๋ค๋ฉด, ์ ์์(final)๋ก ์ ์ธ ๋์ด์ผ ํ๊ณ , ์์(final)๋ก ์ ์ธ๋ ์ธ์คํด์ค๋ฅผ ์ด๋ป๊ฒ ๋ณ๊ฒฝํ ์ ์์๊น ?
์ด์ setter์ ๋ํ ๋ถ๋ถ์ ๊ณ ๋ คํ์ง ์๊ณ ๋ฉค๋ฒ๋ฅผ public์ผ๋ก ์์ฑํด ๋ณด๋๋ก ํ๊ฒ ๋ค.
User ํด๋์ค๋ฅผ ์์ฑํ๊ณ , name ๋ณ์๋ฅผ ๋ณ๊ฒฝํด๋ณด์.
class User {
final String name = "tyger";
}
๋ณ๊ฒฝํ๋ ค๊ณ ํ๋ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค. ๋น์ฐํ ๊ฒ์ด๋ค.
์์(final)๋ก ์ ์ธ ๋์๊ธฐ ๋๋ฌธ์ ์ํ๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ค.
void main() {
User tyger = User();
tyger.name = "TYGER";
}
'name' can't be used as a setter because it's final. Try finding a different setter, or making 'name' non-final.
๊ทธ๋ ๋ค๋ฉด ์์๋ก ์ ์ธํ์ง ์์ผ๋ฉด ์๋๋ ? ๊ทธ๋ผ ์ฝ๊ฒ ๊ฐ์ ๋ณ๊ฒฝํ๊ณ ์ ์ดํ ์ ์์ ํ ๋ฐ...
Dart ์ธ์ด๋ Flutter์์๋ ๋ถ๋ณ ๊ฐ์ฒด(Immutable Object)๋ฅผ ์์ฑํด ํผํฌ๋จผ์ค ํฅ์ ๋ฐ ์์ ํ ์ ์๋ ๊ฐ์ฒด๋ฅผ ์์ฑ ์์ธก ๊ฐ๋ฅํ ๋์์ ๊ตฌํํ๋๋ก ํ์ฌ ๋ถํ์ํ ๋ฒ๊ทธ๋ฅผ ๊ฐ์ ์ํค๊ณ , ์ฝ๋์ ๊ฐ๋ ์ฑ์ ๋ํ ์ ์๋๋ก ํ๊ณ ์๋ค.
๋ณํ ์ ์๋ ๊ฐ์ฒด, ์ฆ ๋ถ๋ณ ๊ฐ์ฒด(Immutable Object)๋ฅผ ์์ฑํ๊ธฐ ์ํด ์์(final) ํ์
์ ์ฌ์ฉํ๊ฒ ๋๋ค.
์์(final) ํ์
์ ์ธ์คํด์ค ํ์ ๊ฐ์ฒด์ ์์ฑ์ ๋ณ๊ฒฝํ ์ ์๊ฒ ๋๊ธฐ ๋๋ฌธ์, ๋ถ๋ณ ๊ฐ์ฒด(Immutable Object)์ ์์ฑ์ ๋ณ๊ฒฝํ๊ธฐ ์ํ ๋ฐฉ๋ฒ์ผ๋ก๋ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ์์ฑํด์ผ ํ๋ค.
์ด๋ ๊ฒ ๊ธฐ์กด ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํด ์๋ก์ด ์ธ์คํด์ค๋ฅผ ๋ณต์ฌ(copy)ํ๋ ๊ธฐ๋ฅ์ ๊น์๋ณต์ฌ(deepCopy)๋ผ ํ๊ณ , copyWith ๋ฉ์๋๋ฅผ ๊ตฌํํ์ฌ ์ฌ์ฉํ ์ ์๋ค.
name, age ์์ฑ์ ์์(final)๋ก ์ ์ธํ์ฌ User ํด๋์ค๋ฅผ ๋ง๋ค์ด ๋ณด์.
class User {
final String name;
final int age;
const User(this.name, this.age);
}
์ด์ age ์์ฑ์ ๋ณ๊ฒฝํ๊ธฐ ์ํด ๊น์๋ณต์ฌ(deepCopy)์ธ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ์ ๋ฌํด ์ฃผ๋๋ก ํ์.
void main() {
User tyger = User("tyger", 100);
tyger = User(tyger.name, 90);
}
์์ฑ์ด ์ ์์ ์ผ๋ก ๋ณ๊ฒฝ์ด ๋์๋ค. ํ์ง๋ง ๋ญ๊ฐ ๋ถํธํ๋ค. ์ง๊ธ์ ์์ฑ์ด 2๊ฐ ๋ฟ์ด์ง๋ง 10๊ฐ๋ผ๋ฉด ์ฝ๋๋ง ๋์ด๋๊ฒ ๋ ๊ฒ์ด๋ค.
๊น์๋ณต์ฌ(deepCopy)๋ฅผ ๊ฐ๋ฅํ๊ฒ ํด์ฃผ๋ copyWith ๋ฉ์๋๋ฅผ ์ถ๊ฐํด ๋ณด๋๋กํ์.
User ํด๋์ค์ ์์ฑ๋ค์ nullable ํ์ ์ผ๋ก ๋งค๊ฐ๋ณ์๋ฅผ ๋ฑ๋กํด์ฃผ๊ณ , ๋งค๊ฐ๋ณ์๊ฐ null์ด๋ฉด User ํด๋์ค์ ์์ฑ์ ์ฌ์ฉํ๋ฉด ๋๊ณ , null์ด ์๋๋ฉด ๋งค๊ฐ๋ณ์์ ๊ฐ์ ์ฌ์ฉํ์ฌ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ์์ฑ์(constructor)๋ก ๋ฐํํด์ฃผ๋ฉด ๋๋ค.
User copyWith({
final String? name,
final int? age,
}) {
return User(
name ?? this.name,
age ?? this.age,
);
}
์ด์ ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํด copyWith ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์ํ๋ ์์ฑ์ ๊ฐ์ ์ ๋ฌํด ์ฃผ๋ฉด ๋ณ๊ฒฝ๋ ์์ฑ์ผ๋ก ์๋ก์ด ์ธ์คํด์ค๋ฅผ ๋ฐํํ๊ฒ ๋๋ค.
void main() {
User tyger = User("tyger", 100);
tyger = tyger.copyWith(age: 20);
}
copyWith์์ ๋ฐํ๋๋ ์ธ์คํด์ค๊ฐ ์๋ก ์์ฑ๋ ์ธ์คํด์ค์ธ์ง ํ์ธํด๋ณด์. hashCode ๊ฐ์ ์ถ๋ ฅํด๋ณด๋ฉด, copyWith์์ ๋ฐํํ ์ธ์คํด์ค๋ ์๋ก์ด ์ธ์คํด์ค๋ผ๋ ๊ฒ์ ์ ์ ์๋ค.
void main() {
User tyger = User("tyger", 100);
print(tyger.hashCode);
// 613218385
tyger = tyger.copyWith(age: 20);
print(tyger.hashCode);
// 436920219
}
์ธ์คํด์ค๋ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ํ ๋น๋ ๊ฒ์ธ๋ฐ, ๋ถ๋ณ ๊ฐ์ฒด(Immutable Object)๋ ๋์ผ ์ธ์คํด์ค์์ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅ ํ๊ธฐ ๋๋ฌธ์, ์๋ก์ด ์ธ์คํด์ค ์์ญ์ ๊ฐ์ฒด(object)๋ฅผ ๋ณต์ฌํ๋ ๊ฐ๋ ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค.
์ด๋ ๊ฒ ๋๋ฉด, ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ์์ฃผ ํ ๋น๋ฐ๊ฒ ๋๋ ๊ฒ ์๋๊น ? ๋ง๋ค. ๊น์๋ณต์ฌ(deepCopy)๋ ์๋ก์ด ์ธ์คํด์ค๊ฐ ์์ฑ๋๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๋ณต์ฌ๋ฅผ ํ๊ฒ๋๋ฉด, ์๋ก์ด ์ธ์คํด์ค์ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ์๋ก ํ ๋น ๋ฐ๊ณ ๊ธฐ์กด ์ธ์คํด์ค์ ๋ฉ๋ชจ๋ฆฌ๋ GC(GarbageCollector) ์์ญ์ ๋ค์ด๊ฐ๊ฒ ๋๋ค.
์ด๋ฐ ๋์์ด ๋ฐ๋ณต์ ์ผ๋ก ๋ฐ์ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ์ ํ ๋น ๋ฐ ๋ฐํ์ด ๋ฐ๋ณต์ ์ผ๋ก ๋ฐ์ํ์ฌ ์๊ฐ์ ์ผ๋ก ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ๋์ด๋ ์ ์๋ค.
๋ํ ๊น์๋ณต์ฌ(deepCopy)๋ ๊ฐ์ฒด(object)๋ฅผ ์ ๋ถ ๋ณต์ฌํ๋ ๊ฐ๋
์ด๊ธฐ ๋๋ฌธ์, ๊ฐ์ฒด ๊ตฌ์กฐ๊ฐ ๋ณต์กํ๊ฒ ๋๋ฉด ์๋ ์ ํ๊ฐ ์ง์์ ์ผ๋ก ๋ฐ์ํ ์๋ ์๋ค.
๊น์๋ณต์ฌ(deepCopy)์ ๊ด๋ จํด์๋ ์ธ์คํด์ค, ์์๋ณต์ฌ(shallowCopy), ๊ฐ์ฒด ๋๋ฑ์ฑ ๋ฑ์ ์ถ๊ฐ์ ์ผ๋ก ๋ค๋ค์ผ ํ๋ ๊ฐ๋ ์ด ๋ง์ ์ด๋ฒ ๊ธ์์๋ ๊ฐ๋จํ ๊ฐ๋ ์ ๋๋ง ์ดํดํ๊ณ , ์์ธํ ๋ด์ฉ์ ๋ณ๋๋ก ๊ธ์ ์์ฑํ๋๋ก ํ๊ฒ ๋ค.
copyWith๋ nullable ํ์ ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ ๋๋ฌธ์, null ํ์ ์ ์ฌ์ฉํ์ง ๋ชปํ๋ ๋ฌธ์ ๊ฐ ์๋๋ฐ, ์๋ ๊ณต์ ํ ๊ฒ์๊ธ ์ฐธ๊ณ ํ์๋ฉด ๋ค์ํ copyWith์ ๊ตฌํ ๋ฐฉ๋ฒ์ ํ์ธํ์ค ์ ์์ต๋๋ค.
Dart ์ธ์ด์์ ์ฌ์ฉํ๋ ํด๋์ค(class)์ ๋ํด ๊ธฐ๋ณธ์ ์ธ ์ฌ์ฉ ๋ฐฉ๋ฒ ๋ถํฐ, ์ถ์ํ, ์์, ๋์์ธ ํจํด ๋ฐ ํด๋์ค์์ ํ์ฉํ ์ ์๋ ๊ฒ๋ค์ ๋ํด ๋ค๋ค๋ณด์๋ค.
์์ธํ ๋ค๋ค๋ณธ ๊ธฐ๋ฅ๋ ์๊ณ , ๊น๊ฒ ๋ค์ด๊ฐ๋ฉด ๋ด์ฉ์ด ๋๋ฌด ๊ธธ์ด์ ธ ์ด์ฉ ์ ์์ด ๊ฐ๋ ๋ง ์ดํด๋ณธ ๊ธฐ๋ฅ๋ ์์๋ค. ๊ธฐ๋ฅ๋ค์ ๋ํด ์์ธํ ์ค๋ช ์ด ์ถ๊ฐ์ ์ผ๋ก ํ์ํ ๋ถ๋ถ๋ค์ ๋ณ๋๋ก ๋ด์ฉ์ ๋ํด ๊ธ์ ์์ฑํ ์์ ์ด๋ค.
ํด๋์ค๋ฅผ ๋ค๋ฃจ๊ธฐ ์ํด ๋ชจ๋ ๊ธฐ๋ฅ์ ๋น์ฐํ ์๊ณ ์๋ ๊ฒ์ ์ค์ํ์ง๋ง, ๊ฐ๋
์ ๋๋ง ์๊ณ ์๋๋ผ๋ ํ์์์ ์ ์ ํ ์ํ๋ ๊ธฐ๋ฅ์ ๋ํด์๋ง ์์ธํ ์ดํด๋ณผ ์ ์์ผ๋ฉด ๋๋ค. ์ต์ง๋ก ์ฌ์ฉ ๋ฐฉ๋ฒ์ ์ธ์ธ ํ์๋ ์๋ ๊ฒ ๊ฐ๋ค.
์์ฃผ ๋ค๋ค๋ณด๋ฉด ์์ฐ์ค๋ฝ๊ฒ ์ต์ํด ์ง ์ ์๋ ๊ธฐ๋ฅ๋ค์ด๋ค.
ํด๋์ค์ ๋ํด ๊ถ๊ธํ์๊ฑฐ๋ ์ดํด๊ฐ ์ ๋์ง ์์ผ์ ๋ด์ฉ๋ค์ด ์๋ค๋ฉด ๋๊ธ ๋จ๊ฒจ์ฃผ์๊ธฐ ๋ฐ๋๋๋ค