首页 文章

如果你有一个只有抽象方法的Abstract类怎么办?这与界面有什么不同?

提问于
浏览
9

根据我的经验,我认为以下是正确的 . 如果我错过了重点,请告诉我 .

接口:

在接口中声明的每个单独的方法都必须在子类中实现 . 接口中只能存在事件,代理,属性(C#)和方法 . 一个类可以实现多个接口 .

抽象类:

只有抽象方法必须由子类实现 . Abstract类可以有实现的常规方法 . Abstract类还可以在Events,Delegates,Properties和Methods旁边有类变量 . 由于C#中不存在多重继承,因此类只能实现一个抽象类 .

所以,即使这种差异也无法解释这个问题

1)如果你的抽象类只有抽象方法怎么办?这与界面有什么不同? 2)如果你在界面中有一个Public变量,那么它与Abstract Class有什么不同呢?

所以任何解释都会有所不同 .

12 回答

  • 2

    当您希望您的类能够执行某些操作时,将使用接口 .

    当存在 'is a' 关系时,您的类会扩展一个抽象类 .

    存在语义差异 .

  • 0

    虽然你的问题表明它是“普通的OO”,但它似乎真正关注.NET对这些术语的使用 .

    • 接口可以没有状态或实现

    • 实现接口的类必须提供该接口的所有方法的实现

    • 抽象类可能包含state(数据成员)和/或实现(方法)

    • 抽象类可以在不实现抽象方法的情况下继承(尽管这样的派生类是抽象的)

    • 接口可能是多重继承的,抽象类可能不是(这可能是接口与abtract类分开存在的关键具体原因 - 它们允许实现多重继承,从而消除了一般MI的许多问题) .

    作为一般的OO术语,差异不一定是明确定义的 . 例如,有些C程序员可能拥有类似的严格定义(接口是不能包含实现的抽象类的严格子集),而有些人可能会说具有一些默认实现的抽象类仍然是一个接口或非抽象的class仍然可以定义一个接口 .

    实际上,有一个称为非虚拟接口(NVI)的C语言,其中公共方法是非虚拟方法,可以“窃取”私有虚拟方法:

    http://www.gotw.ca/publications/mill18.htm http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface

  • 3

    在Java中:

    abstract classimplement interface .

    interface cannot extend an abstract class .

    顺便说一句:奇怪的是 - abstract class 可以 implementinterface 而实际上并没有这样做 .

    interface I {
      public String hello ();
    }
    
    interface J {
      public String goodbye ();
    }
    
    abstract class A implements I, J {
      @Override
      abstract public String hello ();
    }
    
    class B extends A {
    
      @Override
      public String hello() {
        return "Hello";
      }
    
      @Override
      public String goodbye() {
        return "goodbye";
      }
    
    }
    
  • 1

    除了技术差异之外,主要是 intension of your design 会导致您决定使用其中一个:

    接口定义实现它们的类的公共API . 您使用接口的目标应该是显示实现它的类的用法 . 这不是副作用,而是一个中心设计目标,类可以实现不同的接口来显示它可以作用的不同角色 .

    抽象类应该实现一些基本算法或常见行为 . 它主要是在一个地方加入子类的通用功能 . 其目的是定义内部使用或流,而不是公共接口 . 如果要发布抽象类的用法,它应该实现一个单独的接口 .

    所以:

    1)当您使用上述指南时,仅使用公共抽象方法的抽象类没有任何意义 . 抽象类可以定义受保护的抽象方法来定义流或算法 . 但是接口不可能实现这一点 .

    2)对于公共属性,抽象类可以定义受保护的实例变量,因此有更多的使用场景(参见上面的解释) .

    编辑:作者删除了“java”标签 . 我试图让它尽可能通用,对于java和C#都应该是这样的

  • 1

    接口的所有变量默认为public和static,您不能在接口中只有一个公共变量,而在Abstract类中,您可以声明一个公共变量 .

    如果类扩展了Abstract类,则它们之间没有任何 Contract . 扩展它的类可能会也可能不会覆盖抽象方法,但是在接口的情况下,接口和实现它的类之间存在严格的约定,即类必须覆盖该接口的所有方法 . 因此从抽象方法的角度来看,它们似乎是相同的,但具有完全不同的属性和优点 .

  • 3

    如果你的抽象类只有抽象方法怎么办?这与界面有什么不同?

    • 您可以实现多个接口,但只能扩展一个类

    • 如果更改接口,抽象类更多 immune 来更改然后接口它会破坏实现它的类 .

    • 接口只能有 static final 个字段 . 抽象类可以有任何类型的字段 .

    • 接口没有构造函数,但抽象类可以拥有它

    但是java docs这样说

    如果抽象类仅包含抽象方法声明,则应将其声明为接口 .

  • 1

    即使今天的抽象类版本中的所有方法都是抽象的,该类的未来版本也可以添加虚拟或非虚拟方法,而无需强制修改实现或重新编译使用者 . 相反,将任何成员添加到接口通常需要修改实现接口的所有类以实现该成员,并且无论更改是否添加了尚未实现的任何内容,通常都必须重新编译实现和使用者 .

    抽象更改可以在不破坏实现或消费者的情况下进行更改这一事实是支持抽象类的一大优势 . 另一方面,抽象类将强制任何实现类仅从它派生而不是从其他类派生 . 相比之下,接口几乎会限制其实现者可以继承或派生的内容 . 这是支持接口的一大优势 .

    因为抽象类和接口都有明确的优点,所以有时候哪一个可能比另一个好 . 从概念上讲,可以在界面工作方式中添加一些功能,这样就可以获得目前仅由抽象类提供的优势,但我知道没有特别的计划 .

  • 2

    您的类只能扩展一个抽象类并实现许多接口 .

  • 0

    好吧,在一个抽象类中,你也可以有字段,并且自动属性不会't need to be reimplemented. You can also specify access specifiers that aren' t public . 此外,它具有更好的可伸缩性(例如,您可以使用 [Obsolete] 来标记旧的实现,然后默认调用旧的实现) . 此外,它将阻止您再继承类 . 另一件事是你可以在抽象类中设置静态字段 .

    此外,接口通常是 performs 一个动作,而类是 being .

  • 0
    *1) What if you had an Abstract class with only abstract methods? How would that be different from an interface?*
    

    默认情况下,接口中的方法是“公共抽象”,抽象类也将抽象方法称为“公共抽象” . 如果抽象类只包含抽象方法,那么最好将它作为一个接口 .

    *2) What if you had a Public variable inside the interface, how would that be different than in Abstract Class?*
    

    接口不能有变量 . 如果您的意思是属性,事件,代表等......它们默认为“公共” . 如果抽象类中没有指定任何内容,那么它将是“Private”(仅针对接口/抽象类的成员) .

  • 2

    在抽象类的情况下 .

    class Dog : abstractAnimal
    

    当我们创建Dog的对象时,我们将不得不创建abstractAnimal的对象,它将导致额外的对象创建 .

    在接口的情况下 .

    class Dog : IAnimal
    

    当我们创建Dog的对象时,我们不会创建任何任何额外的对象 .

  • 3

    在这种情况下,你可以说:

    1)我们可以为类中存在的方法指定不同的访问修饰符,但是我们不能更改Interface成员的访问修饰符 . 2)摘要中的派生类不会强制执行 .

相关问题