Faking abstract methods using exceptions in Java

假装的抽象方法使用异常在Java

问题 (Question)

I've been asked this question and am frankly stumped:

Instead of writing abstract methods we could try to fake them with exceptions, like this:

public int someMethod(int someparameter) {
    throws new RuntimeException("unimplemented");
}

What would be the purpose of doing this and can anyone provide an example of code for an abstract method that the above is trying to fake? Any help is greatly appreciated. Thank you.

有人问我这个问题,我坦白了:

而不是写摘要的方法我们可以假装他们有例外,像这样:

public int someMethod(int someparameter) {
    throws new RuntimeException("unimplemented");
}

什么是这样做的目的,任何人都可以为上述企图伪造一个抽象方法提供一个例子代码?非常感谢您的帮助。谢谢你

最佳答案 (Best Answer)

I can think of one (possibly) valid use case: You have an abstract class, and a number of other classes throughout your project that extended it. (Or the abstract class is in an open-source library, so you have no idea what other classes throughout the universe might be extended from it.) Now, you find that it's useful to add new abstract methods to this class. But if you add abstract methods to the class, this breaks every other class that has already extended it, because those classes need to be changed to contain override for the new methods. So I can see how, in some cases, it might be considered more feasible to add them as non-abstract methods and have them throw exceptions just in case a new class that extends it uses the new methods but forgets to write an overriding method. It won't be caught at compile-time, but at least it might be caught during testing.

I'm not sure how legitimate this reason is, since it's also possible to define a new abstract class NewImprovedWhatever that extends the old one, to contain the new methods. That may pose its own maintenance challenges, though. I'm not sure.

I did notice that Java defines an abstract class java.net.SocketImpl, that contains two non-abstract methods, shutdownInput() and shutdownOutput(), whose default implementation is to throw an exception:

protected void shutdownInput() throws IOException {
  throw new IOException("Method not implemented!");
}

The comments indicate that they were added in 1.3, so perhaps that's the exact reason it was done this way, i.e. not to require modification of other classes that already extended SocketImpl. But I don't know for sure.

In any case, a design like this would surely be really bad code, if the class were designed that way from scratch. But the nice O-O concepts we learn about in class aren't always so nice in practice when existing code has to be modified.

我能想到一个(可能)有效的使用案例:你有一个抽象类,并在您的项目中,扩展了它的一些其他类。(或抽象类是一个开源的库,所以你不知道其他类在整个宇宙中可能会延长它。)现在,你发现它对这类添加新的抽象方法。但是如果你加入abstract方法的类,这打破了其他班,已经扩大了它,因为这些类需要改变包含新的方法重写。所以我可以看到,在某些情况下,它可能是更可行的添加作为非抽象方法和他们抛出异常以防万一类的类使用新的方法却忘了写一个压倒一切的方法。它不会在编译时被发现,但至少它可能被捕获在测试。

我不确定这个原因是合法的,因为定义一个新的抽象类,它也有可能NewImprovedWhatever将旧的,包含新的方法。这可能会造成自己的维修的挑战,尽管。我不确定。

我的确注意到,Java定义了一个抽象类java.net.SocketImpl,包含两个非抽象方法,shutdownInput()shutdownOutput(),其默认实现是抛出一个异常:

protected void shutdownInput() throws IOException {
  throw new IOException("Method not implemented!");
}

的言论表明,他们增加了1.3,所以也许这就是这样做是确切的原因,即不需要修改的其他类,已扩展SocketImpl。但我不知道。

在任何情况下,一个这样的设计无疑是很糟糕的代码,如果类从头开始设计这样的。但好的面向对象的概念,我们了解在课堂上并不总是这么好的做法时,现有的代码已被修改。

答案 (Answer) 2

The purpose of doing this would be to purposefully write BAD CODE.
If one wants to confuse its readers and want them to feel the agony of going through their code, then one writes such code.
It also shows lack of designing skills in the code.
A poorly written API will have such code.
Don't do that.

这样做的目的是要有目的地写糟糕的代码
如果一个人想迷惑读者,让他们感觉到的痛苦经历他们的代码,然后编写这样的代码。
它也显示在代码中缺少设计技巧。
写得不好的API会有这样的代码。
不要那样做。

答案 (Answer) 3

I have sometimes thrown UnsupportedOperationException from a method whose functionality has not yet been implemented. (There is also a NotImplementedException in Apache Commons which is a subclass of UnsupportedOperationException.) This was always meant as a placeholder and a message to others using the related class or service that the method is not yet complete. Such code never made it to production, however.

有时候我会抛出UnsupportedOperationException异常从法的功能尚未实施。(还有一个在Apache Commons notimplementedexception这是UnsupportedOperationException异常的一个子类。)这意味着作为一个占位符,一个消息给他人使用相关的类或方法是尚未完成的服务。这样的代码没有生产,但。

本文翻译自StackoverFlow,英语好的童鞋可直接参考原文:http://stackoverflow.com/questions/22077172