[Dart] 다트 객체지향 프로그래밍

찌니월드·2024년 2월 13일
0

📚 책 스터디

목록 보기
2/11
post-thumbnail

클래스

// class 키워드를 입력 후 클래스명을 지정해 클래스를 선언한다.
class Panda {
  // 클래스에 종속되는 변수를 지정할 수 있다.
  String name = '푸바오';
  
  // 클래스에 종속되는 함수를 지정할 수 있다.
  // 클래스에 종속되는 함수를 메서드라고 부른다.
  void sayName() {
    
    // 클래스 내부의 속성을 지칭하고 싶을 때는 this 키워드를 사용하면 된다.
    // 결과적으로 this.name은 Panda 클래스의 name 변수를 지칭한다.
    print('저는 ${this.name}입니다.');
    // 스코프 안에 같은 속성 이름이 하나만 존재한다면 this를 생략할 수 있다.
    print('저는 $name입니다.');
  }
}

void main() {
  Panda panda = Panda(); // Panda 인스턴스 생성
  
  // 메서드 실행
  panda.sayName();
}

생성자

class Panda {
  // 생성자에서 입력받는 변수들은 일반적으로 final 키워드 사용
  final String name;
  
  // 생성자 선언
  // 클래스와 같은 이름이어야 한다.
  Panda(String name) : this.name = name;
  
  void sayName() {
    print('저는 ${this.name}입니다.');
  }
  
}

void main() {
  Panda panda = Panda('푸바오'); // Panda 인스턴스 생성
  
  // 메서드 실행
  panda.sayName();
}

프라이빗 변수

클래스 내부에서만 사용하는 변수가 아닌, 같은 파일에서만 접근 가능한 변수를 말한다.

class Panda {  
  // '_'로 변수명을 시작
  String _name;
  
  Panda(this._name);
}

void main() {
  Panda panda = Panda('푸바오');
  
  // 같은 파일에서는 _name 변수에 접근할 수 있지만
  // 다른 파일에서는 _name 변수에 접근할 수 없다.
  print(panda._name);
}

상속

class Idol {  
  final String name;
  final int membersCount;
  
  Idol(this.name, this.membersCount);
  
  void sayName() {
    print('저는 ${this.name}입니다.');
  }
  
  void sayMembersCount() {
    print('${this.name} 멤버는 ${this.membersCount}명입니다.');
  }
}

// class 자식 클래스 extends 부모 클래스
class BoyGroup extends Idol {
  
  // 상속받은 생성자
  BoyGroup(
  String name,
  int membersCount,
  ) : super( // super는 부모 클래스를 지칭한다.
    name, 
    membersCount,
  );
  
  // 상속받지 않은 기능
  void sayMale() {
    print('저는 남자 아이돌입니다.');
  }
}

void main() {
  BoyGroup bts = BoyGroup('BTS', 7); // 생성자로 객체 생성
  
  bts.sayName();
  bts.sayMembersCount();
  bts.sayMale();
}

오버라이드

부모 클래스 또는 인터페이스에 정의된 메서드를 재정의하는 것을 의미한다.

class Idol {
  final String name;
  final int membersCount;

  Idol(this.name, this.membersCount);

  void sayName() {
    print('저는 ${this.name}입니다.');
  }

  void sayMembersCount() {
    print('${this.name} 멤버는 ${this.membersCount}명입니다.');
  }
}

class GirlGroup extends Idol {
  
  GirlGroup(
    super.name,
    super.membersCount,
  );

  @override
  void sayName() {
    print('저는 여자 아이돌 ${this.name}입니다.');
  }
}

void main() {
  GirlGroup blackPink = GirlGroup('블랙핑크', 4);
  
  // 자식 클래스의 오버라이드된 메서드 사용
  blackPink.sayName();
  
  // sayMembersCount는 오버라이드하지 않았기 때문에
  // 그대로 Idol 클래스의 메서드가 실행된다.
  blackPink.sayMembersCount();
}

믹스인

특정 클래스에 원하는 기능들만 골라 넣을 수 있는 기능이다.

class Idol {
  final String name;
  final int membersCount;
  
  Idol(this.name, this.membersCount);
}

mixin IdolSingMixin on Idol {
  void sing() {
    print('${this.name}가 노래를 부릅니다.');
  }
}

// 믹스인을 적용할 때는 with 키워드 사용
class BoyGroup extends Idol with IdolSingMixin {
  BoyGroup(
    super.name,
    super.membersCount,
  );
  
  void sayMale() {
    print('저는 남자 아이돌입니다.');
  }
}

void main() {
  BoyGroup bts = BoyGroup('BTS', 7);
  
  // 믹스인에 정의된 sing() 함수 사용 가능
  bts.sing();
}

추상

추상 클래스는 인스턴스화가 필요 없는 공통 부모 클래스를 만들 때 사용한다.

// 추상 클래스
abstract class Idol {
  final String name;
  final int membersCount;

  Idol(this.name, this.membersCount);

  void sayName();
  void sayMembersCount();
}

// 추상 클래스를 구현하는 클래스
class GirlGroup implements Idol {
  final String name;
  final int membersCount;

  GirlGroup(
    this.name,
    this.membersCount,
  );

  void sayName() {
    print('저는 여자 아이돌 ${this.name}입니다.');
  }

  void sayMembersCount() {
    print('${this.name} 멤버는 ${this.membersCount}명입니다.');
  }
}

void main() {
  GirlGroup blackPink = GirlGroup('블랙핑크', 4);

  blackPink.sayName();
  blackPink.sayMembersCount();
}

제네릭

특정 변수의 타입을 하나의 타입으로 제한하고 싶지 않을 때 자주 사용한다.

// 인스턴스화할 때 입력받을 타입을 T로 지정한다.
class Cache<T> {
  // data의 타입을 추후 입력될 T 타입으로 지정한다.
  final T data;
  
  Cache({required this.data});
}

void main() {
  // T의 타입을 List<int>로 입력한다.
  final cache = Cache<List<int>> (
    data: [1, 2, 3],
  );
  
  // 제네릭에 입력된 값을 통해 data 변수의 타입이 자동으로 유추한다.
  print(cache.data.reduce((value, element) => value + element)); // 6
}

Static

static 키워드를 사용하면 클래스 자체에 귀속되기 때문에 인스턴스끼리 공유해야 하는 정보에 지정하면 된다.

캐스케이드 연산자

인스턴스에서 해당 인스턴스의 속성이나 멤버 함수를 연속해서 사용하는 기능이다.

void main() {
  // cascade operator (..)를 사용하면
  // 선언한 변수의 메서드를 연속으로 실행할 수 있다.
  Idol blackPink = Idol('블랙핑크', 4)
    ..sayName()
    ..sayMembersCount();
}

참고

이 글은 골든래빗 《코드팩토리의 플러터 프로그래밍》의 스터디 내용 입니다.

profile
Front-End Developer

0개의 댓글