简体   繁体   English

是否可以在Java中链接重写的方法

[英]Is it possible to chain overridden methods in Java

Let's say that I have an abstract class: 假设我有一个抽象类:

abstract class DBTable {

    abstract boolean append();

}

And that I also have a child class that inherits from DBTable: 而且我还有一个从DBTable继承的子类:

// Client objects are rows of a database table
class Client extends DBTable {

    @Override
    boolean append() {

    }
}

Finally, let's say that I have a subclass of Client which I have used to represent the denormalized form of a Client object (I feel that this is ok. It's all in the same package and a Client.Expand -is a- Client). 最后,假设我有一个Client的子类,用于表示Client对象的非规范化形式(我觉得这没关系。它们都在同一包中,并且Client.Expand -is- Client)。

What I would like to do is override the append() method in Client.Expand, and have it chain up to the append() method in Client before coming back to doing work that is appropriate only for the subclass. 我想做的是重写Client.Expand中的append()方法,并使其返回到Client中的append()方法,然后再返回仅适用于子类的工作。 Something like this... 像这样

    // Expand is a member class of Client
    static class Expand extends Client {

        @Override
        boolean append() {
            super.append();
            :
            :
        }
    }

Does Java allow this? Java允许吗? I am getting errors from the IDE when I try to override a method that is already overridden in the parent class. 当我尝试覆盖在父类中已被覆盖的方法时,我从IDE中收到错误消息。 It seems like I should be able to override an overridden method to provide for additional implementation needed by the child class, but maybe Java isn't built for this kind of inheritance? 看来我应该能够重写一个重写的方法以提供子类所需的其他实现,但是也许Java不是为这种继承构建的?

There are several issues with your example: 您的示例有几个问题:

  1. When you declare a member of a class as static, this member is associated with the Class. 当您将类的成员声明为静态时,该成员与该类相关联。 It cannot be used with and instance of that class. 不能与该类的实例一起使用。 For example, when you have a code in Expand's append method such as - super .append() - that "super" refers to an instance, not "class". 例如,当你有一个代码中展开的附加方法,如- 超级 .append() -即“超”是指一个实例,而不是“下课”。 Therefore it contradicts the static definition. 因此,它与静态定义相矛盾。 As is suggested in the comments, you need to remove static from class declaration. 如注释中所建议,您需要从类声明中删除静态变量。

  2. A child class, should not be an inner class, this is not a good design, even if it is allowed. 子类,不应是内部类,即使允许,也不是一个好的设计。 Because, if you think about it semantically, a subclass is not a member of the super class (parent child words is misleading in this case, superclass and subclass are better) . 因为,如果从语义上考虑它,则子类不是超类的成员(在这种情况下,父子词会产生误导,因此,超类和子类更好)。 Superclass should not know about classes that may extend it, it should be self-contained. 超类不应该知道可以扩展它的类,它应该是独立的。 Therefore, it is better to move subclass to a separate class. 因此,最好将子类移至单独的类。

  3. Your design has some other issues as well: First of all, naming is not descriptive of the subject. 您的设计还存在其他一些问题:首先,命名并不能描述主题。 If client represents a row, then Row, or TableRow, ... is perhaps a better name, and ExpendedRow for the next class. 如果client代表一行,那么Row或TableRow ...可能是一个更好的名称,而ExpendedRow用于下一个类。

But, more importantly, a row extending a table is not a good idea. 但是,更重要的是,扩展表的行并不是一个好主意。 A better approach might be to have a Row class and Table class composing Row. 更好的方法可能是让Row类和Table类组成Row。 Something like this: 像这样:

// Client objects are rows of a database table
class Row {

    @Override
    boolean append() {

    }
}

class Expanded extends Row{

        @Override
        boolean append() {
            super.append();
            :
            :
        }
    }
class DBTable {

    Row row;

}

I've found the problem. 我发现了问题。 It's embarrassing. 这让人很难堪。 I'll answer my own question a bit circuitously as part of my own defense. 在我自己的辩护中,我会'回地回答自己的问题。

I like to design my classes so that a class subserves a theme. 我喜欢设计班级,以便班级可以保留主题。 All the functionality that is related to that theme, I like to try and place into the same class. 与该主题相关的所有功能,我都想尝试并放入同一类中。 This works especially well for database data model classes, because the structure of the classes can often be repeated for other database model classes. 这对于数据库数据模型类特别有效,因为对于其他数据库模型类而言,此类结构通常可以重复。

What do I mean exactly? 我到底是什么意思

Well, here is the "structure" of my Client class. 好吧,这是我的客户类的“结构”。 As you can see, it contains several member classes: 如您所见,它包含几个成员类:

+----------------------------+
|  CLIENT                    |
+---+------------------------+
    |  static EXPAND         |
    +------------------------+
    |  static GHOST          |
    +------------------------+
    |  static BUILDER        |
    +------------------------+
    |  static INQUISITOR     |
    +------------------------+
    |  static QUERYBUILDER   |
    +------------------------+
    |  static JDBCFactory    |
    +------------------------+

I like this design a lot. 我非常喜欢这个设计。 It means that the class that builds Client objects for me can be in the same file as the Client class and I can invoke it with the semi-mnemonic "new Client.Builder()" or that I can create an object that builds SQL queries for Client objects with "new Client.QueryBuilder()". 这意味着为我构建Client对象的类可以与Client类位于同一文件中,并且可以使用半助记符“ new Client.Builder()”来调用它,或者可以创建用于构建SQL查询的对象带有“ new Client.QueryBuilder()”的客户端对象。 The class whose object becomes the factory for making Client objects from JDBC resultsets can be instantiated with "new Client.JDBCFactory" etc. etc. I like this a lot. 可以使用“ new Client.JDBCFactory”等实例化其对象成为从JDBC结果集中制作Client对象的工厂的类。我非常喜欢这一类。

The downside ... is that I have a lot of braces. 缺点是我的牙套很多。

And ... if I'm not careful, I can type something that ends up in the wrong context. 而且...如果我不小心,我可以输入以错误的上下文结尾的内容。 In this case, where I was typing the definition for the append() method that I -wanted- to be in the EXPAND member class ... was actually just outside the brace and I was typing it into the context for CLIENT. 在这种情况下,我要键入我希望在EXPAND成员类中的append()方法的定义...实际上只是在括号之外,而是在CLIENT的上下文中键入它。

Well, Client already had an append() method and so the IDE was complaining to me that I was trying to override a method in the very same class that already had an append() method. 好的,Client已经有一个append()方法,因此IDE向我抱怨说我试图覆盖已经具有append()方法的同一类中的方法。

Yes, Java does fully support override chaining. 是的,Java完全支持覆盖链接。 There's nothing wrong with my IDE or JVM ... just with me. 我的IDE或JVM没什么问题,只是我。 Thanks again to @Robe and others for their input. 再次感谢@Robe和其他人的投入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM