【问题标题】:Can you access fields of a subclass which are not declared in the superclass?您可以访问未在超类中声明的子类的字段吗?
【发布时间】:2017-05-12 20:37:41
【问题描述】:

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

编辑以使其更清晰:

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

编辑:我想要实现的示例。

我做了一个小例子

//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

“Bill”类应该包含一个列表,其中可以包括饮料和彩票, 可以计算总额,并且客户必须能够开出这样的账单。 Customer 类还需要一个方法来确认购买并检查他的号码是否 他购买的每张彩票都不同。因为当他在两张票上有相同的号码时 确认失败。

【问题讨论】:

    标签: scala inheritance


    【解决方案1】:

    如果不使用非常肮脏的技巧,我强烈建议不要这样做。看起来你的类层次结构可能有一些问题——没有具体的例子,很难给出准确的建议,但我在 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,就像您需要它一样。

    【讨论】:

    • 嗯,我正在做一些有不同物品的商店。所以我有一个名为 item 的类(带有一个字段:price),不同的项目是对象,因为它们只有一个价格,没有别的。但也有一些特殊的项目,其中项目的每个实例都有不同的 id。并且“购物者”必须能够制作包含普通商品和特殊商品的“购物清单”,其中可以计算总价,但您还必须能够从清单中查看特殊商品的 ID。
    【解决方案2】:

    一般来说,这在面向对象编程的原则中是不可用的。可能是如果您必须编写另一个特殊的价格抽象字段来解决问题。除此之外,您必须实例化基类中的子类以使子类中的字段可访问。我不知道这是否会对您有所帮助,但您是否可以发布您的课程的某种结构以及您正在尝试做的事情。我认为这将有很大帮助。

    【讨论】:

    • 我会添加一个例子
    【解决方案3】:

    虽然确实不推荐(因为它意味着设计缺陷 - 你不知道手头是否有子类,但你仍然有兴趣调用它的方法),但这里有一些选项:

    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() {}
    }
    

    【讨论】:

    • 那么,在特征 A 中,您究竟在哪里访问 B 的字段? (请不要尝试)
    • 哎呀 - 误读了问题 - 虽然仍然有可能......更新
    • 好吧,所以我想要实现的并不好,所以我写了一个我真正想做的例子。这可能是一种简单的方法吗?
    猜你喜欢
    • 2016-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 2013-06-15
    • 1970-01-01
    • 2018-07-03
    • 2013-05-27
    相关资源
    最近更新 更多