Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
抽象类还是接口:JAVA?_Java - Fatal编程技术网

抽象类还是接口:JAVA?

抽象类还是接口:JAVA?,java,Java,我有一个常用方法,我需要在几个类中使用它,只需要调用调用类的一个调用。 所以我看到的是,我可以用两种方式来称呼它 public abstract class TestAbstractClass { void commonMethod(){ System.out.println("Calling common method : TestAbstractClass"); } } 主叫班级: public class RunApplication extends Te

我有一个常用方法,我需要在几个类中使用它,只需要调用调用类的一个调用。 所以我看到的是,我可以用两种方式来称呼它

public abstract class TestAbstractClass {
    void commonMethod(){
        System.out.println("Calling common method : TestAbstractClass");
    }
}
主叫班级:

public class RunApplication extends TestAbstractClass{

    public void testMethod(){
        commonMethod();
    }
}
[或]

在接口中使用默认方法的Java8特性

public interface TestInterface {
    default void commonMethod(){
        System.out.println("Calling common method : TestInterface");
    }
}
主叫班级:

public class RunApplication implements TestInterface{

    public void testMethod(){
        commonMethod();
    }
}
它们对我来说都很好, 但是,有什么更好的方法,一个带有非抽象方法的抽象类还是 与默认方法的接口

抽象类或接口

如果我是你,我会通过检查所有这些课程是否相关来判断是否合适

通常,如果实现接口的类几乎没有关系或者根本没有关系,并且它们恰好共享某些行为,这些行为可以通过接口中的方法公开,那么我将使用接口

public interface TestInterface {
    default void commonMethod(){
        System.out.println("Calling common method : TestInterface");
    }
}
当类是另一个类的子集时,我将使用抽象

示例:

以鸟和飞机为例。鸟和飞机都会飞。但除此之外,它们根本没有关系。您自然会希望实现一个接口,而不是使用抽象类,因为两个平面都不是鸟,也都不是鸟

class Bird implements Flyable
{
    @Override
    public void fly(){

    }
}

class Plane implements Flyable
{
    @Override
    public void fly(){

    }
}

另一个要考虑的问题是<强>多重继承< /强>。在Java中,类的多重继承是不允许的。因此,如果您使用抽象,您的子类将无法扩展到另一个类


如果您的类实现了一个接口,它总是可以实现另一个接口或扩展到另一个类。

这将是一个自以为是的线程

我的观点是,您应该使用
抽象类:它为其后代提供通用功能

Java 8接口中的默认方法也可以做到这一点,但它们的设计略有不同:

默认方法使您能够向库的接口添加新功能,并确保与为这些接口的旧版本编写的代码的二进制兼容性

(摘自)

换句话说,向接口添加默认方法可以在不破坏继承的情况下丰富接口

还要注意的是,使用Java8的
default
接口方法习惯用法限制了向后兼容性,尽管这在这里可能不是问题(否则我猜您不会在一开始就处理这两种方法)

归根结底,这一切都归结为您共同祖先中所期望的抽象类型,以及您希望如何在子代中派生它

注意


我在这里并没有详细阐述“抽象类与接口”这一典型的二分法,因为假设您知道其利弊

任何形式的继承都设计用于多态性


若你们有一个通用的方法,不要把它升级到超类,而是考虑使用单独的类来包装它。通过这种方式,您可以在以后重构代码,以便在通用方法出现任何波动时使用策略设计模式。

有参数支持这两种方法。最好的办法是看看它们之间的区别。例如,如果您希望子类继承另一个类,那么扩展抽象类并不是您想要做的事情。这样的问题在堆栈溢出上没有意义-答案实际上取决于您必须解决的具体问题。这里没有泛型的“this或thas更好”,问题还在于这一个方法是否与其他类紧密交织在一起,应该在接口或抽象类中。也许它应该是一个静态方法,或者它应该在一个单独的类中,您可以从该类中创建其他类中的字段。接口将允许您不阻止类的继承。例如,如果你的班级必须成为一个孩子,它将被允许,如果它已经继承了另一个类,则情况并非如此。这完全取决于您的需求,但我认为如果您在这种情况下进行扩展,那么您将从子类中获取一个属性,因为在该子类之后,该子类将无法扩展任何其他类,但在接口的情况下,您可以选择将任何其他类扩展为也可以使用默认关键字well在接口中定义的实现,但是可以从另一个类实现接口和子类。如果您已经从抽象类中创建子类,则不会出现这种情况…:)@hfhc2属于标准和众所周知的抽象类与接口二分法。我想OP已经知道了。