2016-12-28 3 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 

Класс «Bill» должен содержать список, который может включать в себя напитки, а также LotteryTickets, для которых общее количество можно рассчитывать и клиент должен быть в состоянии сделать такой счет. Класс Customer также нуждается в методе, который подтверждает покупку и проверяет, отличаются ли номера в его LottoryTicket для каждого купленного им Билета. Потому что, когда у него одинаковое количество на 2 билета, подтверждение не получается. Кроме того, в будущем можно добавлять новые продукты (например, например, пищу), без изменения основного кода.

+0

Вы всегда можете создать «Список [Любой]», но я бы попытался структурировать ваш код, чтобы у вас либо был список для каждого типа, либо чтобы элементы в списке наследовались от того же суперкласса (что-то вроде ' Список [T <: CommonSuperClass] ') –

+0

Вы имеете в виду как суперкласс« Item », который распространяется на Drink and Ticket? –

+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

Ow нет, я вижу, это для проверки чисел. Но проблема заключается в том, что эта проверка должна быть выполнена в отдельном методе в конце, и единственный способ, который я могу сделать для этого, - сделать дополнительный 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

Ой, да, это хорошая идея, спасибо! И спасибо за отзыв о ценах. –

 Смежные вопросы

  • Нет связанных вопросов^_^