So I made a post earlier about accessing a field of a subclass from within the superclass to solve a problem i have. But they made it clear that it is practically impossible. So I made a little example of what i want to achieve:
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
The class 'Bill' should contain a list which can include Drinks as well as LotteryTickets, for which the total can be calculated and the Customer has to be able to make such a bill. The Customer class also needs a method which confirms the purchase and checks if the numbers on his LottoryTicket are different for every Ticket he bought. Because when he has the same number on 2 tickets The confirmation fails. It alse must be possible to add new products in the future (like food for example) in an easy way (without changing the core code).
You want your "billable" items implement a trait, that exposes their common features.
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 _ =>
}
}