java:关于重写方法的继承问题

java:关于重写方法的继承问题,java,class,inheritance,overriding,Java,Class,Inheritance,Overriding,如果父类中的方法不需要参数,但子类中的重写方法需要参数。在父类的方法中有一个无用的参数是一种好的做法吗 //in parent class: getFeature(String name){ return defaultFeature; } //in child class: getFeature(String name){ return new Feature(name); } 此方法已使用,并且仅在父类中的另一个方法中使用。因此,父类和子类具有相同的签名。真正的问题是有两

如果父类中的方法不需要参数,但子类中的重写方法需要参数。在父类的方法中有一个无用的参数是一种好的做法吗

//in parent class:
getFeature(String name){
    return defaultFeature;
}

//in child class:
getFeature(String name){
    return new Feature(name);
}
此方法已使用,并且仅在父类中的另一个方法中使用。因此,父类和子类具有相同的签名。真正的问题是有两个子类,它们的getFeature实现略有不同


还是有更好的方法来实现这一点

Actual您重写了,这是一种误导性的方法,因为类的客户端必须传递一个字符串,而这个字符串只在子类中使用:

child.getFeature("makeSenseArg");
parent.getFeature("notUsedArg");
应在子类中重载getFeature方法:

//in parent class:
getFeature(){
    return defaultFeature;
}

//in child class:
getFeature(String name){
    return new Feature(name);
}
你不会再从多元信仰中受益,但这可能不是问题,因为这是两种截然不同的行为。 将它们合并到一个方法签名中可能不是最好的做法

请注意,如果确实需要依赖重写,可以使用@javax.annotation.Nullable注释参数。 它使类客户端的API更加清晰,此外,Sonar等代码分析工具也考虑了这些注释。 这将使:

// parent class
Feature getFeature(@Nullable String name){
    return defaultFeature;
}
此外,如果对于重写的方法,该参数是必需的,则您甚至可以指定反向注释@javax.validation.constraints.notnull:

客户会称之为:

child.getFeature("makeSenseArg");
parent.getFeature(null);

实际重写,这是一种误导性的方法,因为类的客户端将必须传递字符串,而这仅在子类中使用:

child.getFeature("makeSenseArg");
parent.getFeature("notUsedArg");
应在子类中重载getFeature方法:

//in parent class:
getFeature(){
    return defaultFeature;
}

//in child class:
getFeature(String name){
    return new Feature(name);
}
你不会再从多元信仰中受益,但这可能不是问题,因为这是两种截然不同的行为。 将它们合并到一个方法签名中可能不是最好的做法

请注意,如果确实需要依赖重写,可以使用@javax.annotation.Nullable注释参数。 它使类客户端的API更加清晰,此外,Sonar等代码分析工具也考虑了这些注释。 这将使:

// parent class
Feature getFeature(@Nullable String name){
    return defaultFeature;
}
此外,如果对于重写的方法,该参数是必需的,则您甚至可以指定反向注释@javax.validation.constraints.notnull:

客户会称之为:

child.getFeature("makeSenseArg");
parent.getFeature(null);
在父类的方法中有一个无用的参数是一种好的做法吗

视情况而定。如果API设计预期即使基类不需要参数,子类也会需要参数,并且您希望确保可以通过父类型引用调用方法的参数版本:

Parent instance = new Subclass();
Feature f = instance.getFeature("foo");
…然后您必须在父类签名中包含该参数,即使在实现中未使用它。您可能还拥有无参数版本,该版本始终提供非参数功能:

class Parent {
    public Feature getFeature() { // Maybe you'd want this, maybe not
        return defaultFeature;
    }
    public Feature getFeature(String name) {
        return this.getFeature();
    }
}
class Subclass extends Parent {
    @Override
    public Feature getFeature(String name) {
        return /*...*/;
    }
}
但如果您预期子类实例将仅与子类类型化引用一起使用:

Subclass instance = new Subclass();
// ^^---------- note
Feature f = instance.getFeature("foo");
…那么父类的getFeature就没有理由拥有它。子类可以将其作为重载添加:

class Parent {
    public Feature getFeature() {
        return defaultFeature;
    }
}
class Subclass extends Parent {
    public Feature getFeature(String name) {
        return /*...*/;
    }
}
这只意味着父类型的引用将被限制为getFeature的无参数特性

在父类的方法中有一个无用的参数是一种好的做法吗

视情况而定。如果API设计预期即使基类不需要参数,子类也会需要参数,并且您希望确保可以通过父类型引用调用方法的参数版本:

Parent instance = new Subclass();
Feature f = instance.getFeature("foo");
…然后您必须在父类签名中包含该参数,即使在实现中未使用它。您可能还拥有无参数版本,该版本始终提供非参数功能:

class Parent {
    public Feature getFeature() { // Maybe you'd want this, maybe not
        return defaultFeature;
    }
    public Feature getFeature(String name) {
        return this.getFeature();
    }
}
class Subclass extends Parent {
    @Override
    public Feature getFeature(String name) {
        return /*...*/;
    }
}
但如果您预期子类实例将仅与子类类型化引用一起使用:

Subclass instance = new Subclass();
// ^^---------- note
Feature f = instance.getFeature("foo");
…那么父类的getFeature就没有理由拥有它。子类可以将其作为重载添加:

class Parent {
    public Feature getFeature() {
        return defaultFeature;
    }
}
class Subclass extends Parent {
    public Feature getFeature(String name) {
        return /*...*/;
    }
}

这只是意味着父类型的引用将被限制在getFeature的无参数功能中。

如果这样做,它就不再重写,而是重载。@Luiggmendoza:不完全是,相对于问题的最后一句话。在我看来,这是抽象工厂模式,除了父类不是抽象的并且返回一些默认对象之外。无论如何,具有不同签名名称+参数列表的方法是不同的方法,因此父类中不能有方法getName,子类中不能有方法getNameString名称,并希望覆盖它。它们没有相同的签名。但是这个getFeature被使用,并且只在父类中的另一个方法中使用。这就是多态性发生的地方。从您上次的评论来看,这似乎是一种可能的代码气味。你能进一步解释一下父类的设计吗?是否始终需要此名称参数?如果这样做,它将不再重写,而是
's重载。@LuiggiMendoza:不太可能,相对于问题的最后一句话来说。在我看来,这是抽象工厂模式,只是父类不是抽象的,并且返回一些默认对象。无论如何,具有不同签名名称+参数列表的方法是不同的方法,因此父类中不能有方法getName,子类中不能有方法getNameString名称,并希望覆盖它。它们没有相同的签名。但是这个getFeature被使用,并且只在父类中的另一个方法中使用。这就是多态性发生的地方。从您上次的评论来看,这似乎是一种可能的代码气味。你能进一步解释一下父类的设计吗?总是需要这个名称参数吗?在第一种方法中,问题或缺点是在子类对象中仍然可以访问无参数方法。在这些情况下,我们总是需要做一些权衡。在第一种方法中,问题或缺点是无参数方法仍然可以在子类对象中访问。在这种情况下,我们总是需要做出一些权衡。