【问题标题】:What is the benefit of creating an abstract class with only final methods?创建一个只有最终方法的抽象类有什么好处?
【发布时间】:2015-07-06 20:47:25
【问题描述】:

我的意思是,很明显,多态方面没有任何好处,

并将(所有)这些方法声明为 final 会阻止我覆盖它们。 而且我知道这是可能的,编译器不会阻止你这样做。

我很想得到一个用法示例...

【问题讨论】:

  • 我不确定是否有一个。
  • 是什么让您认为有好处?只是编译器允许您这样做的事实?编译器让你做很多无用的事情。 public static void main(String[] args) { throw new RuntimeException("useless"); }
  • 可能你只是真的想要一个不能直接实例化但不需要任何抽象方法的基类。不寻常但耸了耸肩。
  • 你能给我们举个例子吗?

标签: java oop abstract-class final


【解决方案1】:

在一些边缘情况下,这样的设计即使不是最优的,至少也可以被激发。例如,您可能有一个类系统,一个公共父类的所有子类,其中每个子类实现一个进一步的接口。可能有一组接口形式不同,但基本功能相同。

在这种特殊情况下,将所有方法设为final 并让每个子类添加自己的方法来使用它们并没有什么坏处。

【讨论】:

  • 在“共同父”中使方法“最终”?
  • 是的。没有理由不这样做。除了这整个事情可能会更好的组合模式。
【解决方案2】:

我会说它是“核心”组件的一部分。您构建了一些东西并设计了架构,并且您知道永远不应更改该方法。

【讨论】:

  • 你所说的对于任何最终方法都是正确的 - 使类抽象及其方法最终有什么好处?
【解决方案3】:

抽象类可以拥有package 访问某些内部方法的权限。

在这种情况下,我们有

  • 一个不完整的类
  • 功能必须保持不变并授予对内部模型的安全访问权限

这就是我们需要声明一个抽象类型及其所有方法final。以一个包含图形的Panel 类为例,但并不总是提供一种让它自己绘制的方法——子类可以有不同的绘制行为。另一方面,它可以提供final protected DrawBuffer makeCircle() 或类似的东西,出于某种原因,它必须访问内部模型才能生成DrawBuffer

【讨论】:

  • 在我的示例中,如果超类根本不提供公共 API,对象组合(实现这些 final 方法的内部帮助对象)会更自然。
【解决方案4】:

当某些方法以这种方式声明时,当它不能被覆盖时,JIT 可以受益。 (静态的、私有的、最终的、在最终类中)

假设您有课程:

abstract class A {
     public void doSomething() {
         // default and only realization;
     }
}

class B extends A { ... }

然后你写这样的东西:

A a = MyAFactory.createA();
a.doSomething();

当方法不知道是final,并且有可能(即使刚刚没有加载)覆盖时,编译器会在第二行调用虚方法。 IE。首先它会确定到底是哪个类A,然后查看虚拟方法表,然后才调用特定的方法。

但是!如果已知方法不能被覆盖,那么编译器可以直接调用 A.doSomething()。

因此,除非您需要覆盖它们,否则建议将方法设为 final。

让我们想象这样的课程:

abstract class C {

    public abstract int getMin();

    public abstract int getMax();

    public final int getSize() {
        return getMax() - getMin();
    }

}

在这个例子中,getSize() 的行为很明显,很难想象什么时候需要改变它。因此,将其声明为 final,不仅可以通过丢弃虚拟调用机制带来好处,而且还可以防止对具有特定和预定义行为的方法进行意外覆盖。

【讨论】:

    猜你喜欢
    • 2017-04-10
    • 2012-07-19
    • 2014-10-30
    • 2010-11-20
    • 2018-04-20
    • 2016-11-24
    • 1970-01-01
    • 1970-01-01
    • 2013-07-22
    相关资源
    最近更新 更多