-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path34. mixin.dart
229 lines (200 loc) · 5.57 KB
/
34. mixin.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
/// Mixins in Dart
///
/// Mixins are a way of reusing a class's code in multiple class hierarchies.
/// They allow you to add the functionality of a class to another class without
/// using inheritance. Mixins are a powerful tool for code reuse and composition.
///
/// Key Concepts:
///
/// 1. Code Reuse: Mixins allow you to reuse code in multiple classes without
/// creating a deep inheritance hierarchy.
/// 2. Composition: Mixins promote composition over inheritance, allowing you to
/// combine the functionality of multiple mixins in a single class.
/// 3. `mixin` Keyword: Mixins are defined using the `mixin` keyword.
/// 4. `with` Keyword: Classes use the `with` keyword to include mixins.
/// 5. No Constructor: Mixins cannot have constructors.
/// 6. No `extends`: Mixins cannot extend other classes.
/// 7. Can Implement Interfaces: Mixins can implement interfaces.
/// 8. Can Have Methods and Instance Variables: Mixins can have both methods and
/// instance variables.
/// 9. Can be Used Multiple Times: A mixin can be used in multiple classes.
/// 10. Can Use Other Mixins: A mixin can use other mixins.
/// 11. Order Matters: When using multiple mixins, the order in which they are
/// listed after the `with` keyword matters. If multiple mixins define the
/// same method, the method from the last mixin listed will be used.
/// 12. `on` Keyword: The `on` keyword can be used to restrict the types that can
/// use a mixin.
///
/// Benefits of Using Mixins:
///
/// 1. Code Reusability: Mixins allow you to reuse code in multiple classes
/// without creating a deep inheritance hierarchy.
/// 2. Avoids Diamond Problem: Mixins avoid the diamond problem that can occur
/// with multiple inheritance.
/// 3. Composition over Inheritance: Mixins promote composition over inheritance,
/// which is often a more flexible and maintainable approach.
/// 4. Flexibility: Mixins provide a flexible way to add functionality to
/// classes.
/// 5. Maintainability: Mixins can make code more maintainable by reducing
/// code duplication.
///
/// How Mixins are Defined and Used:
///
/// 1. Defining a Mixin:
/// - Use the `mixin` keyword followed by the mixin name.
/// - Define methods and instance variables within the mixin.
///
/// mixin MyMixin {
/// void myMethod() {
/// print('MyMixin.myMethod');
/// }
/// }
///
/// 2. Using a Mixin:
/// - Use the `with` keyword followed by the mixin name.
/// - A class can use multiple mixins by listing them after the `with` keyword,
/// separated by commas.
///
/// class MyClass with MyMixin {
/// // ...
/// }
///
/// class AnotherClass with MyMixin, AnotherMixin {
/// // ...
/// }
///
/// Example 1: Basic Mixin Implementation
///
/// This example demonstrates a simple mixin `Logger` and a class `User` that
/// uses it.
mixin Logger {
void log(String message) {
print('Log: $message');
}
}
class User with Logger {
String name;
User(this.name);
void greet() {
log('User $name is greeting.');
print('Hello, my name is $name.');
}
}
/// Example 2: Multiple Mixins
///
/// This example demonstrates a class using multiple mixins.
mixin Flyable {
void fly() {
print('Flying...');
}
}
mixin Swimmable {
void swim() {
print('Swimming...');
}
}
class Duck with Flyable, Swimmable {
void quack() {
print('Quack!');
}
}
/// Example 3: Mixin with Instance Variables
///
/// This example demonstrates a mixin with an instance variable.
mixin Counter {
int _count = 0;
void increment() {
_count++;
}
int get count => _count;
}
class Clicker with Counter {
void click() {
increment();
print('Clicked! Count: $count');
}
}
/// Example 4: Mixin with `on` Keyword
///
/// This example demonstrates a mixin that can only be used with classes that
/// implement a specific interface.
abstract class Animal {
void makeSound();
}
mixin Vocal on Animal {
void speak() {
makeSound();
}
}
class Dog extends Animal with Vocal {
@override
void makeSound() {
print('Woof!');
}
}
// class Cat with Vocal { // Error: The mixin 'Vocal' can only be applied to classes that extend 'Animal'.
// @override
// void makeSound() {
// print('Meow!');
// }
// }
/// Example 5: Method Overriding with Mixins
///
/// This example demonstrates how method overriding works with multiple mixins.
mixin A {
void doSomething() {
print('A.doSomething');
}
}
mixin B {
void doSomething() {
print('B.doSomething');
}
}
class C with A, B {
// B's doSomething will be used because it's the last mixin listed.
}
class D with B, A {
// A's doSomething will be used because it's the last mixin listed.
}
void main() {
// Example 1: Basic Mixin Implementation
print('--- Example 1 ---');
User user1 = User('Alice');
user1.greet();
// Output:
// Log: User Alice is greeting.
// Hello, my name is Alice.
// Example 2: Multiple Mixins
print('\n--- Example 2 ---');
Duck duck1 = Duck();
duck1.fly();
duck1.swim();
duck1.quack();
// Output:
// Flying...
// Swimming...
// Quack!
// Example 3: Mixin with Instance Variables
print('\n--- Example 3 ---');
Clicker clicker1 = Clicker();
clicker1.click();
clicker1.click();
clicker1.click();
// Output:
// Clicked! Count: 1
// Clicked! Count: 2
// Clicked! Count: 3
// Example 4: Mixin with `on` Keyword
print('\n--- Example 4 ---');
Dog dog1 = Dog();
dog1.speak();
// Output:
// Woof!
// Example 5: Method Overriding with Mixins
print('\n--- Example 5 ---');
C c = C();
c.doSomething(); // Output: B.doSomething
D d = D();
d.doSomething(); // Output: A.doSomething
}