Java 如何在不使用抽象的情况下强制实现子类中的方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18331350/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to force implementation of a method in subclass without using abstract?
提问by Maniz
I want to force subclass to implement an implemented method of my mother class. I look this Java - Force implementation of an implemented methodbut i can't convert my mother class to an abstract class.
我想强制子类实现我母类的已实现方法。我看这个Java - Force implementation of an implementation of an implementation,但我无法将我的母类转换为抽象类。
public class myMotherClass {
myMethod {
...some code ..
}
}
public class myClass extends myMotherClass {
myMethod {
... other code ...
}
}
So, in this exemple, I want to force myClass implement myMethod.
所以,在这个例子中,我想强制 myClass 实现 myMethod。
Sorry for my english...
对不起我的英语不好...
采纳答案by René Link
You can not force a subclass to override a method. You can only force it to implement a method by making it abstract.
您不能强制子类覆盖方法。您只能通过使其抽象来强制它实现一个方法。
So if you can not make myMotherClass abstract you can only introduce another superclass that extends myMotherClass and delegates to the method that must be implemented:
因此,如果您不能使 myMotherClass 抽象,则只能引入另一个扩展 myMotherClass 并委托给必须实现的方法的超类:
public abstract class EnforceImplementation extends myMotherClass {
public final void myMethod(){
implementMyMethod();
}
public abstract void implementMyMethod();
}
EDIT
编辑
I found another interessting way of solving the problem in the hemcrest
api that is e.g. used by mockito.
我在hemcrest
api 中找到了另一种解决问题的有趣方法,例如 mockito 使用的方法。
public interface Matcher<T> extends SelfDescribing {
/**
* Evaluates the matcher for argument <var>item</var>.
* <p/>
* This method matches against Object, instead of the generic type T. This is
* because the caller of the Matcher does not know at runtime what the type is
* (because of type erasure with Java generics). It is down to the implementations
* to check the correct type.
*
* @param item the object against which the matcher is evaluated.
* @return <code>true</code> if <var>item</var> matches, otherwise <code>false</code>.
*
* @see BaseMatcher
*/
boolean matches(Object item);
/**
* This method simply acts a friendly reminder not to implement Matcher directly and
* instead extend BaseMatcher. It's easy to ignore JavaDoc, but a bit harder to ignore
* compile errors .
*
* @see Matcher for reasons why.
* @see BaseMatcher
*/
void _dont_implement_Matcher___instead_extend_BaseMatcher_();
}
The interface specifies a method _dont_implement_Matcher___instead_extend_BaseMatcher_
. Of course it does not prevent others from implementing the Matcher
interface, but it guides the developer in the right direction.
接口指定了一个方法_dont_implement_Matcher___instead_extend_BaseMatcher_
。当然,它不会阻止其他人实现该Matcher
接口,但它会引导开发人员朝着正确的方向前进。
And the BaseMatcher
class implements the _dont_implement_Matcher___instead_extend_BaseMatcher_
method as final
并且BaseMatcher
该类将该_dont_implement_Matcher___instead_extend_BaseMatcher_
方法实现为 final
public final void _dont_implement_Matcher___instead_extend_BaseMatcher_() {
// See Matcher interface for an explanation of this method.
}
Finally I think that this is a design problem, because the BaseMatcher
obviouosly implements logic that every Matcher
should implement. Thus it would have been better to make the Matcher
an abstract class and use a template method.
最后我认为这是一个设计问题,因为BaseMatcher
显然实现了每个人都Matcher
应该实现的逻辑。因此,最好使Matcher
抽象类并使用模板方法。
But I guess they did it because it was the best compromise between bytecode compatibility and new features.
但我猜他们这样做是因为这是字节码兼容性和新功能之间的最佳折衷。
回答by Karthik T
You could rework your hierarchy so that your concrete classes are only leafs of the tree.
您可以重新设计您的层次结构,以便您的具体类只是树的叶子。
Instead of
代替
myClass extends myMotherClass
Consider
考虑
myClass extends myMotherAbstractClass
myMotherClass extends myMotherAbstractClass
This way the Abstract class is inherited by both instantiated classes. It is likely in this case the myMotherClass
would be extremely thin, just the implementation of myMethod
.
这样抽象类就被两个实例化的类继承了。在这种情况下,myMotherClass
可能会非常薄,只是myMethod
.
回答by Ruchira Gayan Ranaweera
If you really want to force to implement method use should use interface
.
如果你真的想强制实现方法使用应该使用interface
.
public interface MyInterface{
void myMethod();
}
Now if some one want to implement from this interface as MyClass implements MyInterface
, You have to implement myMethod();
现在如果有人想从这个接口实现 as MyClass implements MyInterface
,你必须实现myMethod();
public MyClass implements MyInterface{
public void myMethod{
// do something
}
}
回答by bnunamak
One thing most people are overlooking is the following implementation (although I saw mention of it in a comment):
大多数人忽略的一件事是以下实现(尽管我在评论中看到了它):
public class MyMotherClass {
public void myMethod() {
throw new RuntimeException("Method not overwritten");
}
}
In most cases this should be enough, as you should have some form of acceptance testing (even if it is only testing the inheriting class by hand). In theory, you are still introducing the possibility that nobody will realize that the method hasn't been overwitten until production though.
在大多数情况下,这应该足够了,因为您应该进行某种形式的验收测试(即使它只是手动测试继承类)。从理论上讲,您仍然在引入一种可能性,即没有人会意识到该方法直到生产才被覆盖。