728x90
반응형
Java 객체 간의 관계 개념
Java는 단일 상속만 허용합니다.
(최상위 클래스인 Object를 제외한 모든 클래스는 하나의 부모 클래스만 상속 가능)
1. 연관 관계
- 객체들이 서로 연결된 일반적인 관계를 의미합니다.
2. 컴포지션 관계 (Composition)
- 정의:
부분-전체 관계 중에서 생명주기가 밀접히 연관된 강한 소유 관계입니다. - 특징:
- 전체 객체가 소멸되면 부분 객체도 함께 소멸됩니다.
- 의존성이 매우 높습니다.
- 예시:
자동차(전체)와 엔진(부분) 관계
class Engine {
final String type;
Engine(this.type);
void startEngine() {
print('${type} 엔진이 시동됩니다.');
}
}
class Car {
final Engine engine;
Car(String enginType) : engine = Engine(enginType) {
print('생성자 호출시 내부 스택 메모리가 호출 된다.');
}
void startCar() {
engine.startEngine();
print('차가 출발합니다.');
}
}
void main() {
Car car1 = Car('v8');
car1.startCar();
}
3. 집합 관계 (Aggregation)
- 정의:
부분-전체 관계 중에서 전체와 부분의 생명주기가 독립적인 약한 소유 관계입니다. - 특징:
- 전체 객체가 소멸되더라도 부분 객체는 독립적으로 존재할 수 있습니다.
- 예시:
부서(전체)와 직원(부분) 관계
class Employee {
final String name;
Employee(this.name);
void displayEmployeeInfo() {
print('직원의 이름 : ${name}');
}
}
class Department {
final String deptName;
List<Employee> employees;
Department(this.deptName) : employees = [] {
print('==Department 생성자 내부 스택 호출 ==');
}
void addEmployee(Employee emps) {
employees.add(emps);
}
void addEmployees(List<Employee> emps) {
for (var emp in emps) {
employees.add(emp);
}
}
void displayDepartmentInfo() {
print('==================');
print('부서의 이름 : ${deptName}');
for (var emp in employees) {
emp.displayEmployeeInfo();
}
print('==================');
}
}
void main() {
Department department1 = Department("개발부");
Department department2 = Department("디자인부");
Employee emp1 = Employee('홍길동');
Employee emp2 = Employee('김유신');
Employee emp3 = Employee('야스오');
List<Employee> emps = [emp1, emp2];
department2.addEmployee(emp3);
department1.addEmployees(emps);
department1.displayDepartmentInfo();
department2.displayDepartmentInfo();
}
==Department 생성자 내부 스택 호출 ==
==Department 생성자 내부 스택 호출 ==
==================
부서의 이름 : 개발부
직원의 이름 : 홍길동
직원의 이름 : 김유신
==================
==================
부서의 이름 : 디자인부
직원의 이름 : 야스오
==================
설명:
- Department 객체는 List<Employee>를 사용하여 여러 직원을 관리합니다.
- 부서 객체가 소멸되더라도 직원 객체는 독립적으로 존재할 수 있습니다.
- 부서 이름과 직원 정보를 출력하는 기능을 제공합니다.
4. 이니셜라이저 리스트
이니셜라이저 리스트(:)는 생성자 호출 시, 클래스 필드의 초기화 작업을 수행하기 위해 사용됩니다.
특히, 클래스 필드가 final일 경우, 생성자 바디보다 먼저 초기화해야 하므로 이니셜라이저 리스트가 유용합니다.
장점
- 생성자의 실행 이전에 필드를 초기화할 수 있습니다.
- 상속 관계뿐만 아니라, 컴포지션 및 집합 관계에서도 객체 생성 시 유용합니다.
Dart의 Mixin
- 정의
Mixin은 클래스의 코드를 여러 클래스 계층에서 재사용할 수 있도록 도와주는 코드 조각입니다. - 특징
- 다중 상속의 문제를 해결합니다.
- 컴퍼지션을 사용하지 않고도 다른 클래스의 코드를 재사용할 수 있습니다.
- Dart에서 Mixin은 with 키워드를 사용하여 적용합니다.
- 장점
- 코드 중복을 줄이고 유지보수를 용이하게 합니다.
- 특정 기능을 재사용하거나 추가할 때 유연성을 제공합니다.
- 예시 (Dart Mixin 사용):
mixin Flyable {
void fly() => print("날아다닐 수 있음!");
}
mixin Swimmable {
void swim() => print("수영할 수 있음!");
}
class Bird with Flyable {}
class Fish with Swimmable {}
void main() {
Bird bird = Bird();
bird.fly();
Fish fish = Fish();
fish.swim();
}
Dart와 Java 개념 비교
개념Dart (Mixin)Java (컴포지션/집합)
다중 상속 | 가능 (with 키워드 사용) | 불가능 (단일 상속만 허용) |
코드 재사용 | 코드 재사용에 매우 적합 | 상속 외에 컴포지션 및 인터페이스 사용 |
소유 관계 | 관계 개념이 없고, 단순 코드 조각 재사용에 집중 | 강한 소유 관계(컴포지션) 또는 약한 소유 관계(집합)으로 정의 |
Dart에서 Mixin과 Mixin Class 사용하기
Dart에서 Mixin은 여러 계층에서 코드를 재사용할 수 있도록 도와주는 강력한 도구입니다. 이번 글에서는 Mixin과 Mixin Class를 사용한 사례를 통해 이를 효과적으로 활용하는 방법을 정리하겠습니다.
1. Mixin의 개념
Mixin이란?
- 클래스 간의 코드 재사용을 가능하게 해주는 코드 조각.
- 다중 상속을 지원하지 않는 Dart에서 다중 상속의 대안을 제공합니다.
- with 키워드를 사용하여 Mixin을 클래스에 추가합니다.
Mixin의 특징
- 다중 상속 문제 해결: 단일 상속만 허용하는 Dart에서 코드 조각을 여러 클래스에서 공유할 수 있습니다.
- 코드 재사용: 공통된 기능을 Mixin으로 정의하고, 필요한 클래스에서 가져다 사용할 수 있습니다.
- 독립성: Mixin은 독립된 기능 단위로 설계되어 다른 클래스와 강하게 결합되지 않습니다.
- 인스턴스화 불가: Mixin 자체는 인스턴스화할 수 없습니다.
2. 기본 Mixin 사용 예제
mixin Engine {
int power = 5000;
}
mixin Wheel {
String wheelName = '4륜구동 바퀴';
}
// Mixin 적용: with 키워드 사용
class BMW with Engine, Wheel {
final String engineType;
BMW(this.engineType) {
// 조건에 따라 power 값 설정
if (engineType == 'V8') {
power = 8000;
} else if (engineType == 'V6') {
power = 6000;
} else {
power = 5000; // 기본 값
}
}
void display() {
print('BMW $engineType');
print('Power: $power');
print('Wheel: $wheelName');
}
}
void main() {
BMW bmw1 = BMW('V8');
print(bmw1.power); // 8000
print(bmw1.wheelName); // 4륜구동 바퀴
bmw1.display();
}
출력
8000
4륜구동 바퀴
BMW V8
Power: 8000
Wheel: 4륜구동 바퀴
설명
- Engine과 Wheel Mixin은 BMW 클래스에 기능을 추가합니다.
- with 키워드를 사용하여 Mixin을 클래스에 적용합니다.
- Mixin은 독립적인 코드 조각으로, 클래스를 설계할 때 필요한 기능만 가져와 사용할 수 있습니다.
3. Mixin의 한계: 인스턴스화 불가
Mixin은 독립적으로 인스턴스화할 수 없습니다.
void main() {
// Mixin 자체는 인스턴스화 불가
// Wheel wheel = Wheel(); // 오류 발생
}
해결 방법: Mixin Class
Dart 3.0부터 **mixin class**를 도입하여 Mixin을 인스턴스화할 수 있도록 확장된 기능을 제공합니다.
4. Mixin Class 사용 예제
mixin class Engine {
int power = 5000;
void startEngine() {
print('엔진 시동: $power 마력');
}
}
mixin class Wheel {
String wheelName = '사륜구동바퀴';
void rotateWheels() {
print('$wheelName가 회전합니다.');
}
}
class BMW with Engine, Wheel {}
void main() {
// Mixin Class는 인스턴스화 가능
Engine e = Engine();
Wheel w = Wheel();
e.startEngine(); // 엔진 시동: 5000 마력
w.rotateWheels(); // 사륜구동바퀴가 회전합니다.
// BMW 클래스에서도 Mixin 기능 사용
BMW bmw = BMW();
bmw.startEngine(); // 엔진 시동: 5000 마력
print(bmw.wheelName); // 사륜구동바퀴
}
출력
엔진 시동: 5000 마력
사륜구동바퀴가 회전합니다.
엔진 시동: 5000 마력
사륜구동바퀴
5. Mixin과 Mixin Class 비교
특징MixinMixin Class
인스턴스화 가능 여부 | 불가능 | 가능 |
기능 추가 | 클래스에 코드 조각 추가 | 클래스에 코드 조각 추가 및 독립적 사용 가능 |
사용법 | with 키워드 사용 | with 키워드 사용 + 인스턴스화 가능 |
Dart 버전 | 모든 버전에서 사용 가능 | Dart 3.0 이상 |
6. 요약
- Mixin은 코드 재사용을 위해 사용되며, with 키워드를 통해 클래스로 가져올 수 있습니다.
- Mixin은 독립적으로 인스턴스화할 수 없지만, **mixin class**를 사용하면 이를 해결할 수 있습니다.
- Mixin Class는 인스턴스화 가능하고, 여전히 다른 클래스에 기능을 추가하는 역할도 수행합니다.
- Dart에서 Mixin을 활용하면 유연한 코드 설계와 유지보수가 용이한 구조를 만들 수 있습니다.
Mixin과 Mixin Class를 활용하여 더 효율적이고 확장 가능한 Dart 프로그램을 설계해보세요! 😊
728x90
반응형
'Flutter' 카테고리의 다른 글
[Flutter 18] Dart에서 추상 클래스와 동적 바인딩 활용 (0) | 2025.01.07 |
---|---|
[Flutter 15] storeApp 만들기1 (0) | 2025.01.06 |
[Flutter 14] Dart의 상속과 다형성 (0) | 2025.01.06 |
댓글