Home  >  Article  >  Backend Development  >  Detailed explanation of the difference between abstract classes and interfaces in C#

Detailed explanation of the difference between abstract classes and interfaces in C#

黄舟
黄舟Original
2017-03-23 11:20:531510browse

本文主要介绍了C#中抽象类与接口的区别。具有很好的参考价值。下面跟着小编一起来看下吧

1.面向接口编程和面向对象编程是什么关系

首先,面向接口编程和面向对象编程并不是平级的,它并不是比面向对象编程更先进的一种独立的编程思想,而是附属于面向对象思想体系,属于其一部分。或者说,它是面向对象编程体系中的思想精髓之一。

2.接口的本质

接口,在表面上是由几个没有主体代码的方法定义组成的集合体,有唯一的名称,可以被类或其他接口所实现(或者也可以说继承)。它在形式上可能是如下的样子:

interface InterfaceName
{
 void Method1();
 void Method2(int para1);
 void Method3(string para2,string para3);
}

那么,接口的本质是什么呢?或者说接口存在的意义是什么。我认为可以从以下两个视角考虑:

1)接口是一组规则的集合,它规定了实现本接口的类或接口必须拥有的一组规则。体现了自然界“如果你是……则必须能……”的理念。

例如,在自然界中,人都能吃饭,即“如果你是人,则必须能吃饭”。那么模拟到计算机程序中,就应该有一个IPerson(习惯上,接口名由“I”开头)接口,并有一个方法叫Eat(),然后我们规定,每一个表示“人”的类,必须实现IPerson接口,这就模拟了自然界“如果你是人,则必须能吃饭”这条规则。

从这里,我想各位也能看到些许面向对象思想的东西。面向对象思想的核心之一,就是模拟真实世界,把真实世界中的事物抽象成类,整个程序靠各个类的实例互相通信、互相协作完成系统功能,这非常符合真实世界的运行状况,也是面向对象思想的精髓。

2)接口是在一定粒度视图上同类事物的抽象表示。注意这里我强调了在一定粒度视图上,因为“同类事物”这个概念是相对的,它因为粒度视图不同而不同。

例如,在我的眼里,我是一个人,和一头猪有本质区别,我可以接受我和我同学是同类这个说法,但绝不能接受我和一头猪是同类。但是,如果在一个动物学家眼里,我和猪应该是同类,因为我们都是动物,他可以认为“人”和“猪”都实现了IAnimal这个接口,而他在研究动物行为时,不会把我和猪分开对待,而会从“动物”这个较大的粒度上研究,但他会认为我和一棵树有本质区别。

现在换了一个遗传学家,情况又不同了,因为生物都能遗传,所以在他眼里,我不仅和猪没区别,和一只蚊子、一个细菌、一颗树、一个蘑菇乃至一个SARS病毒都没什么区别,因为他会认为我们都实现了IDescendable这个接口(注:descend vi. 遗传),即我们都是可遗传的东西,他不会分别研究我们,而会将所有生物作为同类进行研究,在他眼里没有人和病毒之分,只有可遗传的物质和不可遗传的物质。但至少,我和一块石头还是有区别的。

可不幸的事情发生了,某日,地球上出现了一位伟大的人,他叫列宁,他在熟读马克思、恩格斯的辩证唯物主义思想巨著后,颇有心得,于是他下了一个著名的定义:所谓物质,就是能被意识所反映的客观实在。至此,我和一块石头、一丝空气、一条成语和传输手机信号的电磁场已经没什么区别了,因为在列宁的眼里,我们都是可以被意识所反映的客观实在。如果列宁是一名程序员,他会这么说:所谓物质,就是所有同时实现了“IReflectabe”和“IEsse”两个接口的类所生成的实例。(注:reflect v. 反映  esse n. 客观实在)

Maybe you will think that my above example is nonsense, but this is exactly the meaning of the existence of interfaces. One of the core concepts of object-oriented thinking is called polymorphism. What is polymorphism? To put it bluntly, it means that similar things are treated uniformly without distinction at a certain granularityView layer. The reason why I dare to do this is because of the existence of interfaces. Like the geneticist, he understands that all organisms implement the IDescendable interface, so as long as it is an organism, it must have the Descend() method, so he can conduct unified research instead of studying each organism separately and eventually dying of exhaustion.

Maybe I can’t give you an intuitive impression of the nature and function of the interface here. Then in the following examples and analysis of several design patterns, you will more intuitively experience the connotation of the interface.

3. Overview of interface-oriented programming

So what is interface-oriented programming? My personal definition is: In system analysis and architecture, distinguish levels and dependencies. Each level does not directly provide services to its upper layer (that is, it is not directly instantiated in the upper layer) ), but by defining a set of interfaces, only expose its interface functions to the upper layer. The upper layer only relies on the interface for the lower layer, and does not rely on specific classes.

The benefits of doing this are obvious. First of all, it is great for system flexibility. When the lower layer needs to be changed, as long as the interface and interface function remain unchanged, the upper layer does not need to make any modifications. You can even replace the entire lower layer without changing the upper layer code, just like we replace a WD 60G hard drive with a Seagate 160G hard drive. There is no need to make any changes to other parts of the computer. Instead, we unplug the original hard drive and install the new hard drive. Just plug it in, because other parts of the computer do not rely on a specific hard disk, but only rely on an IDE interface. As long as the hard disk implements this interface, it can be replaced. From here, the interface in the program is very similar to the interface in reality, so I always think that the word interface is really similar!

Another advantage of using interfaces is that developers of different components or levels can start work in parallel. Just like those who build hard disks do not have to wait for those who build CPUs or monitors. As long as the interfaces are consistent and the design is reasonable, the complete Development can be done in parallel, increasing efficiency.

Supplement to this article:

1. About the "interface" in "interface-oriented programming" and specific object-oriented languages The word "interface" in the middle

I saw a friend suggest that the word "interface" in "interface-oriented programming" should have a wider scope than the word "interface" in a simpleprogramming language . After thinking about it, I think it makes sense. What I wrote here is indeed unreasonable. I think "interface" in object-oriented languages ​​refers to a specific code structure, such as the interface defined with the interface keyword in C#. The "interface" in "interface-oriented programming" can be said to refer to a structural component that is used to hide specific underlying classes and implement polymorphism from a software architecture perspective and from a more abstract level. In this sense, if an abstract class is defined and the purpose is to achieve polymorphism, then I think it is reasonable to call this abstract class an "interface". But is it reasonable to use abstract classes to implement polymorphism? Discussed in the second article below.

In summary, I think the two concepts of "interface" are both different from each other and related to each other. The interface in "interface-oriented programming" is an architectural component at the ideological level used to achieve polymorphism and improve software flexibility and maintainability, while the "interface" in a specific language is a concrete component in this ideological level. Implemented into the code.

2. About abstract classes and interfaces

If you look at the specific code alone, it is easy to blur these two concepts, and even think that interfaces are redundant, because Judging from the specific functions alone, in addition to multiple inheritance (in C#, Java), abstract classes seem to be able to completely replace interfaces. But, does the interface exist to implement multiple inheritance? of course not. In my opinion, the difference between abstract classes and interfaces is the motivation for their use. The purpose of using abstract classes is for code reuse, while the motivation for using interfaces is to achieve polymorphism. So, if you are indecisive about whether to use an interface or an abstract class somewhere, think about your motivation.

I saw some friends questioning the IPerson interface. My personal understanding is that whether the IPerson interface should be defined depends on the specific application. If we have Women and Man in our project, both inherit Person, and most of the methods of Women and Man are the same, only one method DoSomethingInWC() is different (the example is rather vulgar, please forgive me), then of course it is more reasonable to define an AbstractPerson abstract class , because it can include all other methods, and the subclass only defines DoSomethingInWC(), which greatly reduces the amount of repeated code.

但是,如果我们程序中的Women和Man两个类基本没有共同代码,而且有一个PersonHandle类需要实例化他们,并且不希望知道他们是男是女,而只需把他们当作人看待,并实现多态,那么定义成接口就有必要了。

总而言之,接口与抽象类的区别主要在于使用的动机,而不在于其本身。而一个东西该定义成抽象类还是接口,要根据具体环境的上下文决定。

再者,我认为接口和抽象类的另一个区别在于,抽象类和它的子类之间应该是一般和特殊的关系,而接口仅仅是它的子类应该实现的一组规则。(当然,有时也可能存在一般与特殊的关系,但我们使用接口的目的不在这里)如,交通工具定义成抽象类,汽车、飞机、轮船定义成子类,是可以接受的,因为汽车、飞机、轮船都是一种特殊的交通工具。再譬如Icomparable接口,它只是说,实现这个接口的类必须要可以进行比较,这是一条规则。如果Car这个类实现了Icomparable,只是说,我们的Car中有一个方法可以对两个Car的实例进行比较,可能是比哪辆车更贵,也可能比哪辆车更大,这都无所谓,但我们不能说“汽车是一种特殊的可以比较”,这在文法上都不通。

C#.NET里面抽象类和接口有什么区别?

接口和抽象类的概念不一样。接口是对动作的抽象,抽象类是对根源的抽象。

抽象类表示的是,这个对象是什么。接口表示的是,这个对象能做什么。比如,男人,女人,这两个类(如果是类的话……),他们的抽象类是人。说明,他们都是人。

人可以吃东西,狗也可以吃东西,你可以把“吃东西”定义成一个接口,然后让这些类去实现它.

所以,在高级语言上,一个类只能继承一个类(抽象类)(正如人不可能同时是生物和非生物),但是可以实现多个接口(吃饭接口、走路接口)。

下面接着再说说两者在应用上的区别:

接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。

而抽象类在代码实现方面发挥作用,可以实现代码的重用

模板方法设计模式是抽象类的一个典型应用

最佳答案:

1抽象类

(1) 抽象方法只作声明,而不包含实现,可以看成是没有实现体的虚方法

(2) 抽象类不能被实例化

(3) 抽象类可以但不是必须有抽象属性和抽象方法,但是一旦有了抽象方法,就一定要把这个类声明为抽象类

(4) 具体派生类必须覆盖基类的抽象方法

(5) 抽象派生类可以覆盖基类的抽象方法,也可以不覆盖。如果不覆盖,则其具体派生类必须覆盖它们。如:

using System;
public abstract class A //抽象类A 
{ 
 private int num=0;
 public int Num //抽象类包含属性 
 { 
  get 
  { 
   return num; 
  } 
  set 
  { 
   num = value; 
  }   
 }
 public virtual int getNum() //抽象类包含虚方法 
 { 
  return num; 
 }
 public void setNum(int n) // //抽象类包含普通方法 
 { 
  this.num = n; 
 }
 public abstract void E(); //类A中的抽象方法E  
}
public abstract class B : A //由于类B继承了类A中的抽象方法E,所以类B也变成了抽象类 
{
}
public class C : B 
{ 
 public override void E() //重写从类A继承的抽象方法。如果类B自己还定义了抽象方法,也必须重写 
 { 
  //throw new Exception("The method or operation is not implemented."); 
 } 
}
public class Test 
{ 
 static void Main() 
 { 
  C c = new C(); 
  c.E(); 
 } 
}

二、接 口

(1) 接口不能被实例化

(2) 接口只能包含方法声明

(3) 接口的成员包括方法、属性、索引器、事件

(4) 接口中不能包含常量、字段(域)、构造函数、析构函数、静态成员。如:

public delegate void EventHandler(object sender, Event e);
public interface ITest 
{ 
 //int x = 0;
 int A 
 { 
  get; 
  set; 
 }
 void Test();
 event EventHandler Event; 
 int this[int index] 
 { 
  get;
  set; 
 } 
}

(5) 接口中的所有成员默认为public,因此接口中不能有private修饰符

(6) 派生类必须实现接口的所有成员

(7) 一个类可以直接实现多个接口,接口之间用逗号隔开

(8) 一个接口可以有多个父接口,实现该接口的类必须实现所有父接口中的所有成员

三、抽象类和接口

相同点:

(1) 都可以被继承

(2) 都不能被实例化

(3) 都可以包含方法声明

(4) 派生类必须实现未实现的方法

区 别:

(1) 抽象基类可以定义字段、属性、方法实现。接口只能定义属性、索引器、事件、和方法声明,不能包含字段。

(2) 抽象类是一个不完整的类,需要进一步细化,而接口是一个行为规范。微软的自定义接口总是后带able字段,证明其是表述一类“我能做。。。”

(3) 接口可以被多重实现,抽象类只能被单一继承

(4) 抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中

(5) Abstract class is a concept abstracted from a series of related objects, so it reflects the internal commonality of things; interface is a functional agreement defined to meet external calls, so it reflects the external characteristics of things.

(6) The interface basically does not have any specific characteristics of inheritance. It only promises methods that can be called

(7) The interface can be used to support callbacks, but inheritance does not have this Features

(8) The specific methods implemented by abstract classes are virtual by default, but the interface methods in the class that implements the interface are non-virtual by default. Of course, you can also declare them as virtual

(9) If the abstract class implements the interface, you can map the methods in the interface to the abstract class as abstract methods without having to implement them, and implement the methods in the interface in the subclass of the abstract class

The above is the detailed content of Detailed explanation of the difference between abstract classes and interfaces in C#. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn