【问题标题】:How to implement a method to be inherited by abstract subclasses?如何实现抽象子类继承的方法?
【发布时间】:2016-04-14 19:13:58
【问题描述】:

使用 Java 工作。

我已经定义了几个不同的抽象类,每个抽象类都有一个名为 aCommonMethod 的静态方法。每一个还有一个依赖方法,它本身调用一个CommonMethod,如下:

public abstract class SomeAbstractClass{
    public static void aCommonMethod() {
    // does something
    }

    public static void someDependentMethod() {
    //some stuff
    aCommonMethod()
    //some more stuff
    }
}

方法 someDependentMethod 对于我的每个抽象类都是相同的,除了通过调用 aCommonMethod 调用的方法。

在 Java 中实现这个的惯用方式是什么?到目前为止,除了将 aCommonMethod 方法实际复制到我的每个抽象类中之外,我找不到任何有效的方法。显然,最好只在某个地方编写一次该方法,然后让我的抽象类以某种方式继承它。我在 Java 中找不到任何方法。

【问题讨论】:

  • SomeAbstractClass 实际上并不是抽象的。您是否发布了正确的代码?
  • 你为什么使用抽象类而不是接口?

标签: java inheritance static overriding abstract


【解决方案1】:

拳头,你不能重写静态方法,如果你想让不同的类有不同的行为可能需要template pattern

例子:

public abstract class SomeAbstractClass{
    public abstract void aCommonMethod();

    public void someDependentMethod() {
        //some stuff
        aCommonMethod();
        //some more stuff
    }
}

public abstract class SomeClass{
    public void aCommonMethod() {
        // Do your thing
    }
}

public abstract class SomeOtherClass{
    public void aCommonMethod() {
        // Do your thing
    }
}

new SomeClass().someDependentMethod();
new SomeOtherClass().someDependentMethod();

【讨论】:

    【解决方案2】:

    如果我明白你的意思,我不确定,但我会通过使用这两个类来解决你的问题:

    母级:

    public class mother 
    {
        public void sortTest()
        {
            //some stuff
            child.sort();
            //some stuff
        }
    }
    

    儿童班:

    public abstract class child extends mother
    {
        public static void sort()
        {
            //some stuff
        }
    }
    

    你应该更准确地描述你的问题!

    【讨论】:

    • 我怎么能更精确呢?我以精确的数学精度陈述了这个问题,并抽象出了所有不相关的细节。即便如此,这实际上可能是我需要的答案,所以谢谢。
    • 为什么是抽象类而不是接口?
    • @AdamHolder - 你真的认为你以如此精确的精度和所需的确切细节量指定了问题,但常规开发人员仍然不明白你想要什么?从您的问题中可以清楚地看出您不懂基本的 Java,但您仍然拒绝听合理的查询。
    • 很明显,这个论坛不欢迎那些还不是专家并且正在努力学习的人。我可能不是 Java 专家,但我知道“数学精度”是什么样的,因为那是我的工作。我将尝试在其他地方找到有帮助的人。
    【解决方案3】:

    这就是抽象方法的用途。

    abstract class SomeAbstractClass {
        public abstract void aCommonMethod();
    
        public void someDependentMethod() {
            // some stuff
            aCommonMethod();
           // some more stuff
        }
    }
    
    class Impl1 extends SomeAbstractClass {
        @Override public void aCommonMethod() {
           System.out.println("Impl1 version of aCommonMethod");
        }
    }
    

    每个子类都可以实现抽象方法来做自己的事,普通的超类方法会调用具体子类的实现。

    继承不适用于静态方法,请改为使用这些实例方法。惯用的答案是避免对属于类层次结构的方法使用静态。

    您在示例中拥有的内容,从您将 aCommonMethod 定义为返回 void 来看,似乎是有状态的且受副作用影响,但如果您拥有的是一组无状态的静态方法,那么您可能不会这里根本需要一个类层次结构;考虑使用策略模式,传入指定操作的对象。

    请参阅this question,了解在 Java 8 中使用 lambda 传递策略。

    【讨论】:

    • 感谢您的合法回答。但是,将我所有的 QuickSort 方法收集到一个抽象的 QuickSort 类中是否违反 Java 的方式?这就是我在这里所做的。我认为这与 Java.util 的 Arrays 类非常相似。它只是有用功能的集合。在我编写 QuckSort 对象时,没有任何理由会实例化它。
    • @AdamHolder:java.util.Arrays 之类的东西不能被继承。如果你有无状态函数,那么静态方法是可以的,但如果你希望覆盖行为,那么你需要实例方法。
    【解决方案4】:

    从 Java 8 开始,现在可以使用 lambda 表达式将函数作为参数传递给其他函数。然而程序员在 Java 8 之前就绕过了这个问题,他们过于复杂的机制已经过时了。

    例如,使用新的 lambda 表达式,可以写成

    interface PointlessInterfaceObject {
        void onlyFunction();
    }
    

    那么 someDependentMethod 可以这样定义:

    someDependentMethod(PointlessInterfaceObject myPointlessInterfaceObject){
    // some code
    myPointlessInterfaceObject.onlyFunction();
    // more code
    }
    

    现在,如果你先像这样实例化匿名函数,

    PointlessInterfaceObject myAnonymousFunction = ()->SomeAbstractClass.aCommonMethod();
    

    然后你可以将它作为参数传递给方法,如下所示:

    someDependentMethod(myAnonymousFunction)
    

    这允许您像 someDependentMethod 一样只编写一次函数,然后将其他方法传递给它。

    【讨论】:

      猜你喜欢
      • 2013-08-25
      • 1970-01-01
      • 2014-02-17
      • 2013-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多