浅谈接口、抽象类、抽象方法和虚方法的区别

开发 后端
本文主要介绍的了接口、抽象类、抽象方法和虚方法的区别,结合实际例子,为大家清楚的介绍了。希望对大家有帮助,一起来看。

C#抽象类接口孩子间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,因此很多开发者在进行抽象类定义时对于抽象类和接口的选择显得比较随意。其实,两者之间还是有很大区别的。

首先说一下接口与抽象类的异同:

相同点:

1.他们都不能实例化自己,也就是说都是用来被继承的。

2.抽象类中的抽象方法和接口方法一样,都不能有方法体

不同点:

1.抽象类里可以有字段,接口中不能有字段.

2.抽象类中的普通方法可以有方法体,而接口方法没有方法体。

3.接口中的方法不能有访问修饰符,抽象类中的抽象方法被继承,需要override重写 .

4.接口更像是一种规范,一种约束。

5.一个子类只能继承一个抽象类,但却可以继承多个接口。

接下来是抽象方法和虚方法的异同:

其实可以把抽象方法看做是没有方法体的虚方法。

相同点:

1.抽象方法和虚方法都可以被重写。

不同点

1.abstract 和virtual的关键字不同

2.抽象方法一定没有方法体,而虚方法可以有方法体。

下面写个例子说明一下:

 

/// <summary>  
/// 一个手机的抽象类  
/// </summary>  
public abstract class Mobilephone   
{  
private string _logo;  
public string Logo  
{  
get { return _logo; }  
set { _logo = value; }  
}  
public abstract void Call();  
public virtual void Callagain()   
{  
Console.WriteLine("我再打一个电话");  
}  
}  
/// <summary>  
/// 定义一个实体类,继承了一个抽象类及多个接口  
/// </summary>  
public class Nokia :Mobilephone,IClock,Ilistenmusic  
{  
public override void Call()  
{  
Console.WriteLine("NOKIA打电话没问题");  
}  
public void clock()  
{  
Console.WriteLine("NOKIA的手机也有闹钟功能");  
}  
public void listenmusic()  
{  
Console.WriteLine("NOKIA的手机还能听歌");  
}  
public override void Callagain()   
{  
Console.WriteLine("算了,还是不打了");  
}  
}  
/// <summary>  
/// 下面定义了两个接口,为了说明可以继承多个接口  
/// </summary>  
public interface Ilistenmusic   
{  
void listenmusic();  
}  
public interface IClock   
{  
void clock();  
}  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.

 

在补充一个小例子,

这里有到很有意思的面试题,说名了new关键字和override的区别:

 

class Program   
{   
static void Main(string[] args)   
{   
B5 b5 = new B5();   
b5.MethodB();   
}   
}   
public class A5   
{   
public virtual void MethodA()   
{   
Console.WriteLine("A5.MethodA");   
Console.Read();   
}   
public virtual void MethodB()   
{   
MethodA();   
}   
}   
public class B5 :A5   
{   
public new void MethodA()   
{   
Console.WriteLine("B5.MethodA");   
Console.ReadLine();   
}   
}   
class Program  
{  
static void Main(string[] args)  
{  
B5 b5 = new B5();  
b5.MethodB();  
}  
}  
public class A5  
{  
public virtual void MethodA()  
{  
Console.WriteLine("A5.MethodA");  
Console.Read();  
}  
public virtual void MethodB()  
{  
MethodA();  
}  
}  
public class B5 :A5  
{  
public new void MethodA()   
{  
Console.WriteLine("B5.MethodA");  
Console.ReadLine();  
}  
}  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.

 

***的答案是:"A5.MethodA"

【编辑推荐】

  1. 分享c#常用函数和方法集
  2. c#.net实体类序列化方法
  3. C#中的闭包是怎么捕获变量的
  4. 解析C#委托、时间和Lambda表达式
  5. 用C#实现HTTP协议下的多线程文件传输
责任编辑:于铁 来源: 超级兔子
相关推荐

2009-08-10 10:04:25

C#抽象类C#接口

2011-07-12 15:58:48

java抽象类接口

2009-04-30 15:15:01

Java抽象类接口

2011-05-19 18:01:56

JAVA

2011-07-06 10:33:31

C#

2011-07-10 14:07:59

JAVA

2009-06-16 11:30:00

Java抽象类Java接口

2009-06-14 21:31:29

Java抽象类Java接口

2011-12-22 10:48:21

Java

2022-04-06 09:10:03

抽象类型普通类型Swift

2012-02-29 09:32:01

Java

2010-03-04 09:40:04

Java接口抽象类

2021-12-23 07:11:31

开发

2020-10-19 13:03:16

Java 8接口抽象类

2009-07-30 18:36:00

C#接口C#抽象类

2015-03-23 09:33:43

Java抽象类Java接口Java

2010-07-06 08:58:52

UML图表达C++

2009-08-14 15:54:17

C#接口和抽象类

2009-08-03 18:12:31

C#抽象类

2023-09-07 13:24:00

C++编程
点赞
收藏

51CTO技术栈公众号