Groovy 2.3 trait語法介紹

Groovy 2.3 trait語法介紹

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中的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的擴展、覆蓋、解決衝突

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 文檔

相關文章
相關標籤/搜索