FlutterFlutter · Chapterبەش 5 · Lectureوانە 5.4
Dart Classes, Inheritance and Mixinsکلاسەکان، بۆماوە و میکسینەکان لە Dartـدا
Classes and objects, every kind of Dart constructor, getters and setters, single inheritance and the diamond problem, abstract classes and interfaces, mixins (the course's Duck example) and extension methods, ending with a Flutter widget read line by line.
و ، هەموو جۆرەکانی لە ، و ، لە یەک و کێشەی ئەڵماس، و ، (نموونەی مراوییەکەی وانەکە) و ، لە کۆتاییدا Flutter دێڕ بە دێڕ دەخوێنرێتەوە.
What you will learnچی فێر دەبیت
- Write a class with fields, methods and the right constructor:
this.x, named andrequiredparameters, named,constandfactoryconstructors. - Use getters, setters and private fields to protect an object's data.
- Explain single inheritance and the diamond problem, and use
extends,superand@override. - Choose between an abstract class, an interface (
implements) and a mixin (with). - Read every word of a Flutter widget's class declaration.
- بە ، و گونجاو بنووسیت:
this.x، ناودار وrequired، ناودار،constوfactory. - ، و تایبەت بەکار بهێنیت بۆ پاراستنی دراوەی .
- لە یەک و کێشەی ئەڵماس ڕوون بکەیتەوە و
extends،superو@overrideبەکار بهێنیت. - لە نێوان ، (
implements) و (with) هەڵبژێریت. - هەموو وشەیەکی ناساندنی Flutter بخوێنیتەوە.
Why classes matter in Flutterبۆچی کلاسەکان لە Flutterـدا گرنگن
Every screen you build in Flutter is made of classes. When you write your own widget, the first line usually looks like this:
هەموو شاشەیەک کە لە Flutterـدا دروستی دەکەیت لە پێک دێت. کاتێک خۆت دەنووسیت، یەکەم دێڕ زۆربەی جار ئاوا دەبێت:
class Greeting extends StatelessWidget {
const Greeting({super.key, required this.name});Almost every word in these two lines is a class idea: class, extends, a const constructor, super.key, required this.name. Flutter itself is a big family of classes: StatelessWidget is an abstract class, the State class uses a mixin, and the button you tap is an object.
نزیکەی هەموو وشەیەکی ئەم دوو دێڕە بیرۆکەیەکی : class، extends، const، super.key و required this.name. خودی Flutter بنەماڵەیەکی گەورەی : StatelessWidget ، State بەکار دەهێنێت و ئەو پەنجەی لێ دەدەیت .
This lesson teaches the Dart you need to read and write those lines: classes and objects, constructors, getters and setters, inheritance, abstract classes and interfaces, mixins and, briefly, extension methods. For the general vocabulary (class, object, method) see Classes and objects in Technical English.
ئەم وانەیە ئەو فێر دەکات کە بۆ خوێندنەوە و نووسینی ئەو دێڕانە پێویستە: و ، ، و ، ، و ، و بە کورتی . بۆ وشە گشتییەکان (، ، ) سەیری کلاسەکان و ئۆبجێکتەکان لە ئینگلیزیی تەکنیکیدا بکە.
Classes and objectsکلاسەکان و ئۆبجێکتەکان
A blueprint for making . It defines which properties and methods its objects have, and new creates an object from it, as in new mysqli(...).
نەخشەیەکە بۆ دروستکردنی . دیاری دەکات ئۆبجێکتەکانی چ تایبەتمەندی و میتۆدێکیان هەیە و new ئۆبجێکتێکی لێ دروست دەکات، وەک new mysqli(...).
A class describes a kind of thing: which data it keeps (its fields, also called properties) and what it can do (its methods). An object is one real thing made from that description. You can make as many objects from one class as you need.
جۆرە شتێک وەسف دەکات: چ دراوەیەک هەڵدەگرێت () و چی دەتوانێت بکات (). یەک شتی ڕاستەقینەیە کە لەو وەسفە دروست دەکرێت. لە یەک هەرچەند پێویست بێت دەتوانیت دروست بکەیت.
class Student {
String name;
int grade;
Student(this.name, this.grade);
void introduce() {
print('I am $name, grade $grade.');
}
}
void main() {
final aram = Student('Aram', 3);
final shilan = Student('Shilan', 4);
aram.introduce();
shilan.introduce();
aram.grade = 4; // change a field of one object
aram.introduce();
shilan.introduce(); // the other object did not change
}I am Aram, grade 3. I am Shilan, grade 4. I am Aram, grade 4. I am Shilan, grade 4.
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2-3
Two fields. Every Student object gets its own
nameandgrade.دوو . هەر Student
nameوgradeـی تایبەتی خۆی هەیە.- Lineدێڕی 5
The constructor:
Student('Aram', 3)puts the two values into the fields.:
Student('Aram', 3)دوو نرخەکە دەخاتە نێو .- Lineدێڕی 7-9
A method: code that belongs to the object and can read its fields.
: کۆدێک کە هی و دەتوانێت بخوێنێتەوە.
- Lineدێڕی 13-14
Two objects from one class. In Dart you do not need the word
new.دوو لە یەک . لە پێویست بە وشەی
newناکات.- Lineدێڕی 19-21
Changing Aram's grade does not touch Shilan's: each object has its own data.
گۆڕینی پۆلی Aram دەست لە هی Shilan نادات: هەر دراوەی خۆی هەیە.
Before Eid, a family fills one wooden kleicha mould again and again. The mould is the class: it decides the shape. Each kleicha that comes out is an object: one has dates inside, another walnuts. The same mould, many different cookies.
پێش جەژن، خێزانێک یەک قاڵبی دارینی کولێچە چەندین جار پڕ دەکاتەوە. قاڵبەکە : شێوەکە دیاری دەکات. هەر کولێچەیەک کە دەردەچێت : یەکێکیان خورمای تێدایە و ئەوی تر گوێز. یەک قاڵب، چەندین کولێچەی جیاواز.
Where the analogy stops workingسنووری ئەم نموونەیە
A baked kleicha cannot change, but an object's fields can change later (unless they are final). And a mould has no 'methods': a class also says what its objects can do.
کولێچەی برژاو ناگۆڕێت، بەڵام دواتر دەتوانن بگۆڕێن (مەگەر final بن). هەروەها قاڵب «»ـی نییە: ئەوەش دەڵێت کە دەتوانن چی بکەن.
Constructors: how objects are bornدروستکەرەکان: ئۆبجێکتەکان چۆن دروست دەبن
A special function of a that makes a new of that class. In Python you call the class's name: list() makes an empty list and list("abc") makes ['a', 'b', 'c']; a class you write yourself sets it up with __init__.
تایبەتی کە نوێی ئەو کلاسە دروست دەکات. لە Pythonـدا ناوی بانگ دەکەیت: list() بەتاڵ دروست دەکات و list("abc") دەکاتە ['a', 'b', 'c']؛ کلاسێک کە خۆت دەینووسیت بە __init__ ئامادەی دەکات.
A constructor has the same name as the class and runs when an object is made. Dart has short ways to write the most common constructors:
هەمان ناوی هەیە و کاتێک دروست دەکرێت جێبەجێ دەبێت. ڕێگای کورتی هەیە بۆ نووسینی باوترین :
this.namein the parameter list copies the argument straight into the fieldname.- Curly braces
{ }make named parameters: the caller writesname: 'Pen', in any order. requiredmeans the caller must give that value. A named parameter withoutrequiredneeds a default value (likethis.stock = 0) or a nullable type (such asString?).finalfields are set once, in the constructor, and never change after that.
this.nameلە لیستی ڕاستەوخۆ دەخاتە نێوnameـەوە.- کەوانەی
{ }دروست دەکات: بانگکەر دەنووسێتname: 'Pen'، بە هەر ڕیزبەندییەک. requiredواتە بانگکەر دەبێت ئەو نرخە بدات. بەبێrequiredپێویستی بە هەیە (وەکthis.stock = 0) یان جۆرێک کە وەربگرێت (وەکString?).-
finalیەک جار لە دادەنرێن و دوای ئەوە هەرگیز ناگۆڕێن.
class Product {
final String name;
final int price; // in Iraqi dinars
final int stock;
Product({required this.name, required this.price, this.stock = 0});
}
void main() {
final tea = Product(name: 'Tea glass', price: 1500, stock: 40);
final pen = Product(price: 500, name: 'Pen'); // any order; stock gets 0
print('${tea.name}: ${tea.price} IQD, ${tea.stock} in stock');
print('${pen.name}: ${pen.price} IQD, ${pen.stock} in stock');
}Tea glass: 1500 IQD, 40 in stock Pen: 500 IQD, 0 in stock
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 6
Named parameters: two
required, one with a default value.: دوانیان
requiredو یەکێکیان بە .- Lineدێڕی 11
The arguments are given by name, so the order does not matter, and
stockgets its default0.بە ناو دەدرێن، بۆیە ڕیزبەندی گرنگ نییە و
stock0وەردەگرێت.
This {required this.x} style is exactly the style of Flutter widgets: Text('Hi', style: ...), Padding(padding: ..., child: ...).
ئەم شێوازی {required this.x}ـە ڕێک شێوازی Flutterـە: Text('Hi', style: ...)، Padding(padding: ..., child: ...).
Constructors: how objects are bornدروستکەرەکان: ئۆبجێکتەکان چۆن دروست دەبن
Named constructorsدروستکەری ناودار
A class can have more than one constructor. The extra ones get a name after a dot: ClassName.something(...). The name tells the reader what kind of object comes out.
دەتوانێت زیاتر لە یەک هەبێت. ئەوانی تر دوای خاڵێک ناوێک وەردەگرن: ClassName.something(...). ناوەکە بە خوێنەر دەڵێت چ جۆرە دەردەچێت.
class Product {
final String name;
final int price;
final int stock;
Product({required this.name, required this.price, this.stock = 0});
// A named constructor: a second, clearly named way to make a Product.
Product.gift(this.name)
: price = 0,
stock = 1;
}
void main() {
final sticker = Product.gift('Sticker');
print('${sticker.name}: ${sticker.price} IQD, ${sticker.stock} in stock');
}Sticker: 0 IQD, 1 in stock
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 9-11
Product.gifthas an initializer list after the colon: it setspriceandstockbefore the object is ready.Product.giftدوای دوو خاڵەکە لیستی دەستپێکردنی هەیە: پێش ئەوەی ئامادە بێتpriceوstockدادەنێت.
Flutter uses named constructors everywhere: EdgeInsets.all(8), EdgeInsets.only(left: 8), ListView.builder(...), Image.asset('logo.png'). Each one is a different, clearly named way to build the same kind of object.
Flutter لە هەموو شوێنێک ناودار بەکار دەهێنێت: EdgeInsets.all(8)، EdgeInsets.only(left: 8)، ListView.builder(...)، Image.asset('logo.png'). هەر یەکەیان ڕێگایەکی جیاواز و ناوی ڕوونە بۆ دروستکردنی هەمان جۆری .
Constructors: how objects are bornدروستکەرەکان: ئۆبجێکتەکان چۆن دروست دەبن
const constructorsدروستکەری const
If every field of a class is final, the class can have a const constructor. Then an object written with const is built once, while the code is compiled, and every identical const object is the very same object in memory.
ئەگەر هەموو final بن، دەتوانێت constـی هەبێت. ئەو کات کە بە const بنووسرێت تەنها یەک جار دروست دەکرێت، لە کاتی کۆمپایلکردنی کۆدەکەدا. هەموو ئەو بە const نووسراون و وەک یەکن، لە یەک .
class Point {
final int x;
final int y;
const Point(this.x, this.y);
}
void main() {
const a = Point(1, 2);
const b = Point(1, 2);
final c = Point(1, 2); // no const: a brand-new object
print(identical(a, b)); // are a and b the very same object?
print(identical(a, c));
}true false
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 5
A
constconstructor: allowed because both fields arefinal.const: ڕێگەپێدراوە چونکە هەردووfinalـن.- Lineدێڕی 9-10
aandbare the same object:identicalsaystrue.aوbهەمان :identicalدەڵێتtrue.- Lineدێڕی 11
Without
constDart makes a new object, soidentical(a, c)isfalse.بەبێ
const، نوێ دروست دەکات، بۆیەidentical(a, c)falseـە.
Why Flutter cares: widgets are immutable, so most of them have const constructors. When you write const Text('Hello'), Flutter can reuse that object instead of making a new one on every rebuild. The default Flutter lints (flutter_lints) ask you to give your own widget classes a const constructor (rule prefer_const_constructors_in_immutables). The stricter rule that marks every place where const could be added, prefer_const_constructors, has not been on by default since flutter_lints 5.0, but many teams switch it on.
بۆچی Flutter گرنگی پێ دەدات: ، بۆیە زۆربەیان constـیان هەیە. کاتێک دەنووسیت const Text('Hello')، Flutter دەتوانێت هەمان دووبارە بەکار بهێنێتەوە لە جیاتی ئەوەی لە هەر دووبارە دروستکردنەوەیەکدا یەکێکی نوێ دروست بکات. یاسا بنەڕەتییەکانی flutter_lints داوات لێ دەکەن const بدەیتە خۆت (یاسای prefer_const_constructors_in_immutables). ئەو یاسا توندترەی هەموو ئەو شوێنانە نیشان دەدات کە دەکرێت constـیان تێدا زیاد بکرێت، واتە prefer_const_constructors، لە flutter_lints 5.0ـەوە بە شێوەی بنەڕەتی چالاک نییە، بەڵام زۆر تیم چالاکی دەکەن.
If a field is not final, the compiler refuses the const constructor:
ئەگەر final نەبێت، const قبووڵ ناکات:
class Box {
int size; // not final!
const Box(this.size);
}
void main() {
print(const Box(1).size);
}Error: Constructor is marked 'const' so all fields must be final. Context: Field isn't final, but constructor is 'const'.
Constructors: how objects are bornدروستکەرەکان: ئۆبجێکتەکان چۆن دروست دەبن
factory constructors and fromJsonدروستکەری factory و fromJson
A normal constructor always makes a new object of its own class and cannot run other code first. A factory constructor is more free: it runs code and then returns an object. It may return an object it kept from before, or even an object of a subclass.
ئاسایی هەمیشە نوێی خۆی دروست دەکات و ناتوانێت پێشتر کۆدی تر جێبەجێ بکات. factory ئازادترە: کۆد جێبەجێ دەکات و پاشان دەگەڕێنێتەوە. دەتوانێت بگەڕێنێتەوە کە پێشتر هەڵیگرتووە، یان تەنانەت .
The most common use in apps is fromJson: data from a server arrives as a Map, and the factory turns it into a typed object.
باوترین بەکارهێنانی لە fromJsonـە: دراوە لە وەک Map دێت و factory دەیکات بە جۆردار.
class Product {
final String name;
final int price;
const Product({required this.name, required this.price});
// A factory constructor: it runs code first, then returns an object.
factory Product.fromJson(Map<String, dynamic> json) {
return Product(
name: json['name'] as String,
price: json['price'] as int,
);
}
}
void main() {
final data = {'name': 'Notebook', 'price': 2000}; // e.g. from a server
final notebook = Product.fromJson(data);
print('${notebook.name} costs ${notebook.price} IQD');
}Notebook costs 2000 IQD
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 8-13
The factory reads the map, checks the types with
as, then returns a normal Product.factoryنەخشەکە دەخوێنێتەوە، جۆرەکان بەasدەپشکنێت و پاشان Productـێکی ئاسایی دەگەڕێنێتەوە.- Lineدێڕی 17
In a real app this map would come from
jsonDecodeof a server answer.لە ڕاستەقینەدا ئەم
Mapـە لەjsonDecodeـی وەڵامی دێت.
Getters, setters and private fieldsمیتۆدەکانی وەرگرتن، میتۆدەکانی دانان و تایبەتمەندییەکانی تایبەت
Sometimes a value should be read like a field but computed, or checked before it is stored. Dart has two special kinds of methods for this:
هەندێک جار نرخێک دەبێت وەک بخوێنرێتەوە بەڵام بژمێردرێت، یان پێش هەڵگرتن بپشکنرێت. دوو جۆری تایبەتی بۆ ئەمە هەیە:
- A getter (
get) is read like a field:battery.isLow, with no parentheses. - A setter (
set) runs when you assign with=:battery.level = 150. - A name that starts with
_is private: only code in the same file (library) can use it.
- (
get) وەک دەخوێنرێتەوە:battery.isLow، بەبێ کەوانە. - (
set) کاتێک بە=نرخ دەدەیت جێبەجێ دەبێت:battery.level = 150. - ناوێک کە بە
_دەست پێ دەکات تایبەتە: تەنها کۆدی هەمان () دەتوانێت بەکاری بهێنێت.
class Battery {
int _level = 50; // the _ makes it private to this file
int get level => _level; // getter: read it like a field
set level(int value) {
_level = value.clamp(0, 100); // setter: keep it between 0 and 100
}
bool get isLow => _level < 20; // a computed getter
}
void main() {
final battery = Battery();
print('Level: ${battery.level}, low: ${battery.isLow}');
battery.level = 150; // calls the setter
print('Level: ${battery.level}');
battery.level = 10;
print('Level: ${battery.level}, low: ${battery.isLow}');
}Level: 50, low: false Level: 100 Level: 10, low: true
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2
The real value is private. Code in other files cannot set it to -5 or 900.
نرخە ڕاستەقینەکە تایبەتە. کۆدی تر ناتوانێت بیکات بە -5 یان 900.
- Lineدێڕی 4
Getter: other code reads
battery.levelbut cannot change_leveldirectly.: کۆدی تر
battery.levelدەخوێنێتەوە بەڵام ناتوانێت ڕاستەوخۆ_levelبگۆڕێت.- Lineدێڕی 6-8
Setter:
clamp(0, 100)keeps the value in range, so 150 becomes 100.:
clamp(0, 100)نرخەکە لە سنووردا دەهێڵێتەوە، بۆیە 150 دەبێتە 100.- Lineدێڕی 10
A computed getter: it has no field of its own, it is calculated each time.
ژمێردراو: خۆی نییە، هەموو جارێک دەژمێردرێت.
Every normal field already has a hidden getter (and a hidden setter if it is not final). So you can start with a plain field and later turn it into a getter/setter pair without changing the code that uses it.
هەموو ئاسایی پێشتر شاراوەی هەیە (و شاراوەش ئەگەر final نەبێت). بۆیە دەتوانیت بە سادە دەست پێ بکەیت و دواتر بیکەیت بە جووتێک و بەبێ گۆڕینی ئەو کۆدەی بەکاری دەهێنێت.
Inheritance: extends, super and @overrideبۆماوە: extends، super و @override
Making a new from an existing one: the new class (subclass) gets the fields and methods of the old one (superclass) and can add or change some. Dart allows single inheritance: a class extends only one class.
دروستکردنی نوێیە لە کلاسێکی هەبووەوە: کلاسە نوێیەکە (subclass) ستوون و میتۆدەکانی کلاسە کۆنەکە (superclass) وەردەگرێت و دەتوانێت هەندێکیان زیاد بکات یان بگۆڕێت. Dart تەنها یەک بۆماوە ڕێگە دەدات: هەر کلاسێک تەنها یەک کلاس extends دەکات.
With extends, a new class (the subclass) gets all fields and methods of an existing class (the superclass). The subclass can add its own members and can override inherited methods, that is, write its own version of them.
بە extends، نوێ () هەموو و هەبوو () وەردەگرێت. دەتوانێت ئەندامی خۆی زیاد بکات و دەتوانێت بۆماوەگیراو پێناسە بکاتەوە ()، واتە وەشانی خۆی لێیان بنووسێت.
class Bird {
final String name;
Bird(this.name);
void chirp() => print('$name: Chirping!');
String describe() => '$name is a bird';
}
class Duck extends Bird {
Duck(super.name); // hands name up to Bird's constructor
@override
String describe() => '${super.describe()} that can quack';
void quack() => print('$name: Quack!');
}
void main() {
final sparrow = Bird('Sparrow');
final duck = Duck('Duck');
print(sparrow.describe());
print(duck.describe()); // Duck's own version
duck.chirp(); // inherited from Bird
duck.quack(); // only Duck has it
}Sparrow is a bird Duck is a bird that can quack Duck: Chirping! Duck: Quack!
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 11
extends Bird: Duck is a subclass of Bird.extends Bird: Duck Birdـە.- Lineدێڕی 12
A super parameter:
super.namepasses the name to Bird's constructor. Constructors are not inherited, so a subclass must call one.super:
super.nameناوەکە دەنێرێت بۆ Bird. بە نایەن، بۆیە دەبێت بانگی یەکێکیان بکات.- Lineدێڕی 14-15
@overridemarks Duck's own version ofdescribe().super.describe()still calls Bird's version.@overrideوەشانی تایبەتی Duck لەdescribe()نیشانە دەکات.super.describe()هێشتا بانگی وەشانەکەی Bird دەکات.- Lineدێڕی 26
chirp()is not written in Duck: it is inherited from Bird.chirp()لە Duckـدا نەنووسراوە: لە Birdـەوە بە هاتووە.
Now you can read const MyApp({super.key}): it is a super parameter. Every widget passes its optional key up to the constructor of Widget, the superclass of all widgets.
ئێستا دەتوانیت const MyApp({super.key}) بخوێنیتەوە: ئەمە superـە. هەموو keyـی ئیختیاری خۆی دەنێرێت بۆ Widget، کە هەموو .
A child inherits a lot from a parent: the family name, the house, maybe the shop in the bazaar. The child does not rebuild the shop but runs it in its own way (override) and may add a new shelf (new methods).
منداڵ زۆر شت لە دایک و باوکی بە میرات وەردەگرێت: ناوی خێزان، خانووەکە، لەوانەیە دوکانەکەی بازاڕیش. منداڵەکە دوکانەکە سەرلەنوێ دروست ناکاتەوە، بەڵام بە شێوازی خۆی بەڕێوەی دەبات () و لەوانەیە ڕەفێکی نوێی بۆ زیاد بکات ( نوێ).
Where the analogy stops workingسنووری ئەم نموونەیە
In Dart a child class has exactly one parent class; a person has two parents. The second 'parent' idea comes back as mixins.
لە ڕێک یەک هەیە؛ مرۆڤ دوو دایک و باوکی هەیە. بیرۆکەی «باوکی دووەم» وەک دەگەڕێتەوە.
Inheritance: extends, super and @overrideبۆماوە: extends، super و @override
Single inheritance and the diamond problemبۆماوە لە یەک کلاسەوە و کێشەی ئەڵماس
In Dart, single inheritance means that a class can directly extend only one other class. This is the usual choice in object-oriented languages (Java and C# do the same): it keeps the family of classes simple and avoids the diamond problem, which appears in languages that allow multiple inheritance.
لە ، لە یەک واتە ڕاستەوخۆ دەتوانێت تەنها یەک تر extends بکات. ئەمە هەڵبژاردنی باوی زمانەکانی (Java و C# هەمان شت دەکەن): بنەماڵەی سادە دەهێڵێتەوە و ڕێگری لە کێشەی ئەڵماس (diamond problem) دەکات کە لەو زمانانەدا دەردەکەوێت کە ڕێگە بە لە چەند دەدەن.
Picture it: Bird and Fish both have a move() method, one flies and one swims. If FlyingFish could extend both, move() would be ambiguous. Dart simply does not allow it:
وێنای بکە: Bird و Fish هەردووکیان move()ـیان هەیە، یەکێکیان دەفڕێت و ئەوی تر مەلە دەکات. ئەگەر FlyingFish بیتوانیایە هەردووکیان extends بکات، move() ناڕوون دەبوو. بە سادەیی ڕێگەی پێ نادات:
class Bird {}
class Fish {}
class FlyingFish extends Bird, Fish {}
void main() {}Error: Each class definition can have at most one extends clause. Try choosing one superclass and define your class to implement (or mix in) the others.
The error message already points to the two Dart answers: implement the other class (an interface, below) or mix it in (a mixin, later in this lesson).
پەیامی هەڵەکە خۆی ئاماژە بە دوو وەڵامەکەی دەکات: تر implement بکە (، لە خوارەوە) یان mix inـی بکە (، دواتر لەم وانەیەدا).
Abstract classesکلاسە ڕووتەکان
A that only describes what its subclasses must do and cannot be used to make objects itself. In MVVM an abstract TodoService lists the methods, and TodoServiceRest and TodoServiceMock implement them.
کە تەنها وەسف دەکات کلاسە لاوەکییەکانی دەبێت چی بکەن و خۆی ناتوانرێت ئۆبجێکتی لێ دروست بکرێت. لە MVVMـدا TodoServiceـی ڕووت میتۆدەکان ڕیز دەکات و TodoServiceRest و TodoServiceMock جێبەجێیان دەکەن.
Sometimes a class is only a general idea: a shape has an area, but you cannot draw 'a shape' without knowing if it is a circle or a square. Mark such a class abstract. It may contain abstract methods: a method header with ; and no body. Every non-abstract subclass must write those bodies.
هەندێک جار تەنها بیرۆکەیەکی گشتییە: شێوە ڕووبەری هەیە، بەڵام ناتوانیت «شێوەیەک» بکێشیت بەبێ ئەوەی بزانیت بازنەیە یان چوارگۆشە. ئەو جۆرە بە abstract نیشانە بکە. دەتوانێت چەند ڕووت لەخۆ بگرێت: سەری بە ; و بەبێ جەستە. هەموو ناڕووت دەبێت ئەو جەستانە بنووسێت.
import 'dart:math';
abstract class Shape {
String get name;
double area(); // no body: every kind of shape writes its own
void describe() => print('$name: area ${area().toStringAsFixed(1)}');
}
class Circle extends Shape {
final double radius;
Circle(this.radius);
@override
String get name => 'Circle';
@override
double area() => pi * radius * radius;
}
class Square extends Shape {
final double side;
Square(this.side);
@override
String get name => 'Square';
@override
double area() => side * side;
}
void main() {
final shapes = <Shape>[Circle(2), Square(3)];
for (final shape in shapes) {
shape.describe();
}
}Circle: area 12.6 Square: area 9.0
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 3
abstract: you cannot writeShape().abstract: ناتوانیتShape()بنووسیت.- Lineدێڕی 4-5
Abstract members: no body, only the promise.
ئەندامی ڕووت: جەستەیان نییە، تەنها بەڵێنەکە.
- Lineدێڕی 7
An abstract class may still have normal methods.
describe()works for every shape.هێشتا دەتوانێت ئاسایی هەبێت.
describe()بۆ هەموو شێوەیەک کار دەکات.- Lineدێڕی 32-37
One list of Shapes, two kinds inside; each answers
area()in its own way.یەک لیستی Shape، دوو جۆری تێدایە؛ هەریەکەیان بە شێوازی خۆی وەڵامی
area()دەداتەوە.
abstract class Shape {
double area();
}
void main() {
final s = Shape();
print(s.area());
}Error: The class 'Shape' is abstract and can't be instantiated.
You use abstract classes in every Flutter app: StatelessWidget and StatefulWidget are abstract. They demand one method from you, build (or createState), and give you everything else.
لە هەموو Flutterـدا بەکار دەهێنیت: StatelessWidget و StatefulWidget ڕووتن. تەنها یەک لە تۆ داوا دەکەن، build (یان createState). هەموو شتەکانی تریش خۆیان دەیدەن.
Abstract classesکلاسە ڕووتەکان
Interfaces: implementsڕووکارەکان: implements
In Dart every class is also an interface: the list of its public members. With implements, a class promises to provide all of them, written by itself; nothing is inherited. A class may extend only one class, but it may implement many interfaces.
لە هەموو : لیستی ئەندامە گشتییەکانی. بە implements، بەڵێن دەدات هەموویان دابین بکات، بە نووسینی خۆی؛ هیچ شتێک بە نایەت. تەنها دەتوانێت یەک extends بکات، بەڵام دەتوانێت چەندین implement بکات.
abstract class MessageSender {
void send(String to, String text);
}
class SmsSender implements MessageSender {
@override
void send(String to, String text) => print('SMS to $to: $text');
}
class EmailSender implements MessageSender {
@override
void send(String to, String text) => print('E-mail to $to: $text');
}
// This function works with ANY MessageSender.
void remind(MessageSender sender) {
sender.send('Aram', 'The lab moves to room 12.');
}
void main() {
remind(SmsSender());
remind(EmailSender());
}SMS to Aram: The lab moves to room 12. E-mail to Aram: The lab moves to room 12.
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 1-3
The interface: what every sender must be able to do.
: ئەوەی هەموو نێرەرێک دەبێت بتوانێت بیکات.
- Lineدێڕی 5, 10
Two classes implement it in different ways.
دوو بە دوو شێوازی جیاواز implementـی دەکەن.
- Lineدێڕی 16-18
remindonly knows the interface. It works with any sender, even one written next year.remindتەنها دەناسێت. لەگەڵ هەر نێرەرێک کار دەکات، تەنانەت ئەوەی ساڵی داهاتوو دەنووسرێت.
This is how bigger Flutter apps are organised: an abstract TodoService describes the work, and a real (internet) version and a fake version for tests both implement it. The screen does not care which one it gets.
گەورەتری Flutter بەم شێوەیە ڕێک دەخرێن: TodoServiceـێکی ڕووت کارەکە وەسف دەکات و وەشانێکی ڕاستەقینە () و وەشانێکی ساختە بۆ تاقیکردنەوە هەردووکیان implementـی دەکەن. شاشەکە گرنگی پێ نادات کامیانی پێ دەدرێت.
Mixins: abilities from several placesمیکسینەکان: توانا لە چەند شوێنێکەوە
A set of methods and fields that can be mixed into many classes with with, so a class can get abilities from several places although it extends only one class. In Dart 3 it is declared with mixin or mixin class.
کۆمەڵێک میتۆد و ستوونە کە دەتوانرێت بە with تێکەڵی چەندین کلاس بکرێت، بۆ ئەوەی کلاسێک لە چەند شوێنێکەوە توانا وەربگرێت هەرچەندە تەنها یەک کلاس extends دەکات. لە Dart 3ـدا بە mixin یان mixin class دەناسێنرێت.
Sometimes several unrelated classes need the same ability: a duck, a bat and a plane can all fly. Flying is not a 'kind of' anything, so it does not fit into one family tree, and copying fly() into every class would be bad code. Dart's answer is the mixin: a bundle of methods (and fields), without a constructor, that you declare with the keyword mixin and add to a class with with. A class still has one superclass, but it can take behaviour from many mixins. This is what the course notes call single inheritance with mixin support.
هەندێک جار چەند جیاواز پێویستیان بە هەمان توانا هەیە: مراوی، شەمشەمەکوێرە و فڕۆکە هەموویان دەفڕن. فڕین جۆرێک لە هیچ شتێک نییە، بۆیە لە یەک دارەخێزاندا جێی نابێتەوە. هەروەها کۆپیکردنی fly() بۆ نێو هەموو کۆدێکی خراپە. وەڵامی : کۆمەڵێک (و )، بەبێ ، کە بە mixin دەیناسێنیت و بە with دەیخەیتە سەر . هێشتا یەک هەیە، بەڵام دەتوانێت ڕەفتار لە چەندین وەربگرێت. تێبینییەکانی وانەکە ئەمە ناو دەنێن لە یەک بە پشتگیریی .
Mixins: abilities from several placesمیکسینەکان: توانا لە چەند شوێنێکەوە
The course's Duck: one superclass, two mixinsمراوییەکەی وانەکە: یەک کلاسی باوک، دوو میکسین
The course notes show this with a duck. A duck is a bird (inheritance), and it can also fly and swim (two mixins):
تێبینییەکانی وانەکە ئەمە بە مراوییەک پیشان دەدەن. مراوی باڵندەیە () و هەروەها دەتوانێت بفڕێت و مەلە بکات (دوو ):
mixin Fly {
void fly() => print("Flying!");
}
mixin Swim {
void swim() => print("Swimming!");
}
class Bird {
void chirp() => print("Chirping!");
}
class Duck extends Bird with Fly, Swim {}
void main() {
Duck duck = Duck();
duck.chirp(); // Inherited from Bird
duck.fly(); // Mixed in from Fly
duck.swim(); // Mixed in from Swim
}Chirping! Flying! Swimming!
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 1-7
Two mixins, each with one ability.
دوو ، هەریەکە بە یەک توانا.
- Lineدێڕی 13
One superclass (
extends Bird) plus two mixins (with Fly, Swim).یەک (
extends Bird) لەگەڵ دوو (with Fly, Swim).- Lineدێڕی 17-19
One object, three abilities from three places.
یەک ، سێ توانا لە سێ شوێنەوە.


Your superclass is like your family: you have exactly one, and you inherit a lot from it. Mixins are like training courses. A teacher, a taxi driver and a shopkeeper can all take the same first-aid course and gain the same skill, although they come from different families.
وەک خێزانەکەتە: ڕێک یەکێکت هەیە و زۆر شتی لێ بە میرات وەردەگریت. وەک خولی ڕاهێنانن. مامۆستایەک، شۆفێری تەکسییەک و دوکاندارێک هەموویان دەتوانن هەمان خولی فریاگوزاری ببینن و هەمان توانا وەربگرن، هەرچەندە لە خێزانی جیاوازەوە دێن.
Where the analogy stops workingسنووری ئەم نموونەیە
A mixin adds code to the class itself, and if two courses teach a skill with the same name, the last one you take replaces the earlier one (see below).
کۆد بۆ خودی زیاد دەکات و ئەگەر دوو خول توانایەک بە هەمان ناو فێر بکەن، ئەوەی دواتر وەریدەگریت جێگەی پێشووتر دەگرێتەوە (لە خوارەوە ببینە).
Mixins: abilities from several placesمیکسینەکان: توانا لە چەند شوێنێکەوە
Mixin rules in Dart 3یاساکانی میکسین لە Dart 3ـدا
- A
mixincannot extend a class and cannot declare a constructor. It is a bundle of members, not a full class. mixin X on Birdlimits the mixin to subclasses ofBird. In return the mixin may use Bird's members (andsuper).- Since Dart 3, a normal
classcan no longer be used afterwith. Declare itmixinormixin class. Amixin classcan be used both ways: afterextendsand afterwith.
mixinناتوانێت extends بکات و ناتوانێت بناسێنێت. کۆمەڵێک ئەندامە، نەک تەواو.mixin X on Birdتەنها بۆBirdسنووردار دەکات. لە بەرامبەردا دەتوانێت ئەندامەکانی Bird بەکار بهێنێت (وsuper).- لە 3ـەوە،
classـی ئاسایی چیتر دوایwithبەکار نایەت. بەmixinیانmixin classبیناسێنە.mixin classبە هەردوو شێوە بەکار دێت: دوایextendsو دوایwith.
class Bird {
final String name;
Bird(this.name);
}
mixin Swim on Bird {
// "on Bird": only Birds may use it, so it can read name
void swim() => print('$name is swimming');
}
class Duck extends Bird with Swim {
Duck(super.name);
}
void main() {
Duck('Duck').swim();
}Duck is swimming
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 6-9
on Bird: the mixin can readnamebecause every user of it is a Bird.on Bird: دەتوانێتnameبخوێنێتەوە چونکە هەموو بەکارهێنەرێکی Birdـە.
A class that is not a Bird cannot use it. class Boat with Swim {} gives:
کە Bird نییە ناتوانێت بەکاری بهێنێت. class Boat with Swim {} ئەمە دەدات:
class Boat with Swim {}Error: 'Object' doesn't implement 'Bird' so it can't be used with 'Swim'.
Mixins: abilities from several placesمیکسینەکان: توانا لە چەند شوێنێکەوە
mixin class, and mixins in Fluttermixin class و میکسینەکان لە Flutterـدا
mixin class: یەک ناساندن، دوو بەکارهێنانDARTmixin class Logger {
void log(String message) => print('[log] $message');
}
class Downloader with Logger {} // used as a mixin
class FileLogger extends Logger {} // used as a normal class
void main() {
Downloader().log('download started');
FileLogger().log('saved to a file');
}[log] download started [log] saved to a file
import 'package:flutter/material.dart';
class Pulse extends StatefulWidget {
const Pulse({super.key});
@override
State<Pulse> createState() => _PulseState();
}
// SingleTickerProviderStateMixin is declared "on State", so it can
// only be mixed into State classes. It gives this class a ticker.
class _PulseState extends State<Pulse> with SingleTickerProviderStateMixin {
late final AnimationController _controller = AnimationController(
vsync: this, // "this" can act as a TickerProvider thanks to the mixin
duration: const Duration(seconds: 1),
)..repeat(reverse: true);
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return FadeTransition(opacity: _controller, child: const Icon(Icons.favorite));
}
}Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 12
with SingleTickerProviderStateMixin: allowed because_PulseStateis aState.with SingleTickerProviderStateMixin: ڕێگەپێدراوە چونکە_PulseStateStateـە.- Lineدێڕی 14
vsync: thisworks because the mixin made this object a ticker provider.vsync: thisکار دەکات چونکە ئەم کردووە بە دابینکەری ticker.
Mixins: abilities from several placesمیکسینەکان: توانا لە چەند شوێنێکەوە
When two mixins clash: the last one winsکاتێک دوو میکسین پێکدادەدەن: دواییەکەیان دەیباتەوە
What if two mixins have a method with the same name, the diamond situation again? Dart has a fixed rule: the class is built in the order you write it: the superclass first, then each mixin from left to right. A later layer covers an earlier one, so the last mixin wins.
ئەگەر دوو بە هەمان ناو هەبێت چی دەبێت، دیسانەوە دۆخی ئەڵماس؟ یاسایەکی جێگیری هەیە: بەو ڕیزبەندییەی دەینووسیت دروست دەکرێت: سەرەتا ، پاشان هەر لە چەپەوە بۆ ڕاست. چینێکی دواتر چینێکی پێشتر دادەپۆشێت، بۆیە دوایین دەیباتەوە.
class Bird {
String move() => 'walking';
}
mixin Fly {
String move() => 'flying';
}
mixin Swim {
String move() => 'swimming';
}
class Duck extends Bird with Fly, Swim {}
class Goose extends Bird with Swim, Fly {}
void main() {
print(Duck().move()); // the last mixin (Swim) wins
print(Goose().move()); // here the last one is Fly
}swimming flying
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 13
Order: Bird, then Fly, then Swim. Swim is on top.
ڕیزبەندی: Bird، پاشان Fly، پاشان Swim. Swim لە سەرەوەیە.
- Lineدێڕی 15
Order: Bird, then Swim, then Fly. Fly is on top.
ڕیزبەندی: Bird، پاشان Swim، پاشان Fly. Fly لە سەرەوەیە.
So mixins give a class abilities from several places without the diamond problem: there is never a doubt about which method runs.
کەواتە لە چەند شوێنێکەوە توانا دەدەنە بەبێ کێشەی ئەڵماس: هەرگیز گومان نییە کام جێبەجێ دەبێت.
Extension methods (briefly)میتۆدەکانی پاشکۆ (بە کورتی)
You cannot change Dart's own int or String classes, but sometimes you want one more method on them. An extension adds methods to an existing type from the outside:
ناتوانیت int و Stringـی خودی بگۆڕیت، بەڵام هەندێک جار زیاترت لەسەریان دەوێت. extension لە دەرەوە بۆ جۆرێکی هەبوو زیاد دەکات:
extension KurdishDigits on int {
String toKurdishDigits() {
const digits = '٠١٢٣٤٥٦٧٨٩';
return toString().split('').map((d) => digits[int.parse(d)]).join();
}
}
void main() {
print(2026.toKurdishDigits());
print(15.toKurdishDigits());
}٢٠٢٦ ١٥
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 1
extension KurdishDigits on int: the new methods belong to everyint.extension KurdishDigits on int: نوێیەکان هی هەمووintـێکن.- Lineدێڕی 4
Inside the extension,
toString()meansthis.toString(): the number itself.لەنێو extensionـەکەدا،
toString()واتەthis.toString(): خودی ژمارەکە.- Lineدێڕی 9
Now any integer has
toKurdishDigits().ئێستا هەموو
toKurdishDigits()ـی هەیە.
Flutter packages use extensions to make code read naturally: for example, the provider package adds context.watch<T>() to every BuildContext with an extension. For now it is enough to recognise the words extension ... on .... (This small example handles only non-negative numbers.)
پاکێجەکانی Flutter extension بەکار دەهێنن بۆ ئەوەی کۆد سروشتی بخوێنرێتەوە: بۆ نموونە پاکێجی provider بە extensionـێک context.watch<T>() بۆ هەموو BuildContextـێک زیاد دەکات. ئێستا بەسە وشەکانی extension ... on ... بناسیتەوە. (ئەم نموونە بچووکە تەنها ژمارەی نانەرێنی بەڕێوە دەبات.)
Two short Dart chapters from freeCodeCamp: adding methods to a class with an extension, and what a Future is.
دوو بەشی کورتی لە freeCodeCampـەوە: زیادکردنی بۆ بە extension، هەروەها (Future) چییە.
Plays 4:25:57-4:30:02: an extension that adds a fullName getter to Person.
لە 4:25:57 تا 4:30:02 پەخش دەبێت: extensionـێک کە بە ناوی fullName بۆ Person زیاد دەکات.
Reading a widget class line by lineخوێندنەوەی کلاسی ویجێتێک دێڕ بە دێڕ
Now put everything together. Here is a small but real Flutter widget:
ئێستا هەموو شتەکان پێکەوە دابنێ. ئەمە بچووک بەڵام ڕاستەقینەی Flutterـە:
import 'package:flutter/material.dart';
class Greeting extends StatelessWidget {
const Greeting({super.key, required this.name});
final String name;
@override
Widget build(BuildContext context) {
return Text('Hello, $name!');
}
}| Codeکۆد | What you learnedئەوەی فێری بوویت |
|---|---|
class Greeting extends StatelessWidget | A subclass of the abstract class StatelessWidget. StatelessWidget. |
const Greeting({...}) | A const constructor: allowed because every field is final. const: ڕێگەپێدراوە چونکە هەموو finalـە. |
super.key | A super parameter: the key goes up to Widget's constructor. super: key بەرز دەبێتەوە بۆ Widget. |
required this.name | A required named parameter that fills the field name. پێویست کە name پڕ دەکاتەوە. |
final String name; | A field that never changes: widgets are immutable. کە هەرگیز ناگۆڕێت: . |
@override Widget build(...) | Overrides the abstract method build of the superclass. ڕووتی buildـی پێناسە دەکاتەوە. |
Common mistakesهەڵە باوەکان
| Mistakeهەڵە | What happensچی ڕوو دەدات | Fixچاکردنەوە |
|---|---|---|
class C extends A, B {} | Compile-time error: at most one extends.: لانیزۆر یەک extends. | Extend one class; use with (mixins) or implements for the others.یەک extends بکە؛ بۆ ئەوانی تر with () یان implements بەکار بهێنە. |
const Box(this.size); // size not final | Error: all fields of a const constructor must be final.هەڵە: هەموو const دەبێت final بن. | Make every field final.هەموو بکە بە final. |
Product({this.name}); // String name | Error: a non-nullable named parameter needs required or a default value.هەڵە: کە وەرناگرێت required یان پێویستە. | Write required this.name.بنووسە required this.name. |
Shape() | Error: an abstract class cannot be instantiated.هەڵە: لێ دروست ناکرێت. | Create an object of a concrete subclass, e.g. Square(3). لە ناڕووت دروست بکە، بۆ نموونە Square(3). |
class Fly { } ... with Fly | Dart 3 error: a normal class cannot be mixed in.هەڵەی 3: ئاسایی تێکەڵ ناکرێت. | Declare it mixin Fly or mixin class Fly.بە mixin Fly یان mixin class Fly بیناسێنە. |
String describe() => ... // no @override | Works, but the linter warns; readers cannot see it replaces a superclass method.کار دەکات، بەڵام linter ئاگادار دەکاتەوە؛ خوێنەر نابینێت کە دەگۆڕێتەوە. | Write @override above every overriding member.لە سەرووی هەموو ئەندامێکی پێناسەکراوەوە @override بنووسە. |
battery.isLow() | Error: a getter is not called with ().هەڵە: بە () بانگ ناکرێت. | Write battery.isLow.بنووسە battery.isLow. |
Exercisesڕاهێنانەکان
Write a class Book with final fields title (String) and pages (int), a const constructor with required named parameters, and a getter isLong that is true when the book has more than 300 pages. Create one book and print its title and isLong.
Book بنووسە بە finalـی title (String) و pages (int)، const بە پێویست و isLong کە trueـە کاتێک کتێبەکە لە ٣٠٠ لاپەڕە زیاترە. کتێبێک دروست بکە و ناونیشان و isLongـی چاپ بکە.
Hintئاماژە
A getter has no parentheses: bool get isLong => ...;
کەوانەی نییە: bool get isLong => ...;
Show answerوەڵامەکە پیشان بدە
class Book {
final String title;
final int pages;
const Book({required this.title, required this.pages});
bool get isLong => pages > 300;
}
void main() {
const book = Book(title: 'Mem u Zin', pages: 320);
print('${book.title}: long? ${book.isLong}');
}Mem u Zin: long? true
Without running it, write the output. Then explain each line.
بەبێ جێبەجێکردن، دەرخستەکە بنووسە. پاشان هەر دێڕێک ڕوون بکەرەوە.
class Bird {
final String name;
Bird(this.name);
void chirp() => print('$name: Chirping!');
String describe() => '$name is a bird';
}
class Duck extends Bird {
Duck(super.name); // hands name up to Bird's constructor
@override
String describe() => '${super.describe()} that can quack';
void quack() => print('$name: Quack!');
}
void main() {
final sparrow = Bird('Sparrow');
final duck = Duck('Duck');
print(sparrow.describe());
print(duck.describe()); // Duck's own version
duck.chirp(); // inherited from Bird
duck.quack(); // only Duck has it
}Show answerوەڵامەکە پیشان بدە
Answer:
وەڵام:
Sparrow is a bird
Duck is a bird that can quack
Duck: Chirping!
Duck: Quack!- Line 1: Bird's own
describe(). - Line 2: Duck overrides
describe()and callssuper.describe()first. - Line 3:
chirp()is inherited from Bird;nameis 'Duck'. - Line 4:
quack()exists only in Duck.
- دێڕی ١:
describe()ـی خودی Bird. - دێڕی ٢: Duck
describe()پێناسە دەکاتەوە و سەرەتا بانگیsuper.describe()دەکات. - دێڕی ٣:
chirp()لە Birdـەوە بە هاتووە؛nameبریتییە لە 'Duck'. - دێڕی ٤:
quack()تەنها لە Duckـدا هەیە.
Start from the course's Duck example. Add a third mixin Quack with a method quack() that prints Quack!, and make Duck use it. What does class Duck extends Bird with Fly, Swim, Quack {} now print when main also calls duck.quack()?
لە نموونەی Duckـی وانەکەوە دەست پێ بکە. سێیەم بە ناوی Quack زیاد بکە بە quack() کە Quack! چاپ دەکات و وای لێ بکە Duck بەکاری بهێنێت. ئێستا کاتێک main بانگی duck.quack()ـیش دەکات، class Duck extends Bird with Fly, Swim, Quack {} چی چاپ دەکات؟
Show answerوەڵامەکە پیشان بدە
mixin Quack {
void quack() => print("Quack!");
}
class Duck extends Bird with Fly, Swim, Quack {}
// in main():
duck.quack(); // Mixed in from QuackChirping! Flying! Swimming! Quack!
A class may use as many mixins as it needs; they are separated by commas after with.
دەتوانێت هەرچەند پێویست بێت بەکار بهێنێت؛ دوای with بە کۆما لێک جیا دەکرێنەوە.
Exercisesڕاهێنانەکان
More exercisesڕاهێنانی زیاتر
This code does not compile: the compiler reports four errors. Find and fix them.
ئەم کۆدە کۆمپایل نابێت: چوار هەڵە ڕادەگەیەنێت. بیاندۆزەرەوە و چاکیان بکەرەوە.
abstract class Device {
String get name;
}
class Camera {
void takePhoto() => print('Click!');
}
class Phone extends Device, Camera {
String model;
const Phone(this.model);
@override
String get name => 'Phone $model';
}
void main() {
final d = Device();
print(d.name);
}Show answerوەڵامەکە پیشان بدە
class Phone extends Device, Camera→ only oneextends. MakeCameraa mixin:mixin Camera { ... }and writeclass Phone extends Device with Camera.String model;in a class with aconstconstructor → writefinal String model;.const Phone(...)calls the constructor ofDevice, which is notconst(Dart: A constant constructor can't call a non-constant super constructor) → giveDeviceaconst Device();constructor, or removeconstfromPhone.Device()whereDeviceis abstract → create aPhoneinstead.
class Phone extends Device, Camera← تەنها یەکextends.Cameraبکە بە :mixin Camera { ... }و بنووسەclass Phone extends Device with Camera.String model;لە بەconst← بنووسەfinal String model;.const Phone(...)بانگیDeviceدەکات کەconstنییە ( دەڵێت: A constant constructor can't call a non-constant super constructor) ←const Device();بدە بەDevice، یانconstلەPhoneلابە.Device()لە کاتێکداDeviceڕووتە ← لە جیاتی ئەوەPhoneدروست بکە.
abstract class Device {
const Device();
String get name;
}
mixin Camera {
void takePhoto() => print('Click!');
}
class Phone extends Device with Camera {
final String model;
const Phone(this.model);
@override
String get name => 'Phone $model';
}
void main() {
const p = Phone('X1');
print(p.name);
p.takePhoto();
}Phone X1 Click!
Write an abstract class PaymentMethod with void pay(int amount). Write Cash and Card that implement it (print Paid 5000 IQD in cash / Paid 5000 IQD by card). Write a function checkout(PaymentMethod m) that pays 5000 with any method.
PaymentMethod بنووسە بە void pay(int amount). Cash و Card بنووسە کە implementـی بکەن (چاپ بکەن Paid 5000 IQD in cash / Paid 5000 IQD by card). checkout(PaymentMethod m) بنووسە کە بە هەر ڕێگایەک ٥٠٠٠ دەدات.
Show answerوەڵامەکە پیشان بدە
abstract class PaymentMethod {
void pay(int amount);
}
class Cash implements PaymentMethod {
@override
void pay(int amount) => print('Paid $amount IQD in cash');
}
class Card implements PaymentMethod {
@override
void pay(int amount) => print('Paid $amount IQD by card');
}
void checkout(PaymentMethod m) => m.pay(5000);
void main() {
checkout(Cash());
checkout(Card());
}Paid 5000 IQD in cash Paid 5000 IQD by card
checkout depends only on the interface. You can add MobileWallet later without touching it.
checkout تەنها پشت بە دەبەستێت. دەتوانیت دواتر MobileWallet زیاد بکەیت بەبێ دەستلێدانی.
Summaryپوختە
- A class is a blueprint; objects are made from it, each with its own field values.
- Constructors:
this.x, named parameters withrequired, named constructorsC.name(),constconstructors (all fieldsfinal),factoryconstructors such asfromJson. - Getters and setters look like fields but run code;
_nameis private to the file. extends: single inheritance (one superclass),super,@override. One superclass avoids the diamond problem.- Abstract classes describe what subclasses must do and cannot be instantiated;
implementspromises an interface, many at once. - Mixins (
mixin,with,on,mixin class) add abilities from several places; the last mixin wins. - Extension methods add methods to existing types.
- نەخشەیە؛ لێی دروست دەکرێن و هەریەکەیان نرخی خۆی هەیە.
- :
this.x، بەrequired، ناودارC.name()،const(هەمووfinal)،factoryوەکfromJson. - و وەک دەردەکەون بەڵام کۆد جێبەجێ دەکەن؛
_nameتایبەتە بە . extends: لە یەک (یەک )،super،@override. یەک ڕێگری لە کێشەی ئەڵماس دەکات.- ئەوە وەسف دەکەن کە دەبێت بیکەن و لێ دروست ناکرێت؛
implementsبەڵێنی دەدات، چەندین دانە پێکەوە. - (
mixin،with،on،mixin class) لە چەند شوێنێکەوە توانا زیاد دەکەن؛ دوایین دەیباتەوە. - بۆ جۆرە هەبووەکان زیاد دەکەن.
Why can a Dart class not write extends A, B?بۆچی کلاسێکی Dart ناتوانێت extends A, B بنووسێت؟
Dart has single inheritance: one superclass keeps things simple and avoids the diamond problem. Use mixins or interfaces for the rest.
لە یەک هەیە: یەک شتەکان سادە دەهێڵێتەوە و ڕێگری لە کێشەی ئەڵماس دەکات. بۆ ئەوانی تر یان بەکار بهێنە.
Why do Flutter widgets have const constructors?بۆچی ویجێتەکانی Flutter دروستکەری constـیان هەیە؟
Widgets are immutable. A const widget is built once and reused, so rebuilding the screen costs less.
. const یەک جار دروست دەکرێت و دووبارە بەکار دێتەوە، بۆیە دووبارە دروستکردنەوەی شاشە کەمتر تێدەچێت.
What is the difference between a mixin and a superclass?جیاوازیی نێوان میکسین و کلاسی باوک چییە؟
A class has exactly one superclass (extends) but can add many mixins (with). A mixin cannot have a constructor and is applied in order.
ڕێک یەک هەیە (extends) بەڵام دەتوانێت چەندین زیاد بکات (with). ناتوانێت هەبێت و بە ڕیزبەندی جێبەجێ دەکرێت.
Lesson complete!وانەکە تەواو بوو!
Well done. Review the key terms, then go on to the next lesson.دەستخۆش. سەیرێکی زاراوە سەرەکییەکان بکەرەوە، پاشان بڕۆ بۆ وانەی داهاتوو.
Key termsزاراوە سەرەکییەکان
Futures, async and await in DartFuture، async و await لە Dartـدا
Related lecturesوانە پەیوەندیدارەکان
References and further readingسەرچاوەکان و خوێندنەوەی زیاتر
This lecture is a first edition. The Kurdish text and terminology are waiting for review by Kurdish IT teachers.ئەم وانەیە چاپی یەکەمە. دەقە کوردییەکە و زاراوەکانی چاوەڕێی پێداچوونەوەی مامۆستایانی کوردی بواری IT ن.