2016-12-28 23 views
-1

因此,我之前曾發佈過一篇關於從超類內訪問子類的字段以解決我遇到的問題的文章。但是他們明確表示這實際上是不可能的。所以我做了什麼,我想實現一個小例子:將不同類型的項目放置在列表中,並且能夠映射它們

abstract class LotteryTicket(val numbers: String) { 

val price: Int 

} 

//The numbers are different for each ticket and are used to denote a winner in the end. 

class GoldTicket(numbers: String) extends LotteryTicket(person) { 

val price: Int = 10 

} 

class SilverTicket(numbers: String) extends LotteryTicket(person) { 

val price: Int = 5 

} 

abstract class Drink { 

val price: Int 

} 

object Water extends Drink { 

val price: Int = 1 

} 

object Coffee extends Drink { 

val price: Int = 2 

} 

class Bill 

class Customer 

類「法案」應該包含一個列表,它可以包括飲料以及LotteryTickets,對此總可以計算與客戶有能夠做出這樣的賬單。客戶類別還需要確認購買的方法,並檢查他的LottoryTicket上的號碼是否與他購買的每張售票不同。因爲當他在2張票上有相同的號碼時確認失敗。它也必須能夠以一種簡單的方式在未來添加新產品(例如食品)(無需更改核心代碼)。

+0

你總是可以創建一個'List [Any]',但我會嘗試構造你的代碼,這樣你就可以爲每個類型創建一個列表,或者讓列表中的項目從同一個超類繼承(類似'列表[T <:CommonSuperClass]') –

+0

你的意思是像一個通過Drink和Ticket擴展的超類'Item'嗎? –

+0

當然,只要從「Item」繼承它們是有意義的。考慮如何使用該列表,以及是否以類似的方式使用「Drink」和「Ticket」 –

回答

3

你希望你的「可結算」項目實現一個特徵,揭示它們的共同特徵。

trait Billable { 
     def price: Int 
    } 
    class LotteryTicket(val numbers: String, val price: Int) extends Billable 
    class GoldTicket(n: String) extends LotteryTicket(n, 10) 
    class SilverTockent(n: String) extends LotteryTicket(n, 5) 

    class Drink(val price: Int) extends Billable 
    object Water extends Drink(1) 
    object Coffee extends Drink(2) 

    case class Bill(val items: Seq[Billable]= Seq.empty) 
    { 
    def amount = items.map(_.price).sum 
    def add(b: Billable) = copy(b +: items) 
    } 

    case class Customer(bill: Bill = Bill()) { 
    def buy(ticket: LotteryTicket) = { 
     // validate numbers, whatever 
     Customer(bill.add(ticket)) 
    } 

    def buy(drink: Drink) = { 
     Customer(bill.add(drink) 
    } 

    def howMuch = bill.total 

    def validateAllTickets = bill.items.foreach { 
     case ticket: LotteryTicket => makeSureNumberIsGood(ticket.numbers) 
     case _ => 
    } 
    } 
+0

謝謝! (我完全忘記了case類,我是scala新手) –

+0

使用帶有上限而不是超載購買的類型變量會更好嗎? –

+0

不,我知道,它是爲了驗證數字。但問題在於這個驗證最終必須以單獨的方法完成,而我唯一能想到的方法就是創建一個額外的List [LotteryTicket],它將第二次保存所有的門票。因爲'數字'的價值必須被認同。 –

1

,對使用迪馬的類比爾級的解決方案:

class BillImplementation { 
    private var container = Seq[Billable]() 

    def addProduct(product: Billable) = container :+= product // this add the product element to the container Seq 

    def listOfAllBillableInThis = container 

    def totalSum = container.map(_.price).sum 

    def isThere2ticketsWithSameNumbers: Boolean = { 
    var containerOfTickets = Seq[LotteryTicket]() 
    for (p <- container) { 
     p match { 
     case lo: LotteryTicket => containerOfTickets = containerOfTickets :+ lo 
     case _ => 
     } 
    } 
    val numbersMap = containerOfTickets.map(_.n) 
    numbersMap.distinct.size != numbersMap.size 
    } 

    def empty: Unit = container = Nil 
} 

不要使用int的價格,但BigDecimal的。

+0

噢,這是個好主意,謝謝!並感謝關於價格的小費。 –

相關問題