08 | 综合案例:掌握Dart核心特性
08 | 综合案例:掌握Dart核心特性
讲述:陈航
时长10:45大小9.85M
案例介绍
类抽象改造
方法改造
对象初始化方式的优化
总结
思考题
赞 17
提建议
精选留言(67)
- relax置顶2019-08-14能不能所有的示例代码放到一个git下面
作者回复: 代码还是要分开放的,因为每节分享都是独立的一个可运行工程,不只是代码,还有CI和单测一堆工程相关的东西,集中放就没法管理了。 我单起了一个仓库,用submodule的方式把这些demo都收进去了,可以自取 https://github.com/cyndibaby905/flutter_core_demo
共 3 条评论4 - Ω2019-07-16Item operator+(Item item) => I... double get price => bookings... 这个改造+号的代码还是无法看懂
作者回复: operator+:把两个Item对象合并为一个。新Item对象的name为这两个对象的name拼接而成,price为他们的price相加而成。 get price:对列表数据采用累加的方式进行求和。这里用到了reduce方法。reduce是函数迭代方法,需要传递一个二元函数进行列表的合并工作。list[0...n].reduce(f)等于: a0 = list[0] a1 = f(a0,list[1]) a2 = f(a1,list[2]) an = f(an-1,list[n]) 在这里我们的f是求和函数f(x,y)=x+y,可以理解成an=list[0]+list[1]+list[n-1]+list[n]
共 2 条评论33 - bytecode2019-07-16double get price() { double sum = 0.0; for(var i in bookings) { sum += i.price; } return sum; } 文中这里的price()是多了括号(),要去掉()展开
作者回复: 感谢提醒
13 - jia589602019-07-24大概能看懂并实现代码,但构造函数中的属性什么时候用this.属性,什么时候不用this,希望老师能回答下。
作者回复: 类的实例变量:1.是声明时定义的,可以用this语法糖赋值;2.是继承来的,不能用this,需要把这个值交给super让父类赋值
共 2 条评论10 - Paradise2019-07-16这种结合代码的方式很友好,可以一边听一边上手,更容易理解...😀6
- 灰灰2019-07-27abstract class PrintHelper { printInfo() => print(getInfo()); getInfo(); } class Meta { double price; String name; Meta(this.name, this.price); } // 定义商品Item类 class Item extends Meta { int count; Item(name, price, this.count): super(name, price); Item operator+(Item item) => Item(name + item.name, price * count + (item.price * item.count), 1); } //定义购物车类 class ShoppingCart extends Meta with PrintHelper { DateTime date; String code; List<Item> bookings; double get price => bookings.reduce((value, element) => (value + element)).price; // ShoppingCart(name, this.code): date = DateTime.now(), super(name,0); ShoppingCart({name}): this.withCode(name: name, code: null); ShoppingCart.withCode({name, this.code}): date = DateTime.now(), super(name, 0); getInfo () => ''' 购物车信息: ---------------- 商品名 单价 数量 总价 ---------------- ${bookings.map((item) => '${item.name} ${item.price} ${item.count} ${item.price * item.count}').join('\n ')} ================ 用户名: $name 优惠码: ${code ?? "没有"} 总价: $price 日期: $date '''; } void main() { ShoppingCart.withCode(name: '张三', code: '123456') ..bookings = [Item('苹果', 10.0, 3), Item('鸭梨', 20.0, 1)] ..printInfo(); ShoppingCart(name: '李四') ..bookings = [Item('香蕉', 2.4, 2), Item('芒果', 6.8, 4)] ..printInfo(); }展开
作者回复: 赞
共 2 条评论4 - Uncle.Wang2019-08-20class Meta { double price; String name; // 成员变量初始化语法糖 Meta(this.name, this.price); } abstract class PrintHelper { printInfo() => print(getInfo()); getInfo(); } class Item extends Meta with PrintHelper { int count; Item(name, price, {int count = 1}): super(name, price) { this.count = count; } // 重载 + 运算符,将商品对象合并为套餐商品 Item operator+(Item item) => Item(name + item.name, price + item.price); @override getInfo() => ''' 商品名: $name 单价: $price 数量: $count --------------- '''; } //with 表示以非继承的方式复用了另一个类的成员变量及函数 class ShoppingCart extends Meta with PrintHelper{ DateTime date; String code; List<Item> bookings; // 以归纳合并方式求和 double get price => bookings.reduce((value, element) => value + element).price; // 默认初始化函数,转发至 withCode 函数 ShoppingCart({name}) : this.withCode(name:name, code:null); //withCode 初始化方法,使用语法糖和初始化列表进行赋值,并调用父类初始化方法 ShoppingCart.withCode({name, this.code}) : date = DateTime.now(), super(name,0); getBookingInfo() { String str = ""; for (Item item in bookings) { str += item.getInfo(); } return str; } //?? 运算符表示为 code 不为 null,则用原值,否则使用默认值 " 没有 " @override getInfo() => ''' 购物车信息: ----------------------------- 用户名: $name 优惠码: ${code??" 没有 "} 总价: $price Date: $date 商品列表: --------------- ${ getBookingInfo() } ----------------------------- '''; } void main() { ShoppingCart.withCode(name:'张三', code:'123456') ..bookings = [Item('苹果',10.0, count: 10), Item('鸭梨',20.0, count: 5)] ..printInfo(); ShoppingCart(name:'李四') ..bookings = [Item('香蕉',15.0), Item('西瓜',40.0)] ..printInfo(); }展开
作者回复: 非常棒!
3 - 江宁彭于晏2019-07-19class Meta { double price; String name; // 成员变量初始化语法糖 Meta(this.name, this.price); } class Item extends Meta{ Item(name, price) : super(name, price); // 重载 + 运算符,将商品对象合并为套餐商品 Item operator+(Item item) => Item(name + item.name, price + item.price); } class Items { Item item; double num; Items(this.item, this.num); double get totalPrice => item.price * num; } abstract class PrintHelper { printInfo() => print(getInfo()); getInfo(); } //with 表示以非继承的方式复用了另一个类的成员变量及函数 class ShoppingCart extends Meta with PrintHelper{ DateTime date; String code; List<Items> bookings; // 以归纳合并方式求和 double get shopPrice { double result = 0.0; bookings.forEach((element) => result+=element.totalPrice); return result; } // 默认初始化函数,转发至 withCode 函数 ShoppingCart({name}) : this.withCode(name:name, code:null); //withCode 初始化方法,使用语法糖和初始化列表进行赋值,并调用父类初始化方法 ShoppingCart.withCode({name, this.code}) : date = DateTime.now(), super(name,0); //?? 运算符表示为 code 不为 null,则用原值,否则使用默认值 " 没有 " @override String getInfo() { String bookingsResult = '商品明细: \n'; bookings.forEach((item) => bookingsResult += ' 商品名称:${item.item.name} 单价:${item.item.price} 数量 :${item.num} 总价:${item.totalPrice}\n'); return ''' 购物车信息: ----------------------------- 用户名: $name 优惠码: ${code??" 没有 "} $bookingsResult 总价: $shopPrice Date: $date ----------------------------- '''; } } void main() { ShoppingCart.withCode(name:'张三', code:'123456') ..bookings = [Items(Item('苹果',10.0),5.0), Items(Item('鸭梨',20.0),10.0)] ..printInfo(); ShoppingCart(name:'李四') ..bookings = [Items(Item('香蕉',15.0),10.0), Items(Item('西瓜',40.0),1.0)] ..printInfo(); }展开
作者回复: 赞👍 不过数量作为Item的属性会更好一点。
3 - 于小鱼2021-09-25Dart 2.12 之后 Enabling null safety , 文中的例子就有了问题。 booking 也需要 Initialize String code 需改为 String? code共 1 条评论2
- gk2021-06-1019年的课,才看,忍不住回复下,主要是太妙了,作者的课程安排很好,另外这堂课的例子,从重载运算符,reduce妙用,级联运算符,一个比一个精彩,给个赞。共 1 条评论1
- Carlo2019-10-15看到一段代码: firebaseService.login().then( (value) { print(value.toJson()); }, onError: (err) { print(err); }, ); 请问这个onError是怎么回事啊。为什么会被执行呢? 这是dart特有的语法么? 我所知道的一般sync function的语法是 thisFunction() .catch(console.error) .then(() => console.log('We do cleanup here'));展开
作者回复: 给你展开一下你就明白了: funcThatThrows() .then(successCallback, onError: (e) { handleError(e); // Original error. anotherFuncThatThrows(); // new error. }) .catchError(handleError); // Error from within then() handled.
1 - 和小胖2019-08-14老师您的第二个题目,我理解是要做每一种商品的分类,但是我还是用了以前语言的思路来做了。麻烦老师,看看是否正确。 关键代码如下: //定义购物车类 class ShoppingCar extends Meta with PrintHelper { DateTime date; //购物日期 String code; //优惠券 List<Item> _bookings; //定义私有属性 num count; //商品数量 //求出总价 double get price => books.reduce((value, element) => value + element).price; List<Item> get books => _bookings; //给bookings定义set方法 set book(List<Item> bookings) { this._bookings = bookings; this.count = bookings.length; } //获取分类产品信息 String getGoodsInfo() { StringBuffer temp = new StringBuffer(); Map map = new Map<String, List<Item>>(); books.forEach((item) { if (!map.containsKey(item.name)) { List list = new List<Item>(); list.add(item); map[item.name] = list; } else { (map[item.name] as List<Item>).add(item); } }); map.forEach((k, v) { temp.write("商品名称:$k,该种商品数量:${(v as List).length},该种商品单价:${(v as List<Item>)[0].price}元\n"); print("$k,$v"); }); return temp.toString(); } //这种表达式赋值还是挺方便的 ShoppingCar.withCode({name, this.code}): this.date = DateTime.now(),super(name, 0.0); ShoppingCar({name}) : this.withCode(name: name, code: null); @override getInfo() { return ''' 购物车信息: ---------------------- 用户名:$name 优惠码:${code ?? "没有优惠券啊"} 商品总量:$count 总价:$price 日期:$date ${getGoodsInfo()} ---------------------- '''; } } 运行后信息如下:购物车信息: ---------------------- 用户名:小李 优惠码:没有优惠券啊 商品总量:3 总价:29.0 日期:2019-08-14 22:01:24.437085 商品名称:苹果,该种商品数量:2,该种商品单价:10.0元 商品名称:梨,该种商品数量:1,该种商品单价:9.0元 ----------------------展开
作者回复: 结果倒是对,但是这个购物车与我们理解的购物车还是有差异: 1.count属性应该是Item对象的:一个Item对象有count个,而不是一直往购物车内加同样的对象count次; 2.由于你的count属性无法拆分到Item类,导致getGoodsInfo的计算异常繁琐了。如果count属性在Item类,getGoodsInfo计算可以收敛到Item对象类内部。
1 - 刘荣清2019-08-03在vs code已经安装dart、code runner插件,本地也安装完dart SDK,然后通过vs code运行dart 提示:dart : 无法将“dart”项识别为 cmdlet、函数... 但在cmd 控制板中就可以正常运行,这是为咋啊,vs code需要额外配置咋吗
作者回复: 把dart命令所在的目录设置成环境变量PATH
1 - 黄金分割2022-12-03 来自广东老师的dart 比较旧了. 如果大家使用了2.12以上的dart, 引入了新特性null safety, 会报错 argument_type_not_assignable. ShoppingCart里的code需要这样声明才行. String? code;
- 利姆露·坦派斯特2022-09-11 来自美国因为dart的null安全,现在要正常执行上面的代码的话。需要在ShoppingCart中对code属性以及bookings的那个属性做一些声明上的更改。使其空值安全才能通过编译。建议各位尝试 ? 跟 late 这两种方式使其空值安全。
- 土豆土豆泥2022-05-08干货满满
- 兔斯基2022-05-01新版本可控字段需要标识(Dart 2.10.5) String? code; 否则会编译不通过
- 杰瑞2021-10-13class Meta{ String name; double price; Meta(this.name,this.price); } abstract class PrintHelper{ printInfo() => print(getPrintInfo()); String getPrintInfo(); } //定义商品Item类 class Item extends Meta with PrintHelper{ int count; Item({name, price}) : this.withCount(name:name,price:price,count:1); Item.withCount({name, price, this.count}):super(name,price); Item operator+(Item item) => Item(name:name+item.name, price:price*count+item.price*item.count); @override String getPrintInfo(){ return '\t $name \t\t $price \t $count \t ${price*count}'; } } //定义购物车类 class ShoppingCart extends Meta with PrintHelper{ DateTime date; String code; List<Item> bookings; ShoppingCart({String name}):this.withCode(name:name, code:null); ShoppingCart.withCode({String name, this.code}):date = DateTime.now(),super(name,0); double get price => bookings.reduce((value,element) => value + element).price; @override String getPrintInfo(){ String itemDetailPrintInfo = ''; bookings.forEach((item)=>{ itemDetailPrintInfo = itemDetailPrintInfo+item.getPrintInfo() + '\n' }); return ''' 购物车信息: ----------------------------- 用户名:$name 优惠码:${code??"无"} 总价: $price 日期: $date ----------------------------- 商品详情: ----------------------------- 商品名 \t 单价 \t 数量 \t 总价 $itemDetailPrintInfo ----------------------------- '''; } } void main(){ ShoppingCart(name:'张三') ..bookings = [Item(name:'苹果',price:10.0), Item.withCount(name:'鸭梨',price:50.0,count:3)] ..printInfo(); ShoppingCart.withCode(name:'李四',code:'123456') ..bookings = [Item.withCount(name:'香蕉',price:15.0,count:2), Item(name:'西瓜',price:40.0)] ..printInfo(); }展开
- 董鹏宇2021-07-29PrintHelper 与 ShoppingCart的关系为什么是“混入“ 而不是组合呢?感觉 是has-a的关系而不是 is-a
- Dale2021-07-03a. 静态方法没有办法使用 this 关键字; b. 构造函数或普通的实例方法里面,this 指向当前操作的实例; c. 构造函数的 “:” 后面初始化那一部分,this 指向当前类。 -------------------------- 不知道这个理解对不对?