【问题标题】:Java inheritance... I think. Maybe notJava继承......我认为。也许不吧
【发布时间】:2012-02-24 00:48:54
【问题描述】:

我需要收集几个不同的类。在我看来,子类继承自更通用的超类。所以我有 SuperClass 类,它当前有一个 Object 类型的成员变量 o,它将采用子类 SubClassA 和 SubClassB 之一的单个实例。 SubClassA 和 SubClassB 有一些共同点,例如需要创建数据库表来保存它们自己的描述。因此,每个子类都需要有一个方法 CreateDatabaseTables()。目前我有一个 SuperClass 实例的集合,每个实例都包含一个 Object o,它可以是我在编译时不知道的几个类之一。也许这不是最好的方法......

我的问题是,当我遍历集合时,我可以调用类似的东西

for (int i = 0; i < superClassArray.size; i++)
{
  superClassInstance[i].o.CreateDatabaseTables();
}

不必将 Object o 转换为子类之一?

还是我把整个事情搞砸了,我只是做错了?这个概念叫做继承,还是别的什么?我不认为这是继承,因为我不打算在 SuperClass 中编写 CreateDatabaseTables() 方法。每个类都必须有自己的方法。

【问题讨论】:

  • 一个超类应该对它的子类有no依赖。您的设计已损坏,应该修复。我怀疑您过于依赖继承来解决不需要继承来解决的问题,而应该通过组合来解决。

标签: java inheritance


【解决方案1】:

您使用的不是继承,而是组合。

您的基类中不需要成员:

abstract class SuperClass
{
    public abstract void CreateDatabaseTables();
}

class SubClassA extends SuperClass
{
    public void CreateDatabaseTables() { /*do whatever*/ }
}
class SubClassB extends SuperClass
{
    public void CreateDatabaseTables() { /*do whatever else*/ }
}

然后简单地调用基类上的覆盖方法:

// Collection<SuperClass> superClassInstance;
// you can populate superClassInstance with objects of type
// SubClassA or SubClassB
for (int i = 0; i < superClassInstance.length; i++)
{
    superClassInstance[i].CreateDatabaseTables();
}

【讨论】:

  • 完美!谢谢,@Luchian。我已经可以说这会好得多。
  • @Luchian - 我试图编辑这篇文章以更正几个 Java 语法错误,但我被拒绝了(看图)。 1.如果类中有抽象方法,则需要将整个类标记为抽象。 2. 在 for 循环中,你有“i
  • @LuchianGrigore,如何将子类成员添加到集合中?我有 ArrayList superClassList;看来我不能使用 superClassList.add(new SubClassA());因为 ArrayList 正在寻找 SuperClass 对象。
  • @MrGibbage 就是这样,SubClassA() 是一个 SuperClass。它应该工作。你确定你是使用extendsSuperClass派生的吗?
  • 哎呀。我已经扩展了 SubClassA 和 SubClassB,但开始使用我没有扩展的“SubClassC”进行测试。我早该知道。现在效果很好!
【解决方案2】:

您需要将CreateDatabaseTables 定义为SuperClass 中的抽象方法,并将o 定义为不是Object,而是SuperClass

但是,我觉得您对 o 成员变量做错了 - 当超类需要子类作为成员时,这种情况并不常见。

【讨论】:

  • 为什么CreateDatabaseTables必须定义为抽象的?
  • 因为SuperClass本身并没有这个方法的实现。
【解决方案3】:

就我个人而言,我会使用接口而不是继承

http://docs.oracle.com/javase/tutorial/java/concepts/interface.html

【讨论】:

  • 你不是说as well as inheritance 没有继承的接口不是很有用。 ;)
【解决方案4】:

您可以拥有一个接口,该接口具有您使用的方法createDatabaseTables() 而不是 Object。更好的是让你的对象有这个方法,而不是直接访问该字段。

【讨论】:

    【解决方案5】:

    如果您从不实例化超类,则将其抽象化,

    public abstract class MySuperClass {
        public abstract void createDatabaseTables();
    }
    
    public class Child extends MySuperClass {
           public abstract void createDatabaseTables(){
                  //bleh
           }
    }
    

    然后所有实施者将自己实施它,您将可以在您的情况下访问它。

    【讨论】:

      【解决方案6】:

      关于...

      我的问题是,当我遍历集合时,我能够 调用类似的东西

      for (int i = 0; i < superClassArray.size; i++) {  
         superClassInstance[i].o.CreateDatabaseTables(); 
      } 
      

      不必将 Object o 转换为子类之一?

      您必须对该对象进行强制转换才能识别子类。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-02
        • 2013-05-29
        • 2012-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-08
        • 1970-01-01
        相关资源
        最近更新 更多