100%抽象类与接口

时间:2010-09-28 07:37:38

标签: java php oop

是否有理由使用100%抽象类而不是接口? 你能不能给我一个很好的例子,这样我可以稍微掌握这个概念?

更新: 100%抽象类 - >只有抽象方法的抽象类。 如果php和java之间在这方面存在差异,我很好奇。

UPDATE2: 即使我理解大多数原因,我对概念更感兴趣而不是技术原因。

7 个答案:

答案 0 :(得分:18)

如果“100%抽象类”是指“没有具体方法的抽象类”,那么我可以想出一个原因:可见性。

您可以定义要保护的抽象方法,因此不是该类的公共API的一部分。然而,这似乎是一个奇怪的设计。

我想到的另一件事是你希望在基类中添加常用功能 - 即它是否可能有一些所有实现者共享的实用方法,但这些方法没有实现。

另一件事 - 实例变量。您可以在抽象类中拥有可继承的实例变量。

答案 1 :(得分:11)

“100%抽象类”在界面上可能有利的一种情况是API稳定性是关键问题。

如果您编写API,其他人应该实现您的界面,您必须坚持使用该界面。您以后不能向接口添加任何方法,因为这会破坏所有客户端(您必须通过实现第二个接口来解决此问题,并让您的代码再次检查instanceof检查的使用情况并提供回退)。 p>

如果您对某个类实现了相同的功能,则可以在以后添加(非抽象)方法而不会破坏客户端。

答案 2 :(得分:2)

除了可见性之外,另一个原因可能是能够指定您希望所有实现实现的特定构造函数,或者定义某个属性。但总的来说,我同意亚历山大的观点,100%的抽象课不是一个好主意。在大多数情况下,我更喜欢一个界面,除非有一个很好的理由不使用界面。

答案 3 :(得分:1)

我个人认为差异在于概念而非技术。例如,拥有一个名为“Human”的界面并在Male和Female上实现它们是个坏主意。让人类成为阶级更有意义。

您可以实现多个接口,您应该将接口视为附加组件。

答案 4 :(得分:1)

我不太确定如何在概念上回答这个问题,但在实践中我使用接口的原因如下:

  • 表示不同的类具有共享接口:您可以操作它们/以相同的方式使用它们
  • 您可以实现多个接口,但只能扩展一个类

使用抽象类的原因:

  • 在类似对象之间共享功能。例如,Porshe911可以扩展Car,覆盖一些方法并保留其余的。
  • 编写人们可以适应的框架。例如,通过保留一些未实现的关键方法,并将类的其余部分编写为内部一致,前提是您实现了这几个方法。一个示例是具有单个抽象方法getMenuItems()
  • 的菜单类

你对100%抽象类的例子对我来说似乎毫无意义。据我所知,这只会使它成为一个界面,增加的限制是你只能有一个。

答案 5 :(得分:0)

100%抽象类不是个好主意。对于子类的通用结构使用Interface。对于使用相同方法而不是相同方法的类似类,使用Abstract Class会更好。

答案 6 :(得分:0)

这是一个简单的例子,只能通过Interface实现。

interface P {
    void p();
}

interface Q {
    void q();
}       

interface R {
    void r();
}

class PQR implements P, Q, R {
    @Override
    public void p() {
        System.out.println("P");
    }

    @Override
    public void q() {
        System.out.println("Q");
    }

    @Override
    public void r() {
        System.out.println("R");
    }
}

class A {
    public void a(P pRef) {
        pRef.p();
    }
}

class B {
    public void b(Q qRef) {
        qRef.q();
    }
}

class C {
    public void c(R rRef) {
        rRef.r();
    }
}

public class InterfaceDemo {
    public static void main(String[] args) {
        P p = new PQR();
        A ainvoker = new A();
        ainvoker.a(p);

        Q q = new PQR();
        B binvoker = new B();
        binvoker.b(q);

        R r = new PQR();
        C cinvoker = new C();
        cinvoker.c(r);
    }
}