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

发布于 2024-09-11 14:48:29 字数 358 浏览 7 评论 0原文

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

public class MyTableModel extends DefaultTableModel {

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

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

这可以实现吗?

I would like to extend a class and then copy the value from an instance of the class which has been extended, so I get all its parameters in my new class. In case this doesn't make sense, a simple example of what I'm trying to do:

public class MyTableModel extends DefaultTableModel {

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

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

Is this possible to achieve?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

原来分手还会想你 2024-09-18 14:48:29

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

您永远无法设置 this = SomethingElse;,但您可以拥有一个 DefaultTableModel 委托,并将大多数/所有请求转发给 delegate,也许添加/根据需要装饰一些方法。

另请参阅

  • 《Effective Java 第 2 版》第 16 条:优先考虑组合而非继承

Guava 示例:ForwardingCollection

此模式的一个示例是 ForwardingCollection 来自 Guava

A java.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 所做的一切就是通过将所有方法转发到其委托来实现 Collection( ),另一个集合。可以理解,这是相当重复且平凡的代码,但现在子类可以简单地扩展 ForwardingCollection 并且只装饰它们想要装饰的内容。

It looks like you want composition instead of inheritance. In particular, it looks like you're trying to use the decorator pattern. That is, you want to take an existing instance of DefaultTableModel, and create another DefaultTableModel that forwards most of the methods to the underlying delegate, but perhaps adding/modifying/decorating some functionalities.

You can never set this = somethingElse;, but you can have a DefaultTableModel delegate, and forward most/all requests to delegate, perhaps adding/decorating some methods as necessary.

See also

  • Effective Java 2nd Edition, Item 16: Favor composition over inheritance

Guava Example: ForwardingCollection

An example of this pattern is ForwardingCollection from Guava:

A java.util.Collection which forwards all its method calls to another collection. Subclasses should override one or more methods to modify the behavior of the backing collection as desired per the decorator pattern.

You can see the source code to see how this pattern is typically implemented:

  @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...

As you can see, all the ForwardingCollection does is it implements Collection simply by forwarding all methods to its delegate(), another Collection. Understandably this is rather repetitive and mundane code to write, but now subclasses can simply extends ForwardingCollection and only decorate what they want to decorate.

奢望 2024-09-18 14:48:29

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

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

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

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

You can't not set this in Java to anything, it is just used for expressions like (this == someObject) or accessing some property of the object being currently used like (this.someProperty) or inside a constructor to initialize the current object. See here for more info about the this keyword

This code will likely throw a java.lang.ClassCastException

That is MyTableModel is a DefaultTableModel but DefaultTableModel is not a MyTableModel. See http://java.sun.com/docs/books/jls/third_edition/html/conversions.html for more details about type conversion in java

If there is some state and/or behavior that you want to reuse from your parent class in your subclass you should consider marking those members as protected, or consider other form of composition.

奢望 2024-09-18 14:48:29

更好的方法是使超类的字段受保护而不是私有 - 这将使您可以在子类中访问它们。

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

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

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

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

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

A better way to do this would be to make the fields of the superclass protected instead of private - this will give you access to them in your subclass.

Note that when you defined the subclass constructor, you will need to call a constructor from the superclass as well, so in that respect you'll still be able to pass in all the required variables.

And don't forget that all public methods in the superclass can be called as-is by any code that has an instance of your subclass.

EDIT: A little example might help:

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

Let me know if I've misunderstood your requirements, but it sounds like you want to access fields and behaviour of the superclass - which you'll have automatic access to in your subclass so long as they're not private.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文