2

我想扩展一个类,然后从已扩展的类的实例中复制值,所以我在我的新类中获取它的所有参数。如果这没有意义,我正在尝试做一个简单的例子:

public class MyTableModel extends DefaultTableModel {

    public MyTableModel(DefaultTableModel model){
        this = (MyTableModel) model; /* I realise this is invalid */
    }

    public newMethod(){
        // Some additional code
    }
}

这有可能实现吗?

4

3 回答 3

3

看起来您想要组合而不是继承。特别是,您似乎正在尝试使用装饰器模式。也就是说,您想要获取 的现有实例DefaultTableModel,并创建另一个DefaultTableModel将大多数方法转发给底层委托的实例,但可能会添加/修改/装饰一些功能。

您永远无法设置this = somethingElse;,但您可以拥有DefaultTableModel delegate, 并将大多数/所有请求转发到delegate,可能会根据需要添加/装饰一些方法。

也可以看看

  • Effective Java 第 2 版,第 16 条:优先组合优于继承

番石榴示例:ForwardingCollection

这种模式的一个例子ForwardingCollection来自 Guava

Ajava.util.Collection将其所有方法调用转发到另一个集合。子类应覆盖一个或多个方法,以根据装饰器模式根据需要修改后备集合的行为。

您可以查看源代码以了解此模式通常是如何实现的:

  @Override protected abstract Collection<E> delegate();

  public int size() {
    return delegate().size();
  }    
  public boolean isEmpty() {
    return delegate().isEmpty();
  }
  public boolean removeAll(Collection<?> collection) {
    return delegate().removeAll(collection);
  }
  // many more interface Collection methods implemented like above...

正如你所看到的,ForwardingCollection它所做的implements Collection只是将所有方法转发给它delegate()的另一个Collection。可以理解,这是相当重复和平凡的代码编写,但现在子类可以简单地extends ForwardingCollection只装饰他们想要装饰的东西。

于 2010-07-28T15:21:13.413 回答
1

您不能在 Java 中将this设置为任何内容,它仅用于表达式之类的表达式(this == someObject)或访问当前正在使用的对象的某些属性,例如(this.someProperty)在构造函数中或在构造函数中初始化当前对象。有关关键字的更多信息,请参见此处this

此代码可能会抛出一个java.lang.ClassCastException

那是MyTableModelaDefaultTableModelDefaultTableModel不是 a MyTableModel。有关java 中类型转换的更多详细信息,请参阅http://java.sun.com/docs/books/jls/third_edition/html/conversions.html

如果您希望在子类中从父类重用某些状态和/或行为,则应考虑将这些成员标记为protected,或考虑其他形式的组合。

于 2010-07-28T15:30:29.500 回答
0

更好的方法是创建超类的字段protected而不是private- 这将使您可以在子类中访问它们。

请注意,当您定义子类构造函数时,您还需要从超类调用构造函数,因此在这方面您仍然可以传递所有必需的变量。

并且不要忘记,超类中的所有公共方法都可以被具有子类实例的任何代码原样调用。

编辑:一个小例子可能会有所帮助:

public class DefaultTableModel
{
    protected String modelName;
    protected int numberOfTables;
    private numTimesReinited = 0;

    public DefaultTableModel(String name, int numTabs)
    {
        modelName = name;
        numberOfTables = numTabs;
    }

    public void reinit()
    {
        numTimesReinited++;
        // Other stuff
    }

    protected int getNumberOfReinits()
    {
        return numTimesReinited;
    }

    public String getName()
    { 
        return name;
    }
}

 

public class MyTableModel extends DefaultTableModel
{
    private String modelType;

    public MyTableModel(String name, int numTables, String modelType)
    { 
        super(name, numTables); // sets up the fields in the superclass
        this.modelType = modelType;
    }

    // purely "local" code
    public void getModelType()
    {
        return modelType;
    }

    // Accesses several protected data to provide new (public) functionality
    public void addTable()
    {
        if (getNumberOfReinits() < 10)
        {
           numberOfTables++;
           reinit();
        }
    }
}

如果我误解了您的要求,请告诉我,但听起来您想访问超类的字段和行为 - 只要它们不是,您就可以在子类中自动访问它们private

于 2010-07-28T15:20:42.730 回答