2010-09-28 119 views
10

是否有理由使用100%抽象类而不是接口? 你能否给我一个很好的例子,以便同时使用这两个概念,以便我能够把握这个概念?100%抽象类与接口

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

Update2: 即使我理解了大部分原因,我对概念更感兴趣超过技术原因。

+0

如何定义'100%抽象类'? – 2010-09-28 07:40:57

+0

java或php?哪一个? – Thilo 2010-09-28 07:41:43

+3

我认为他的意思是抽象类只有抽象方法,在100%抽象类中没有默认实现 – 2010-09-28 07:51:34

回答

18

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

您可以定义要保护的抽象方法,因此不是该类的公共API的一部分。但是,这看起来像一个奇怪的设计。

我想到的另一件事是,当您希望为基类添加通用功能时 - 即,如果它可能有一些实用方法由所有实现者共享,但这些方法未实现。

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

+6

,你也可以定义可以遗漏的非常量变量。这是不可能的接口。 – 2010-09-28 07:46:47

+0

@Benoit准确无误。无论如何,我在添加这个内容的同时也表示感谢。 – Bozho 2010-09-28 07:48:03

+2

另一件事是构造函数......这在接口 – 2010-09-28 07:50:47

0

100%抽象类不是好主意。对于通用结构的子类使用Interface。对于类似的类有相同的方法而不是相同的其他类更适合使用抽象类。

2

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

1

我个人认为差异作为概念比技术更重要。例如,拥有一个名为“Human”的界面并将它们应用于男性和女性将是一个不好的主意。将人类作为课堂会更有意义。

您可以实现多个接口,并且应该将接口看作加载项。

+0

拥有人机界面的确是一个坏主意? – 2010-09-28 07:53:39

+0

男性和女性共享功能,它们不是通用接口的不同实现。此外,人的概念不是由人类实现的功能来定义的。 – 2010-09-28 07:57:17

+0

甚至还有人机接口指南;-) – Thilo 2010-09-28 07:57:59

11

一个“100%抽象类”可能比接口更有优势的例子是API稳定性是一个关键问题的地方。

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

如果您意识到与类相同,则可以稍后添加(非抽象)方法而不会破坏客户端。

+1

+1。这是JDK接口(如java.sql.Connection)的一个问题,它们一直添加方法,所以旧的实现不再编译。 – Thilo 2010-09-28 07:59:47

+0

如果集合接口是“纯粹的”抽象类,我们不需要防御方法。 – 2010-09-29 00:11:14

1

我不太知道如何回答这个概念了,但在实践中我使用的接口,原因如下:

  • 来表示不同的类别有一个共同的接口:你可以操纵他们/使用他们以同样的方式
  • 可以实现多个接口,但只能继承一个类

理由使用抽象类:

  • 分享类似对象之间的功能。例如,Porshe911可以扩展Car,覆盖一些方法并保留其余部分。
  • 编写人们可以适应的框架。例如,通过让一些重要的方法未实现,并且将其余的类编写成内部一致,只要实现这些方法即可。一个例子是一个带有抽象方法的菜单类getMenuItems()

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

0

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

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); 
    } 
}