White Cat's Paw

플러터/문법 및 설치

[플러터] dart 연관관계와 믹스인

JungMayo 2025. 1. 8. 01:14
연관관계 : 컴포지션 관계, 집합 관계

| 컴포지션 관계

  •   부분-전체 관계 중에서 생명주기가 밀접하게 연관된 강한 소유 관계를 의미
  •   전체 객체가 소멸될 때 부분 객체도 함께 소멸되는 것이 특징
  •   예시 : 차와 엔진, 인간과 심장을 생각하면 편함(하나 죽으면 망가지는 것과 동일)
  •   [강한 소유 관계]

예시)

class Engine {
  final String type;

  Engine(this.type);

  void startEngine() {
    print('${type} 엔진이 시동됩니다');
  }
}

//
class Car {
  final Engine engine;

  // Car(this.engine);
  // 생성자 코드이다. 1. 축약버전 --> 생성자 바디부분을 생략 했다.
  // Car(String enginType) : engine = Engine(enginType);
  // 생성자 코드이다. 2. 생성자 + 인스턴스화
  Car(String enginType) : engine = Engine(enginType) {
    print('생성자 호출 시 내부 스택 메모리가 호출 된다.');
  }

  void startCar() {
    engine.startEngine();
    print("차가 출발 합니다.");
  }
}
void main() {
  // Engine v8Engine = Engine('v8');
  // Car car1 = Car(v8Engine);
  //////////////////////////////
  Car car1 = Car('v8');
  car1.startCar();
  
  --> 'v8'엔진이 시동 됩니다. 차가 출발 합니다.가 출력됨
  // 누군가 참조하고 있지 않다면 GC 대상이 된다. GC란 ? garbage collection 이라는 의미 -> 메모리에서 해제되는 과정을 의미한다.

 

| 집합 관계

  •   부분-전체 관계 중에서 전체와 부분의 생명주기가 독립적인 관계를 의미
  •   전체 객체가 소멸되더라도 부분 객체는 독립적으로 존재할 수 있다.
  •   예시 : 부서와 직원 클래스를 생각해볼 수 있음(부서가 없어지더라도 직원이 없어지는 것은 아님)
  •   [약한 소유 관계]
class Employee {
  final String name;

  Employee(this.name);

  void displayEmployeeInfo() {
    print('직원의 이름 : ${name}');
  }
}

class Department {
  final String deptName;
  final List<Employee> employees;
 
// 객체를 초기화 , 인스턴스화 한 것이 아니라 employees의 빈배열 리스트를 생성
  Department(this.deptName) : employees = [] {
    print('=== Department 생성자 내부 스택 호출 ===');
  }

  void addEmployee(Employee emp) {
  //메인에서 인스턴스화 된 객체가 매개변수로 들어오옴
    employees.add(emp);
  }

  void displayDepartmentInfo() {
    print("-------------------");
    print("부서의 이름 : ${deptName}");
    for (var emp in employees) { //반복문, 빈 배열에 값이 추가되었고 각 배열은 객체가 된다. 따라서 emp의 메서드를 사용 가능
      emp.displayEmployeeInfo();
    }
  }
}

void main() {

  Department department1 = Department('개발부');
  Department department2 = Department('디자인부서');
  Employee emp1 = Employee('정마요');
  Employee emp2 = Employee('정지현');
  Employee emp3 = Employee('챱챱김');

  department1.addEmployee(emp1);
  department1.addEmployee(emp2);
  department2.addEmployee(emp3);

  department1.displayDepartmentInfo();
}
믹스인

| 믹스인

  •   Dart에서 클래스의 코드를 여러 클래스의 계층에서 재사용할 수 있도록 해주는 코드 조각이다.
  •   Mixin을 사용하게 되면 다중 상속의 문제를 해결할 수 있고 컴퍼지션을 사용하지 않고
  • 다른 클래스의 코드를 재사용 할 수 있다.
// 믹스인 사용해보기
// 여러 계층에서 코드를 재사용할 수 있도록 하는 코드 조각이다.

mixin Engine {
  int power = 5000;
}

mixin Wheel {
  String wheelName = '4륜 구동 바퀴';
}

//with를 사용
class BMW with Engine, Wheel {}

void main() {
  // 인스턴스화 시킴
  BMW bm1 = BMW();
  print(bm1.power);
  print(bm1.wheelName);

  // 상속구조를 사용하면 단일 상속만 허용한다. 믹스인 사용하면 여러 계층에서
  // 코드의 조각들을 편하게 가져올 수 있다.
  // 단 믹스인 maxin Engine 이 인스턴스화 되는 것은 아니다. !!!!
  // Wheel wheel1 = Wheel(); 믹스인은 인스턴스화 시킬 수 없다.
}

 

Q : 근데 만약 믹스인을 인스턴스화 시키고 싶다면?

A : class를 추가해주면 된다.

// 믹스인을 인스턴스화 시킬 때 사용하는 문법
// class를 추가해준 것!
mixin class Engine {
  int power = 5000;
}

mixin class Wheel {
  String wheelName = '4륜 구동 바퀴';
}

class BMW with Engine, Wheel {}

void main() {
  BMW b = BMW();
  Engine e = Engine(); // 믹스인 클래스는 인스턴스화 가능하다.
  Wheel w = Wheel();
  print(b.power);
}

 

 

** 이니셜라이저 리스트 ( : )

  •   이니셜라이저 리스트는 상속 관계뿐만 아니라 연관관계에서도 클래스의 필드 초기화 및 객체 생성에 사용가능