본문 바로가기
flutter

플러터 - mixin

by 들풀민들레 2023. 3. 13.
본 글은 [Do it! 깡샘의 플러터&다트 프로그래밍] 의 내용을 발췌한 것입니다.

 

 

책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.

 

믹스인 알아보기


일반 클래스는 class라는 예약어로 선언하고 변수와 함수, 생성자를 정의할 수 있습니다. 그런데 믹스인은 mixin이라는 예약어로 선언합니다.

mixin MyMixin {
	int data1 = 10;
	void myFun1() {
		print('MyMixin... myFun()...');
	}
}

믹스인에는 변수와 함수를 선언할 수 있지만 클래스가 아니므로 생성자는 선언할 수 없습니다.

mixin MyMixin {
	int data1 = 10;
	static int data2 = 20;
	MyMixin() {} // 오류
	void myFun1() {
		print('MyMixin... myFun()...');
	}
	static void myFun2() {}
}

믹스인은 생성자를 가질 수 없으므로 객체를 생성할 수도 없습니다.

mixin MyMixin {
	int data1 = 10;
	void myFun1() {
		print('MyMixin... myFun()...');
	}
}
main() {
	var obj = MyMixin() ; // 오류
}

믹스인 사용하기


생서자를 가질 수 없어서 객체로 만들 수 없는 믹스인은 어떤 쓸모가 있을까요? 다트를 비롯해 대부분의 객체지향 언어에서는 다중 상속을 지원하지 않습니다. 즉, 하나의 클래스만 상속받을 수 있습니다. 따라서 다음과 같은 코드는 오류가 발생합니다.

class Super1 {}
class Super2 {}
class MySub extends Super1, Super2 { // 오류
}

그런데 여러 클래스에 선언된 멤버를 상속한 것처럼 이용하고 싶을 때가 있습니다. 이때 믹스인을 사용합니다. 믹스인을 사용하면 클래스를 상속하지 않고도 믹스인에 선언한 멤버를 다른 클래스에서 사용할 수 있습니다. 이때 with 예약어를 사용합니다.
오른쪽 코드에서는 MyClass에 with My Mixin을 선언해 믹스인의 멤버를 사용합니다.

mixin MyMixin {
	int mixinData = 10;
	void mixInFun() {
		print('MyMixin... mixInFun()...');
	}
}
class MyClass with MyMixin {
	void sayHello() {
		print('data : $mixinData');
		mixInFun();
	}
}

결국 다트는 다중 상속을 제공하지 않는 대신 다른 클래스에서 사용할 수 있는 멤버를 선언할 수 있도록 믹스인을 제공합니다. 다음 코드는 마치 다중 상속처럼 자식 클래스에서 믹스인을 사용한 예입니다.

mixin MyMixin {
	int mixinData = 10;
	void mixInFun() {
		print('MyMixin... mixInFun()...');
	}
}
class MySuper {
	int superData = 20;
	void superFun() {
		print('MySuper... superFun()');
	}
}
class MyClass extends MySuper with MyMixin {
	void sayHello() {
		print('class data : $superData, mixin data : $mixinData');
		mixInFun();
		superFun();
	}
}
main() {
	var obj = MyClass();
	obj.sayHello();
}

또한 with 예약어로 믹스인을 이용하는 클래스의 객체는 믹스인 타입으로 사용할 수 있습니다.

class MyClass with MyMixin {}
main() {
	var obj = MyClass();
	if (obj is MyMixin) {
		print('obj is MyMixin');
	} else {
		print('obj is not MyMixin');
	}
	MyMixin obj2 = MyClass();
}

믹스인 사용 제약


믹스인은 모든 클래스에서 with 예약어로 사용할 수 있습니다. 그런데 특정 타입의 클래스에서만 사용하도록 제한할 수도 있습니다. 이때는 믹스인 선언부에 on 예약어로 해당 타입을 지정합니다.
다음 코드에서는 MyMixin에 on으로 MySuper를 지정했습니다. 따라서 MySuper를 상속받은 MyClass에서는 MyMixin을 사용할 수 있지만, MySomeClass에서는 사용할 수 없습니다.

mixin MyMixin on MySuper {
}
class MySuper {
}
class MyClass extends MySuper with MyMixin { // 성공
}
class MySomeClass with MyMixin { // 오류
}

with로 클래스 이용하기


앞에서 알아본 것처럼 with 예약어는 믹스인을 사용할 때 이용합니다. 하지만 클래스도 with로 이용할 수 있습니다. 다음 코드에서는 MyClass를 선언하면서 with로 SomeClass를 연결했으므로 MyClass에서 SomeClass의 멤버를 이용할 수 있습니다.

class SomeClass {
	int someData = 10;
}
class MyClass with SomeClass {
	void sayHello() {
		print('someData : $someData');
	}
}

보통은 클래스를 extends로 상속받아 이용하지만 믹스인처럼 with로도 이용할 수 있습니다. 즉, 어떤 클래스에서 다른 클래스나 믹스인에 선언된 멤버를 사용할 때 with를 사용할 수 있습니다.
이렇게 보면 믹스인과 클래스는 별 차이가 없는 것 같습니다. 그러나 클래스는 객체를 생성할 수 있지만, 믹스인은 객체를 생성할 수 없습니다. 결국 믹스인은 독립적으로 이용할 수 없으며 다른 클래스에서 공통으로 사용할 변수나 함수를 믹스인에 담아 두고 필요한 클래스에서 with로 연결해서 사용합니다.
또한 with 에약어로 사용할 클래스에는 생성자를 선언할 수 없습니다. 따라서 다음 코드를 실행하면 User 클래스는 생성자를 선언하므로 믹스인으로 사용할 수 없다는 오류가 발생합니다.

class User {
	User() {}
}
class MyClass with User { // 오류
}

 

 

 

책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.

 

 

'flutter' 카테고리의 다른 글

플러터 - Text Widget  (0) 2023.03.13
플러터 - StatefulWidget  (0) 2023.03.13
플러터 - factory constructor  (0) 2023.03.13
플러터 - named constructor  (0) 2023.03.13
플러터 - for, in, switch case, try on catch finally  (2) 2023.03.13