C#抽象类与接口的区别及应用场合
本文主要给大家详细介绍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#抽象类与接口的区别及应用场合相关推荐
- 不允许使用抽象类类型的对象怎么办_Java基础——面试官:你来说说抽象类和接口的区别...
无论你是新手Java 程序员,还是老手程序员,可能在实际开发中很少自己写抽象类. 但是抽象类在某些时候的功能很强大,可以保证子类中百分百实现父类中的方法 -- 普通类的弊端,消除子类的冗余代码 -- ...
- php 抽象类 接口 区别,PHP中抽象类、接口的区别与选择分析
本文实例分析了PHP中抽象类.接口的区别与选择.分享给大家供大家参考,具体如下: 区别: 1.对接口的使用是通过关键字implements.对抽象类的使用是通过关键字extends.当然接口也可以通过 ...
- C#中抽象类和接口的区别
一.抽象类: 抽象类是特殊的类,只是不能被实例化:除此以外,具有类的其他特性:重要的是抽象类可以包括抽象方法,这是普通类所不能的.抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆 ...
- C#中抽象类和接口的区别与使用
一.抽象类: 抽象类是特殊的类,只是不能被实例化:除此以外,具有类的其他特性:重要的是抽象类可以包括抽象方法,这是普通类所不能的.抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们.另外 ...
- 1.13 抽象类和接口的区别
接口是一种特殊的抽象类,接口和抽象类的渊源颇深,有很大的相似之处,所以在选择使用谁的问题上很容易迷糊. 1)抽象类 在 Java 中,被关键字 abstract 修饰的类称为抽象类:被 abstrac ...
- C#抽象类与接口的区别【转】
C#抽象类与接口的区别[转] 一.抽象类: 抽象类是特殊的类,只是不能被实例化(可以用派生类实例化基类对象):除此以外,具有类的其他特性:重要的是抽象类可以包括抽象方法(当然它可以有普通方法 ...
- 问题小结(二)——maven的核心功能、面向对象编程和面向接口编程的区别、抽象类和接口的区别等
文章目录 1. Java创建对象有哪四种方式? 2. 什么是maven?maven的核心功能有哪些? 3. 什么是MVC?说说分层的好处. 4. Spring的两大核心技术是什么? 5. 什么是IOC ...
- Java11-day02【多态(成员访问、多态转型、内存图解)、抽象类(成员特点)、接口(成员特点)、类和接口的关系、抽象类和接口的区别、综合案例】
视频+资料(工程源码.笔记)[链接:https://pan.baidu.com/s/1MdFNUADVSFf-lVw3SJRvtg 提取码:zjxs] Java基础--学习笔记(零起点打开java ...
- C++中的抽象类以及接口的区别联系
一.抽象类和接口 抽象类: 抽象类是特殊的类,不能被实例化(将定义了纯虚函数的类称为抽象类):除此以外,具有类的其他特性: 重要的是抽象类可以包括抽象方法,这是普通类所不能的,但同时也能包括普通的方法 ...
最新文章
- leetcode算法题--调整数组顺序使奇数位于偶数前面
- python调用qq互联_Django项目中实现使用qq第三方登录功能
- win7mysql免安装版安装_win7下MySQL免安装版下载安装、配置与使用
- 鸿蒙开发者社区入口,鸿蒙OS 社区
- 介绍一下ajax后最好的返回结果的方式#34;Json#34;
- Java面试问题:新的任务提交到线程池,线程池是怎样处理
- matlab数据取整方法
- Ubuntu18.04版本安装ssh及连接ssh的常见问题
- Python实现自己的分布式区块链视频教程-张敏-专题视频课程
- 我们短暂的人类世和即将到来的算法世
- gps面积测量仪手机版下载安装_gps面积测量仪手机版下载-GPS距离面积测量仪 安卓版v3.5.7-PC6安卓网...
- Android跳转小项目-CHANGE页面-Recycylerview、List、Context(二)
- git glo_TWOdW,2011年8月31日:作者,演讲者,开发商Andy Glover
- 问农事 - 菜蔬作物的节令
- 【二手车交易价格预测】赛题理解
- 科学计算自由软件SCILAB
- 对代码规范性的一点切实感受
- cisco Linux SRv6 实战踩坑记录
- iTunes Converter for mac(音频格式转换工具)
- codeforces1407C Chocolate Bunny