我想扩展一个类,然后从已扩展的类的实例中复制该值,因此我在新类中获取所有参数。如果这没有意义,那就是我正在尝试做的一个简单例子:
public class MyTableModel extends DefaultTableModel {
public MyTableModel(DefaultTableModel model){
this = (MyTableModel) model; /* I realise this is invalid */
}
public newMethod(){
// Some additional code
}
}
这可能实现吗?
答案 0 :(得分:3)
看起来你想要组合而不是继承。特别是,您似乎正在尝试使用decorator pattern。也就是说,您希望获取DefaultTableModel
的现有实例,并创建另一个DefaultTableModel
,将大多数方法转发给基础委托,但可能会添加/修改/修饰某些功能。
您永远不能设置this = somethingElse;
,但您可以拥有DefaultTableModel delegate
,并将大多数/所有请求转发给delegate
,也许可以根据需要添加/装饰某些方法。
ForwardingCollection
此模式的一个示例是ForwardingCollection
from Guava:
一个
java.util.Collection
,它将所有方法调用转发给另一个集合。子类应该重写一个或多个方法,以根据装饰器模式修改后端集合的行为。
您可以看到the source code以了解此模式的实施方式:
@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
,只能装饰他们想要装饰的东西。
答案 1 :(得分:1)
您不能将Java中的 this 设置为任何内容,它只用于(this == someObject)
之类的表达式或访问当前使用的对象的某些属性,如(this.someProperty)
或者在构造函数内部初始化当前对象。有关this
关键字
此代码可能会抛出java.lang.ClassCastException
即MyTableModel
是DefaultTableModel
,但DefaultTableModel
不是MyTableModel
。有关java中类型转换的更多详细信息,请参阅http://java.sun.com/docs/books/jls/third_edition/html/conversions.html
如果您希望从子类中的父类重用某些状态和/或行为,则应考虑将这些成员标记为protected
,或考虑其他形式的组合。
答案 2 :(得分: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();
}
}
}
如果我误解了您的要求,请告诉我,但听起来您想要访问超类的字段和行为 - 只要它们不是{{1,您就可以自动访问子类中的字段和行为}}