2016-12-28 5 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を含むことができ、リストを含める必要がありますそのような法案を作ることができる。また、Customerクラスでは、購入を確認し、購入したTicketごとにLottoryTicketの番号が異なるかどうかを確認するメソッドが必要です。彼が2枚のチケットで同じ番号を持っているので、確認は失敗します。それは、簡単な方法で(コアコードを変更することなく)将来的に新しい食品(食品など)を追加することが可能でなければなりません。

+0

あなたはいつも 'List [Any]'を作ることができますが、あなたはそれぞれの型のリストを持つか、リスト内の項目を同じスーパークラスから継承するようにコードを構造化しようとします( 'リスト[T <:CommonSuperClass] ') –

+0

飲み物とチケットで延長されるスーパークラスの「アイテム」のような意味ですか? –

+0

もちろん、「アイテム」から継承することが理にかなっている限り、リストがどのように使われるか、 '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

ありがとうございました! (私は完全にケースクラスについて忘れてしまった、私はscalaを新しくしています) –

+0

オーバーロードの代わりに上限を持つ型変数を使用する方が良いでしょうか? –

+0

いいえ、わかりました、数字の検証用です。しかし問題は、このバリデーションが最後に別の方法で行われなければならないという事実です。これを行うために私が考えることができる唯一の方法は、すべてのチケットを2回目に保持する余分なList [LotteryTicket] 。 'numbers'の値にアクセスする必要があるからです。 –

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 
} 

そして価格が、BigDecimalのためのIntを使用しないでください。

+0

ええ、それは良いアイデアです、ありがとう!そして、価格についてのヒントをありがとう。 –

関連する問題