本文主要给大家详细介绍C#抽象类与接口的区别及应用场合。

一、抽象类

一句话说重点:抽象是为了繁衍更多的子孙后代,充当类继承时的祖宗(第一代)。
抽象类,说道抽象一词,大概大家就已经顾名思义了,不就是不把事情说具体的类吗,具体来说就是不用把属性、方法、事件等说清楚的类吗?是的!

1、一个普通的抽象类的定义

我们来具体看看一个简单的抽象类:

    abstract class Human{public string name;public int age;public void  showBaseInfo(){ } public void showFullInfo(){ }public void doSomething() { }}

这就是一个抽象类,方法没有任何实现(注意这里这些方法都是一些普通的方法,只是没有实现方法体而已)。那它究竟能不能去具体实现呢?我们试试看,定义一个实现了方法体的doSomething试试看,会不会报错呢?

 abstract class Human{public string name;public int age;public Human(string name){this.name = name;this.age = 0;}public void  showBaseInfo(){ } public void showFullInfo(){ }public void doSomething() {Console.WriteLine("let me do something!");}}

编译以后,没有发现他报错,那说明是可以实现的啊。到目前为止,我们还没有找到抽象类的本质,它和有不有方法体没有一毛钱关系。那说明实不实现具体的方法和属性体内容这不是抽象类这个“抽象”一词的本质啊! 我们回忆一下,这个抽象类的最大特点是什么?难道是继承,是继承的时候有什么特点吗?我们来看看继承
总结:
实不实现具体的方法和属性体不是抽象类的特点

2、抽象类的继承

下面,我们用设计的抽象类来实现继承,我们设计两个子类来继承Human类:

using System;namespace ConsoleApp1
{class Program{static void Main(string[] args){Author ar = new Author("Tom");Reader rdr = new Reader("Jack");Console.WriteLine(ar.name);Console.WriteLine(rdr.name);ar.doSomething();rdr.doSomething();}}public abstract class Human{public string name;public int age;public Human(string name){this.name = name;this.age = 0;}public void  showBaseInfo(){ } public void showFullInfo(){ }public void doSomething() {Console.WriteLine(this.name+": let me do something!");}}public class Author:Human{public Author(string name) : base(name) { }}public class Reader : Human{public Reader(string name) : base(name) { }}}

运行结果如下图:

经过上面的测试我们发现,抽象类的继承和普通的类的继承没有发现有任何一样啊,那么抽象类的抽象不是继承上有特点吧!那是什么呢?

3、给抽象类定义抽象函数

如果我们给抽象类设计一个抽象方法mustDo,那会怎样呢?

using System;namespace ConsoleApp1
{class Program{static void Main(string[] args){Author ar = new Author("Tom");Reader rdr = new Reader("Jack");Console.WriteLine(ar.name);Console.WriteLine(rdr.name);ar.doSomething();rdr.doSomething();ar.mustDo();rdr.mustDo();}}///public abstract class Human{public string name;public int age;public Human(string name){this.name = name;this.age = 0;}public void  showBaseInfo(){ } public void showFullInfo(){ }public void doSomething() {Console.WriteLine(this.name+": let me do something!");}public abstract void mustDo();    //****子类必须override来实现public virtual void OtherFun(){ } //*****子类不必理会}
///public class Author:Human{public Author(string name) : base(name) { }public override void mustDo(){Console.WriteLine(name + ": must do!");// throw new NotImplementedException();}}/ public class Reader : Human{public Reader(string name) : base(name) { }public override void mustDo(){Console.WriteLine(name + ": must do!");//throw new NotImplementedException();}}}

在两个继承类中分别override后,运行程序:


特别注意的是,抽象类中定义的abstract方法必须在其子类中override,否则报错。这和虚拟virtual方法不同。

4、给抽象类定义抽象属性

既然能够定义抽象方法,我们来看看给抽象类添加抽象属性,我们给Human增加一个Name的抽象属性(注意抽象属性是不可以有get和set的访问器实现体的)

using System;namespace ConsoleApp2
{class Program{static void Main(string[] args){Author ar = new Author("Tom");Reader rdr = new Reader("Jack");Console.WriteLine(ar.Name);Console.WriteLine(rdr.Name);ar.doSomething();rdr.doSomething();ar.mustDo();rdr.mustDo();Console.Read();}}public abstract class Human{private  string name;public int age;public abstract string Name { get; set; } //注意抽象属性是不可以有get和set的访问器实现体的public Human(string name){this.name = name;this.age = 0;}public void showBaseInfo() { }public void showFullInfo() { }public void doSomething(){Console.WriteLine(this.name + ": let me do something!");}public abstract void mustDo();public virtual void OtherFun(){ }}public class Author : Human{private string _name;public Author(string name) : base(name) {this._name = name;}public override string Name{get { return this.name; }set { this._name = Name; }}public override void mustDo(){Console.WriteLine(Name + ": must do!");}}public class Reader : Human{private string name;public Reader(string name) : base(name) {this._name = name;}public override string Name{get { return this._name; }set { this._name = Name; }}public override void mustDo(){Console.WriteLine(Name + ": must do!");}}}

编译后运行,一切正常,看来抽象类还是可以属性为抽象属性的。

4、给普通类不能定义抽象函数

我们可以试试,我们在继承自Human的子类Author类中定义一个抽象方法,结果编辑器提示错误:

总结:
抽象类之所以叫做抽象类,是因为在抽象类中可以声明抽象函数和抽象属性
整明白了抽象类,我们可以来看看接口了。

接口

一句话说重点:接口是一种规范,规范的对象自然是类。
我们都知道,生活中存在各种接口,电缆接口,USB接口,水管接口等等,各种接口功能都只有一个,那就是对接。那么涉及到对接,那就必须约定要对接的规范(如开口型号),放在我们的程序中也是一模一样,接口的功能也是负责对接,所以接口就必须约定要对接的规范,也就是说接口是约定对接规范的一种文档。

1、定义方法(规范方法)

我们来看看最简单的接口:

interface Creature{void Eat();void Walk(int distance);string Vocalize();}

我们为这个接口定义了三个方法,严格的说就是方法头,这和C语言及C++中的头文件中的定义貌似一样。

2、定义属性


编辑器直接报错,我们发现接口是不能定义字段的。和抽象类定义抽象属性一样,接口内定义属性一定要有获取器get和set,如下:

interface Creature{string Name { get; }void Eat();void Walk(int distance);string Vocalize();}interface Mammal : Creature{int CId { get; set; }int Birthday { get; set; }double Weight { get; set; }void BirthBaby();}

3、让类继承接口(让接口规范类)

我们尝试让类来继承刚刚定义的接口,看看

public abstract class Human{private  string name;public int age;public abstract string Name { get; set; }public Human(string name){this.name = name;this.age = 0;}public void showBaseInfo() { }public void showFullInfo() { }public void doSomething(){Console.WriteLine(this.name + ": let me do something!");}public abstract void mustDo();public virtual void OtherFun(){ }}/接口的定义interface Creature{void Eat();void Walk(int distance);string Vocalize();}public class Author : Human,Creature{private string name;public Author(string name) : base(name) {this.name = name;}public void Eat(){  }public void Walk(int distanc){   }public string Vocalize(){return "hoo~~~";}public override string Name{get { return this.name; }set { this.name = Name; }}public override void mustDo(){Console.WriteLine(Name + ": must do!");}           }

这里注意:
如果,一个类继承了接口,那么该接口中的所有方法都必须在继承的类中实现,否则报错。
换句话说,既然一个类宣布了接收某个接口的规范,那么每一条都要遵守,不能忽略任意一条。

总结:
接口的规范可以对类的属性、方法、事件、索引进行规范,也就是说接口中可以有属性、方法、事件、索引。

4、接口也可以继承接口(规范的继承)

接口在继承接口的时候不需要实现父接口的方法,但结成子接口的类必须一口气将子接口和父接口中的方法全部实现,下面我们给Creature接口设计一个子接口Mammal :

interface Creature{void Eat();void Walk(int distance);string Vocalize();}interface Mammal : Creature{void BirthBaby();}public abstract class Human{private  string name;public int age;public abstract string Name { get; set; }public Human(string name){this.name = name;this.age = 0;}public void showBaseInfo() { }public void showFullInfo() { }public void doSomething(){Console.WriteLine(this.name + ": let me do something!");}public abstract void mustDo();public virtual void OtherFun(){ }}public class Author : Human, Mammal{private string name;public Author(string name) : base(name) {this.name = name;}public void BirthBaby() { }public void Eat(){  }public void Walk(int distanc){   }public string Vocalize(){return "hoo~~~";}public override string Name{get { return this.name; }set { this.name = Name; }}public override void mustDo(){Console.WriteLine(Name + ": must do!");}           }

很显然,我们如果让接口Mammal 继承了Creature接口,我们就要将他们两个接口中的所有方法都在继承类Author类中全部实现。否则报错!

5、关于接口的小总结

在本部分的一开始我们就说道,接口是为了规范类的,那么如何去规范呢?规范的法则条款我们是写入了接口中了,接受这个规范的类如何去使用它呢?那就像用继承类一样的语法来继承。
严格的说那不叫做继承,这是C#没有办法,只能通过类似类的继承的方法来实现了。因为刚好子类继承父类的时候也客观上遵守了父类的“基因”。但严格的说是类引用接口来规范了自己,既然是规范自己,那么可以引用多个规范。
就好比一个学校,有劳动规范,有学习规范、有教学规范、有生活规范等等。所以说,一个类可以接受任意多的接口来规范自己。一个接口也可以无限多次的继承接口。

三、接口和抽象类区别

1、可以用抽象类来规范类

抽象类的abstract方法继承它的子类也必须实现,那为什么不用抽象类来作规范呢?
答:其实抽象类的抽象方法的确有规范作用,但它是类,规范类这个工作,只有接口是专业的,术业有专攻嘛。抽象类在规范类方面还是业余了些,但你实在么有什么大的构架计划,也是可以用它起到一定的规范作用。

2、抽象类和接口的区别

抽象类和接口的区别主要有以下几点:
1、它们的派生类只能继承一个抽象但可以继承任意多个接口。
2、抽象类中可以定义成员的实现,但接口中只能定义,不可实现。
3、抽象类中可以包含字段、构造函数、析构函数、静态成员或常量等,接口中不可以。
4、抽象类中的成员可以是私有的(只要它们不是抽象的)、受保的、内部的或受保护的内部成员(受保护的内部成员只能在应用在程序的代码或派生类中访问),但接口中的成员默认是公共的,定义时不能加修饰符。

C#抽象类与接口的区别及应用场合相关推荐

  1. 不允许使用抽象类类型的对象怎么办_Java基础——面试官:你来说说抽象类和接口的区别...

    无论你是新手Java 程序员,还是老手程序员,可能在实际开发中很少自己写抽象类. 但是抽象类在某些时候的功能很强大,可以保证子类中百分百实现父类中的方法 -- 普通类的弊端,消除子类的冗余代码 -- ...

  2. php 抽象类 接口 区别,PHP中抽象类、接口的区别与选择分析

    本文实例分析了PHP中抽象类.接口的区别与选择.分享给大家供大家参考,具体如下: 区别: 1.对接口的使用是通过关键字implements.对抽象类的使用是通过关键字extends.当然接口也可以通过 ...

  3. C#中抽象类和接口的区别

    一.抽象类:       抽象类是特殊的类,只是不能被实例化:除此以外,具有类的其他特性:重要的是抽象类可以包括抽象方法,这是普通类所不能的.抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆 ...

  4. C#中抽象类和接口的区别与使用

    一.抽象类: 抽象类是特殊的类,只是不能被实例化:除此以外,具有类的其他特性:重要的是抽象类可以包括抽象方法,这是普通类所不能的.抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们.另外 ...

  5. 1.13 抽象类和接口的区别

    接口是一种特殊的抽象类,接口和抽象类的渊源颇深,有很大的相似之处,所以在选择使用谁的问题上很容易迷糊. 1)抽象类 在 Java 中,被关键字 abstract 修饰的类称为抽象类:被 abstrac ...

  6. C#抽象类与接口的区别【转】

    C#抽象类与接口的区别[转] 一.抽象类:      抽象类是特殊的类,只是不能被实例化(可以用派生类实例化基类对象):除此以外,具有类的其他特性:重要的是抽象类可以包括抽象方法(当然它可以有普通方法 ...

  7. 问题小结(二)——maven的核心功能、面向对象编程和面向接口编程的区别、抽象类和接口的区别等

    文章目录 1. Java创建对象有哪四种方式? 2. 什么是maven?maven的核心功能有哪些? 3. 什么是MVC?说说分层的好处. 4. Spring的两大核心技术是什么? 5. 什么是IOC ...

  8. Java11-day02【多态(成员访问、多态转型、内存图解)、抽象类(成员特点)、接口(成员特点)、类和接口的关系、抽象类和接口的区别、综合案例】

    视频+资料(工程源码.笔记)[链接:https://pan.baidu.com/s/1MdFNUADVSFf-lVw3SJRvtg   提取码:zjxs] Java基础--学习笔记(零起点打开java ...

  9. C++中的抽象类以及接口的区别联系

    一.抽象类和接口 抽象类: 抽象类是特殊的类,不能被实例化(将定义了纯虚函数的类称为抽象类):除此以外,具有类的其他特性: 重要的是抽象类可以包括抽象方法,这是普通类所不能的,但同时也能包括普通的方法 ...

最新文章

  1. leetcode算法题--调整数组顺序使奇数位于偶数前面
  2. python调用qq互联_Django项目中实现使用qq第三方登录功能
  3. win7mysql免安装版安装_win7下MySQL免安装版下载安装、配置与使用
  4. 鸿蒙开发者社区入口,鸿蒙OS 社区
  5. 介绍一下ajax后最好的返回结果的方式#34;Json#34;
  6. Java面试问题:新的任务提交到线程池,线程池是怎样处理
  7. matlab数据取整方法
  8. Ubuntu18.04版本安装ssh及连接ssh的常见问题
  9. Python实现自己的分布式区块链视频教程-张敏-专题视频课程
  10. 我们短暂的人类世和即将到来的算法世
  11. gps面积测量仪手机版下载安装_gps面积测量仪手机版下载-GPS距离面积测量仪 安卓版v3.5.7-PC6安卓网...
  12. Android跳转小项目-CHANGE页面-Recycylerview、List、Context(二)
  13. git glo_TWOdW,2011年8月31日:作者,演讲者,开发商Andy Glover
  14. 问农事 - 菜蔬作物的节令
  15. 【二手车交易价格预测】赛题理解
  16. 科学计算自由软件SCILAB
  17. 对代码规范性的一点切实感受
  18. cisco Linux SRv6 实战踩坑记录
  19. iTunes Converter for mac(音频格式转换工具)
  20. codeforces1407C Chocolate Bunny

热门文章

  1. 细分赛道下,若羽臣小体量,大挑战
  2. 图形学笔记(八)画一个可以由鼠标和键盘控制的立方体
  3. 苹果开发者后台的帮助文档
  4. 服务器防勒索病毒经验分享
  5. 深度解读数据管理葵花宝典-《DAMA-DMBOK2数据管理知识体系指南(第2版)》
  6. python爬虫我要个性网,获取头像
  7. vertx访问html,Vert.x-Web的讲授和使用(一)
  8. macOS Homebrew 安装 OpenCV 及切换版本【转】
  9. 性能测试框架gatling
  10. 十几亿用户中心系统架构,落地实践