您可以访问未在超类中声明的子类的字段吗?

时间:2016-12-28 14:33:05

标签: scala inheritance

所以我有一个absract超类,以及一个子类,它使用未在超类中声明的字段来扩展这个超类。有没有办法从超类中访问这些字段?我不能在超类中声明这些字段,因为它有其他可能没有这些字段的子句。

  

修改以便更清楚:

所以我正在制作一些有不同商品的商店。因此,我有一个名为item的抽象类(带有字段:price),不同的项是扩展项类的对象,定义价格。但也有一些特殊项目,其中同一项目的所有实例都有不同的ID,他们也声明了他们的价格。并且“购物者”必须能够制作正常和特殊物品的“购物清单”,其中可以计算总价格,但您还必须能够从列表中查看特殊物品的ID。 / p>

  

编辑:我想要实现的一个例子。

我做了一个小例子

//The numbers are different for each ticket
// and are used to denote a winner in the end.
abstract class LotteryTicket(val numbers: String) {
  val price: Int
}

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

班级“比尔”应该包含一个列表,其中可以包括饮品和彩票票,  可以计算总额并且客户必须能够制作这样的账单。 Customer类还需要一种方法来确认购买并检查其上的数字 LottoryTicket对于他购买的每张门票都不同。因为他在2张票上有相同的号码 确认失败。

3 个答案:

答案 0 :(得分:2)

虽然确实不推荐(因为它暗示了一个设计缺陷 - 你不知道你是否有子类,但你仍然对调用它的方法感兴趣),这里有一些选择:

trait A {
  // pattern-match to doStuff only if B:
  this match {
    case b: B => b.doStuff()
    case _ => // do nothing
  }

  // check if type is B (not recommended)
  if (this.isInstanceOf[B]) {
    this.asInstanceOf[B].doStuff()
  }
}

class B extends A {
  def doStuff() {}
}

答案 1 :(得分:1)

一般来说,这在面向对象编程原理中是不可用的。可能是如果你必须过代码使另一个特殊价格抽象字段来解决。除此之外,您必须在基类中实例化子类,以便使子类中的字段可访问。我不知道这是否会对你有所帮助,但是如果你可以发布你的课程的某种结构以及你想要做什么。我认为这会有很大的帮助。

答案 2 :(得分:0)

我强烈建议不要采用非常肮脏的技巧。看起来你的类层次结构可能有一些问题 - 没有具体的例子很难给出确切的建议,但我想Scala主要看的是具有特征而不是继承的组合。对于您的问题,您可以为可以放入购物车的所有内容制作特征

trait Buyable {
  def price: Int
}

然后将该特征混合到您希望能够在购物车中着陆的任何内容中。通过这种方式,您可以构建各种产品的小型继承树,并添加特征。例如

class Drink extends Buyable {
  // Drink can set the price for all its subclasses
  override def price = ...
}

abstract class LotteryTicket extends Buyable {
  // LotteryTicket cannot, so it's abstract
}
class SilverTicket {
  override def price = 20
}

您的购物车没有任何意义,只是对可购买的东西进行操作:

class ShoppingCart {
  def add(b: Buyable) ...
}

当然,您也可以将一些标识符等等移动到Buyable,就像您需要它一样。