1. 程式人生 > >kotlin實現鴨子例子的設計模式(行為模式)

kotlin實現鴨子例子的設計模式(行為模式)

init 使用 win 必須 fun ray play 建立 arc

package com.duck

/**
* 一.
* 這樣做降低了程序的耦合度,但接口不具有實現方法,實現接口無法達到代碼的復用
* 關鍵字:耦合度,復用
*/
interface Flyable {
fun fly()
}

interface Quackable {
fun quack()
}

abstract class Duck {
fun swim() {
println("我會遊泳!")
}

abstract fun display()
}


//野鴨子:野鴨子不是抽象類,所以必須實現父類和接口所有的非抽象方法
class MallardDuck : Duck(), Flyable, Quackable {

override fun display() {
println("我的顏色是野鴨子顏色")
}

override fun fly() {
println("野鴨子在飛")
}

override fun quack() {
println("野鴨子在叫")
}

}

class RedheadDuck : Duck(), Flyable, Quackable {

override fun display() {
println("紅頭鴨的顏色")
}

override fun fly() {
println("紅頭鴨在飛")
}

override fun quack() {
println("紅頭鴨在叫")
}
}

class DisabledDuck : Duck(), Quackable {
override fun display() {
println("廢鴨的顏色")
}

override fun quack() {
println("廢鴨在叫")
}
}

/**

* 二.
* 1.1
* 解決一中的問題,strategy(策略模式)
* 設計原則:
* (1)找出應用中的相同之處,且不容易發生改變的部分,把它們抽象出來,讓子類繼承
* (2)找出可能變化的部分,把它們獨立出來;不要和那些不需要變化的代碼混在一起
*
* 為了分開”要變化和不要變化的部分“,可以建立兩組類(完全遠離Duck類)--<行為模式>
*/
interface FlyBehavior {
fun fly()
}

interface QuackBehavior {
fun quack()
}

class FlyWithWinngs : FlyBehavior {
override fun fly() {
println("有翅膀的鴨子會飛")
}
}

class FlyNoWay : FlyBehavior {
override fun fly() {
println("沒翅膀的鴨子不會飛")
}
}

class Quack : QuackBehavior {
override fun quack() {
println("鴨子呱呱叫")
}
}
class Squeak :QuackBehavior{
override fun quack() {
println("鴨子吱吱叫")
}
}
class MuteQuack :QuackBehavior{
override fun quack() {
println("安靜的鴨子")
}
}
/**二.

* 1.1 點評
* 這樣的設計,可以讓不同的飛行和叫的行為讓其它的對象復用,提高了代碼的復用
* 而我們繼續增加一些新的行為的時候,既不會影響到既有的行為類,也不會影響到使用”現有行為“的具體類
*/

/**
* 二.
* 1.2
* 設計Duck類,MallardDuck類

*/
abstract class Duck二() {
open lateinit var flyBehavior: FlyBehavior
open lateinit var quackBehaving: QuackBehavior
abstract fun display()
fun swim(){
println("所有的鴨子都會遊泳")
}

fun performFly(){
flyBehavior.fly()
}
fun performQuack() {
quackBehaving.quack()
}

}

class MallardDuck二: Duck二() {

override var flyBehavior: FlyBehavior=FlyWithWinngs()
override var quackBehaving: QuackBehavior=Quack()

override fun display() {
println("野鴨子的顏色")
}
}

fun main(args: Array<String>) {
var m = MallardDuck二()
var f = m.performFly()
var q = m.performQuack()
var d = m.display()
var s = m.swim()

"$f,$q,$d,$s"
}

/**

*二.
* 1.2 點評
* 動態代理。。。
* 這樣既可以飛,又可以展示自己的顏色
* 這樣的設計可以看到是把flyBehavior,quackBehavior的實例化卸載子類了。我們還可以動態決定
*
* 在構造方法中對屬性進行賦值與用屬性的setter賦值的區別:
* 構造方法中對屬性進行賦值:固定,不可變;
* 用屬性的setter賦值,可以在實例化對象後,動態的變化,比較靈活
* **/



相關總結:

1.
(1)普通類繼承抽象類時,必須實現其所有抽象方法;
(2)抽象類繼承抽象類時,可以不實現所有抽象方法;
(3)抽象類可以繼承普通類;
(4)普通類繼承抽象類時,可以不實現其抽象方法。
(5)普通類中不可以有抽象方法

2.kotlin中A類繼承B實現C,D的寫法:
class A :B(),C,D{

// override...

}

3.kotlin中,普通類繼承抽象類時
(1) 如果抽象類中的fly()方法用abstarct修飾,則不可以有方法體,且繼承它的類必須重寫fly()方法;
(2) 如果抽象類中的fly()方法為普通方法,但沒被open修飾,則子類不可以重寫fly()方法;
(3) 如果抽象類中的fly()方法為普通方法,且被open修飾,則子類可以重寫fly()方法。

kotlin實現鴨子例子的設計模式(行為模式)