http://www.javacodegeeks.com/2014/04/groovy-2-3-introduces-traits.htmlhtml
前几天,Groovy 2.3的第二个beta版本发布。Groovy 2.3最重要的新特性之一是trait语法。trait是一组可重用的方法和字段,能够将它们混入到一个或多个类中。一个类能够同时拥有多个trait而不须要使用多重继承(从而避免钻石问题)。java
在Groovy 2.3中,这样定义一个基本的trait:app
trait SwimmingAbility { def swim() { println "swimming.." } }
trait的定义与类的定义很是类似。SwimmingAbility trait只定义了一个swim()方法。接下来就可使用implements关键字来向类中加入这个trait:学习
class Goldfish implements SwimmingAbility { .. }
如今,咱们就能够调用Goldfish对象的swim()方法了。this
def goldfish = new Goldfish() goldfish.swim()
到这里,咱们已经实现了与继承一样的功能。不一样的是,咱们能够添加多个trait到同一个类中。下面,咱们定义其它的trait:code
trait FlyingAbility { def fly() { println "flying.." } }
再建立一个新的类,同时使用这些trait:htm
class Duck implements SwimmingAbility, FlyingAbility { .. }
如今鸭子能够游动和飞了:对象
def duck = new Duck() duck.swim() duck.fly()
trait中的this关键字表明了trait的实现的实例,因此,你能够这样写:继承
trait FlyingAbility { def fly() { println "${this.class.name} is flying.." } }
若是调用duck.fly()
,将会打印:ip
Duck is flying..
下面的例子将展现trait的更多特性
trait Trader { int availableMoney = 0 private int tradesDone = 0 def buy(Item item) { if (item.price <= availableMoney) { availableMoney -= item.price tradesDone += 1 println "${getName()} bought ${item.name}" } } def sell(Item item) { .. } abstract String getName() }
就像Groovy类,trait也支持属性。本例中,availableMoney
属性将变成私有的,同时相应的setter和getter方法会被自动生成。在实现中能够访问这些方法。但没法在Trader之外访问tradesDone
私有变量。咱们还定义了一抽象方法getName(),实现类必须实现它。
如今就建立一个实现Trader的类:
class Merchant implements Trader { String name String getName() { return this.name } }
如今Merchant就能够购买东西了:
def bike = new Item(name: 'big red bike', price: 750) def paul = new Merchant(name: 'paul') paul.availableMoney = 2000 paul.buy(bike) // prints "paul bought big red bike" println paul.availableMoney // 1250
trait使用extends关键字实现继承:
trait Dealer { def getProfit() { ... } def deal() { ... } } trait CarDealer extends Dealer { def deal() { ... } }
在这里,CarDealer继承了Dealer,同时覆盖了Dealer的deal()方法。
trait的方法也能够被实现类覆盖:
class OnlineCarDealer implements CarDealer { def deal() { ... } }
如是一个类同时实现了多个trait,就颇有可能产生冲突。由于超过一个trait使用了相同的签名:
trait Car { def drive() { ... } } trait Bike { def drive() { ... } } class DrivingThing implements Car, Bike { ... }
在这种状况下,只有后一个trait定义生效。(本例中Bike生效)。
trait是一个很是有用的概念,很开心在Groovy中看到它。Groovy混合trait是在编译期,所以,Java能够调用trait(Other than Groovy mixins traits work at compile time and can therefore be accessed from Java code)。进一步学习,我推荐Groovy 2.3的Trait 文档。