Flutter/Dart 핵심만 쏙 - 객체지향
Dart 객체 지향
객체 지향은 프로그램을 명령어의 집합으로 보는 시각에서 벗어나 독립된 객체들의 모임으로 보는 프로그래밍 패러다임이다. dart 또한 객체지향 언어로 다른 언어들과 유사한(constructor, getter/setter …) 문법들을 지원하고 있으며 dart만의 특이점(mixin)을 지니는 문법 또한 존재한다.
Class 와 Instance
객체지향 언어로서 Dart의 특징
- 모든 변수는 객체이다.
- Object 클래스는 모든 class의 부모 객체이다.
접근 제한자
- Dart는 접근 제한자가 따로없음
- 변수명 앞에 underscore(_)를 붙여 private 변수로 지정
- private변수는 외부 파일에서 접근이 불가능 하지만 동일한 파일 내에선 접근 가능
class Idol{
String _name; // 접근제한자
int membersCount;
Idol(this._name, this.membersCount);
}
getter/setter
class Idol{
String _name;
int membersCount;
Idol(this._name, this.membersCount);
String get myname{
return this._name;
}
set myname(String n){
this._name = n;
}
}
void main() {
Idol hot = Idol("Hot", 5);
print(hot.myname); // Hot
hot.myname = "BTS";
print(hot.myname); // BTS
}
- 멤버 변수에 직접 접근 하는것보다 getter/setter를 사용하면 코딩 실수를 줄일 수 있다.
- getter/setter를 메소드로 만드는 다른 언어들과 달리 get, set 키워드를 자체지원
- 외부에서 import한 private변수에도 getter, setter를 접근가능
Constructor
Default Constructor
Dart는 field 초기화를 좀 더 간소화 하기 위한 자체 문법이 존재한다.
class Idol{
String name;
int membersCount;
Idol(String name, int membersCount):
this.name = name,
this.membersCount = membersCount;
void hello() {
print("Hello I'm $name we have $membersCount members");
}
}
위 코드는 아래와 같이 축약이 가능
class Idol{
String name;
int membersCount;
Idol(this.name, this.membersCount);
void hello() {
print("Hello I'm $name we have $membersCount members");
}
}
Named Constructor
Named Constructor는 Default constructor과는 별개로 생성이 가능
class Idol {
String name;
int membersCount;
Idol(this.name, this.membersCount); // default constructor
Idol.fromList(List values) // name constructor
: this.name = values[0],
this.membersCount = values[1];
void hello() {
print("Hello I'm $name we have $membersCount members");
}
}
void main() {
List btsInfo = ["BTS", 7];
Idol bts = Idol.fromList(btsInfo);
bts.hello();
}
Const Constructor
field 가 모두 final로 선언되었기 때문에 field 값을 바꿀 수 없다.
class Idol {
final String name;
final int membersCount;
const Idol(this.name, this.membersCount);
Idol.fromList(List values)
:this.name = values[0],
this.membersCount = values[1];
void hello() {
print("Hello I'm $name we have $membersCount members");
}
}
void main() {
Idol idol1 = const Idol("Idol", 5);
Idol idol2 = const Idol("Idol", 5);
Idol idol3 = Idol("Idol", 5);
Idol idol4 = Idol("Idol", 5);
print(idol1 == idol2);
print(idol3 == idol4);
}
const constructor로 생성된 동일한 내용의 constructor은 같은 instance로 취급
Dart 상속
Dart는 상속은 Java의 그것과 유사하다.
extends 키워드로 상속을 하고 super키워드로 부모 클래스에 접근한다.
interface
-
dart에서 interface는 클래스를 이용하여 선언
-
사용할 땐 implements를 이용
-
클래스 형태를 맞추도록 강제하는 역할
class Idol {
final String name;
final int membersCount;
const Idol(this.name, this.membersCount);
void hello() {} //형태만 강제
}
class BoyGroup implements Idol {
String name;
int membersCount;
BoyGroup(this.name, this.membersCount);
void hello(){
print("My name is $name we have $membersCount boys");
}
}
class GirlGroup implements Idol {
String name;
int membersCount;
GirlGroup(this.name, this.membersCount);
void hello(){
print("My name is $name we have $membersCount girls");
}
}
void main() {
BoyGroup bg = BoyGroup("BTS", 5);
BoyGroup gg = BoyGroup("Nespa", 6);
Idol idol = Idol("boy", 7); // Bad
}
interface를 인스턴스화 하는것은 바람직하지 않다.
abstract
abstract class Idol {
final String name;
final int membersCount;
const Idol(this.name, this.membersCount);
void hello() {} //형태만 강제
}
class BoyGroup implements Idol {
String name;
int membersCount;
BoyGroup(this.name, this.membersCount);
void hello(){
print("My name is $name we have $membersCount boys");
}
}
class GirlGroup implements Idol {
String name;
int membersCount;
GirlGroup(this.name, this.membersCount);
void hello(){
print("My name is $name we have $membersCount girls");
}
}
void main() {
BoyGroup bg = BoyGroup("BTS", 5);
BoyGroup gg = BoyGroup("Nespa", 6);
Idol idol = Idol("boy", 7); // Error
}
abstract 키워드는 interface를 인스턴스화하는 것을 막을 수 있다.
mixin
- mixin은 자식클래스의 생성없이 물려줄 수 있는 도구이다.
- 다중 상속을 피하기 위하여 사용
- with키워드를 이용하여 사용한다.
※ 다중 상속을 피해야하는 이유↓ https://siyoon210.tistory.com/125
mixin이 필요한 이유(mixin 미사용시)
abstract class Insect{
void crawl() {
print("crawling");
}
}
abstract class AirbornInsect extends Insect {
void flutter() {
print("fluttering");
}
void buzz() {
print("buzzing annoyingly");
}
}
abstract class Bird{
void chirp() {
print("chirping");
}
// Duplicated method
void flutter(){
print("fluttering");
}
}
class Mosquito extends AirbornInsect{
void doMosquitoThing(){
crawl();
flutter();
buzz();
print("Sucking blood");
}
}
class Swallow extends Bird {
void doSwallowThing(){
chirp();
flutter();
print("Eating a mosquito");
}
}
2개의 서로 다른 클래스에서 flutter method가 중복으로 사용됨
mixin이 필요한 이유(mix인 사용)
mixin Fluttering {
void flutter(){
print("fluttering");
}
}
abstract class Insect{
void crawl() {
print("crawling");
}
}
abstract class AirbornInsect extends Insect with Fluttering{
void buzz() {
print("buzzing annoyingly");
}
}
abstract class Bird with Fluttering{
void chirp() {
print("chirping");
}
}
class Mosquito extends AirbornInsect{
void doMosquitoThing(){
crawl();
flutter();
buzz();
print("Sucking blood");
}
}
class Swallow extends Bird {
void doSwallowThing(){
chirp();
flutter();
print("Eating a mosquito");
}
}
코드의 중복을 피하면서 Fluttering class만 상속 가능
Fluttering 클래스 상속 구조
mixin 사용법
abstract class Walk{
final String foot = "Small Foot";
void walk(){
print("Walk with $foot");
}
}
- abstract class
mixin Walk{
final String foot = "Small Foot";
void walk(){
print("Walk with $foot");
}
}
- mixin 키워드
mixin의 on
-
특정 클래스만 해당 mixin 상속 가능하게 함
-
해당 클래스의 타입의 변수와 메소드를 사용가능하다.
-
mixin으로 선언된 경우에만 사용가능
class FlyingAnimal {
final String name;
FlyingAnimal(this.name);
void fly() {
print("$name is flying");
}
}
mixin Walk on FlyingAnimal{
final String foot = "Small foot";
void walk() {
print("$name is Walk with $foot");
fly(); // FlyingAnimal method 사용가능
}
}
class Minsu extends FlyingAnimal with Walk {
Minsu(String name): super(name);
void hi() {
print("hi");
walk();
}
}
/* Walk은 on으로 FlyingAnimal에만 사용가능하게
한것을 Sumin 클래스에 상속하려해서 에러 발생
*/
class Sumin with Walk{
void sumin(){
print("sumin");
}
}
Walk는 on을 사용하여 FlyingAnimal에만 상속 가능 한데 Sumin에 상속하려 했기 때문에 에러가 발생
작성자: YunSukHyun
댓글남기기