Java 继承-重写mutator方法?

Java 继承-重写mutator方法?,java,inheritance,overriding,Java,Inheritance,Overriding,那么,假设我有以下课程: 福 酒吧 在上面的例子中,BarKey是FooKey的一个子类。在这里,我想确保为Bar设置的键是FooKey的特定子类(即BarKey)。我该怎么办?我是不是把事情弄得太复杂了?有更好的设计方法吗?只需删除@Override注释,因为您没有覆盖超类的方法(应该是相同的参数),您只是定义了一个新的setKey方法,类型更窄。但是,这种新的设置键方法只能通过条参考进行访问 你不能这样强制执行。考虑: Bar b = new Bar(); FooKey k = new Fo

那么,假设我有以下课程:

福 酒吧
在上面的例子中,
BarKey
FooKey
的一个子类。在这里,我想确保为
Bar
设置的键是
FooKey
的特定子类(即
BarKey
)。我该怎么办?我是不是把事情弄得太复杂了?有更好的设计方法吗?

只需删除
@Override
注释,因为您没有覆盖超类的方法(应该是相同的参数),您只是定义了一个新的
setKey
方法,类型更窄。但是,这种新的设置键方法只能通过
参考进行访问

你不能这样强制执行。考虑:

Bar b = new Bar();
FooKey k = new FooKey();
b.setKey(k);  // You want to prohibit this
Foo f = b;
f.setKey(k);  // But there's no way to prohibit this
通常,派生类不能提供比其超类更严格的接口


因此,我建议从抽象类中删除
setKey

这是不正确的,因为您使子类比超类更具限制性:超类可以设置任何类型的FooKey,但子类只接受BarKey

为此,您需要将超类设置为泛型:

abstract class Foo<K extends FooKey> {
    private K key;

    public void setKey(K key){
        this.key = key;
    }
}

final class Bar extends Foo<BarKey> {
}
抽象类Foo{
私钥;
公共无效设置密钥(K密钥){
this.key=key;
}
}
最后一个类栏扩展了Foo{
}

您应该了解重写和重载之间的区别。您所做的只是重载,因为您更改了不允许重写的参数类型。

我不是继承方面的专家,但这不是使您的方法签名彼此不匹配,并且无法编译吗?也许使用
instaceof
会有所帮助?@posdef,是的,这不会编译(因此“不能这样做”)。是的,我知道我可以使用
instanceof
,但这通常是糟糕的OOP的标志。很好的解释。我想知道你的最后一句话是否可以概括为经验法则,比如,“在抽象类中使用特定的setter通常是个坏主意”@posdef:我不这么认为。问题不在于二传手,而是OP违反了规则。
Bar b = new Bar();
FooKey k = new FooKey();
b.setKey(k);  // You want to prohibit this
Foo f = b;
f.setKey(k);  // But there's no way to prohibit this
abstract class Foo<K extends FooKey> {
    private K key;

    public void setKey(K key){
        this.key = key;
    }
}

final class Bar extends Foo<BarKey> {
}