案例介绍
一个有着基本功能的购物车程序长什么样子:
//定义商品Item类class Item {double price;String name;Item(name, price) {this.name = name;this.price = price;}}//定义购物车类class ShoppingCart {String name;DateTime date;String code;List<Item> bookings;price() {double sum = 0.0;for(var i in bookings) {sum += i.price;}return sum;}ShoppingCart(name, code) {this.name = name;this.code = code;this.date = DateTime.now();}getInfo() {return '购物车信息:' +'\n-----------------------------' +'\n用户名: ' + name+'\n优惠码: ' + code +'\n总价: ' + price().toString() +'\n日期: ' + date.toString() +'\n-----------------------------';}}void main() {ShoppingCart sc = ShoppingCart('张三', '123456');sc.bookings = [Item('苹果',10.0), Item('鸭梨',20.0)];print(sc.getInfo());}
类抽象改造
class Item {double price;String name;Item(this.name, this.price);}class ShoppingCart {String name;DateTime date;String code;List<Item> bookings;price() {...}//删掉了构造函数函数体ShoppingCart(this.name, this.code) : date = DateTime.now();...}
抽象 name, price:
class Meta {double price;String name;Meta(this.name, this.price);}class Item extends Meta{Item(name, price) : super(name, price);}class ShoppingCart extends Meta{DateTime date;String code;List<Item> bookings;double get price {...}ShoppingCart(name, this.code) : date = DateTime.now(),super(name,0);getInfo() {...}}
方法改造
我们先看看 price 属性的 get 方法:
double get price {double sum = 0.0;for(var i in bookings) {sum += i.price;}return sum;}
使用 Dart 的箭头函数来进一步简化实现函数:
class Item extends Meta{...//重载了+运算符,合并商品为套餐商品Item operator+(Item item) => Item(name + item.name, price + item.price);}class ShoppingCart extends Meta{...//把迭代求和改写为归纳合并double get price => bookings.reduce((value, element) => value + element).price;...getInfo() {...}}
getInfo 方法如何优化:
getInfo () => '''购物车信息:-----------------------------用户名: $name优惠码: $code总价: $priceDate: $date-----------------------------''';
对象初始化方式的优化
class ShoppingCart extends Meta{...//默认初始化方法,转发到withCode里ShoppingCart({name}) : this.withCode(name:name, code:null);//withCode初始化方法,使用语法糖和初始化列表进行赋值,并调用父类初始化方法ShoppingCart.withCode({name, this.code}) : date = DateTime.now(), super(name,0);//??运算符表示为code不为null,则用原值,否则使用默认值"没有"getInfo () => '''购物车信息:-----------------------------用户名: $name优惠码: ${code??"没有"}总价: $priceDate: $date-----------------------------''';}void main() {ShoppingCart sc = ShoppingCart.withCode(name:'张三', code:'123456');sc.bookings = [Item('苹果',10.0), Item('鸭梨',20.0)];print(sc.getInfo());ShoppingCart sc2 = ShoppingCart(name:'李四');sc2.bookings = [Item('香蕉',15.0), Item('西瓜',40.0)];print(sc2.getInfo());}
增加 PrintHelper 类,并调整 ShoppingCart 的声明:
abstract class PrintHelper {printInfo() => print(getInfo());getInfo();}class ShoppingCart extends Meta with PrintHelper{...}
总结
class 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);}abstract class PrintHelper {printInfo() => print(getInfo());getInfo();}//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);//??运算符表示为code不为null,则用原值,否则使用默认值"没有"@overridegetInfo() => '''购物车信息:-----------------------------用户名: $name优惠码: ${code??"没有"}总价: $priceDate: $date-----------------------------''';}void main() {ShoppingCart.withCode(name:'张三', code:'123456')..bookings = [Item('苹果',10.0), Item('鸭梨',20.0)]..printInfo();ShoppingCart(name:'李四')..bookings = [Item('香蕉',15.0), Item('西瓜',40.0)]..printInfo();}
