在Java中扩展类并使用扩展类的实例构造

在Java中扩展类并使用扩展类的实例构造,java,extend,Java,Extend,我想扩展一个类,然后从已扩展的类的实例中复制该值,因此我在新类中获取它的所有参数。如果这不合理,请举一个简单的例子说明我正在尝试做什么: public class MyTableModel extends DefaultTableModel { public MyTableModel(DefaultTableModel model){ this = (MyTableModel) model; /* I realise this is invalid */ }

我想扩展一个类,然后从已扩展的类的实例中复制该值,因此我在新类中获取它的所有参数。如果这不合理,请举一个简单的例子说明我正在尝试做什么:

public class MyTableModel extends DefaultTableModel {

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

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

这可能实现吗?

更好的方法是将超类
的字段设置为受保护的
,而不是
私有的
——这将允许您在子类中访问它们

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

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

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

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;
    }
}

公共类MyTableModel扩展了DefaultTableModel
{
私有字符串模型类型;
公共MyTableModel(字符串名称、int numTables、字符串模型类型)
{ 
super(名称,numTables);//设置超类中的字段
this.modelType=modelType;
}
//纯粹的“本地”代码
public void getModelType()
{
返回模型类型;
}
//访问多个受保护的数据以提供新的(公共)功能
公共void addTable()
{
if(getNumberOfReinits()<10)
{
numberOfTables++;
雷尼特();
}
}
}
如果我误解了您的要求,请告诉我,但听起来您希望访问超类的字段和行为-您可以在子类中自动访问这些字段和行为,只要它们不是私有的。特别是,看起来您正在尝试使用。也就是说,您希望获取一个现有的
DefaultTableModel
实例,并创建另一个
DefaultTableModel
,该实例将大多数方法转发给底层委托,但可能会添加/修改/修饰一些功能

您永远不能设置
this=somethingElse
,但您可以拥有一个
DefaultTableModel委托
,并将大部分/所有请求转发给
委托
,可能会根据需要添加/修饰一些方法

另见
  • 有效Java第二版,第16项:偏爱组合而非继承

番石榴示例:
ForwardingCollection
这种模式的一个例子是:

将其所有方法调用转发到另一个集合的。根据decorator模式,子类应该重写一个或多个方法,以根据需要修改支持集合的行为

您可以看到此模式通常是如何实现的:

  @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...
@重写受保护的抽象集合委托();
公共整数大小(){
返回委托().size();
}    
公共布尔值为空(){
返回委托().isEmpty();
}
公共布尔removeAll(集合){
返回委托().removeAll(集合);
}
//还有更多的接口收集方法像上面那样实现。。。

正如您所看到的,
ForwardingCollection
只需将所有方法转发到另一个
集合
委托()
,即可实现集合
。可以理解,这是一个相当重复和平凡的代码,但是现在子类可以简单地
扩展ForwardingCollection
,并且只修饰它们想要修饰的内容。

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

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

也就是说,
MyTableModel
DefaultTableModel
DefaultTableModel
不是
MyTableModel
。有关java中类型转换的更多详细信息,请参阅


如果您想在父类中重用父类中的某些状态和/或行为,则应考虑将这些成员标记为<代码>受保护的< /代码>,或者考虑其他形式的构词。

我不认为这会起作用。看起来OP有一个现有的对象,可能不一定有能力在第一个实例中将该对象实例化为MyTabLimoDeld。啊,我想你可能是对的。当我读到这个问题时,它是从“我想扩展一个类”开始的,所以我把它作为基本要求。经过深思熟虑,我认为其他答案可能是正确的,而Decorator模式是最合适的答案。
  @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...