.NET Core CSharp初级篇 1-5

本节内容类的接口、枚举、抽象

简介

问题

  • 如果你需要表示星期或者是某些状态,使用字符串或者数字是否不直观?
  • 你是否发现,无论何种电脑,它的USB口的设计都是遵循一定规范的?

枚举

枚举(enum)是一个非常好用的一个特殊值类型,他可以让你指定一系列字符常量(通常从0开始)。它的定义和使用如下:

public enum Week
{
Monday,
...//此处省略
Sunday = 6//可赋值
}
bool flag = (6 == (int)Week.Sunday)

不过你也可以指定其他的类型作为枚举的值,例如:

public enum Week:byte
{
Monday,
...
Sunday= 6
}

枚举与其他类型的转换使用强制类型转换即可,例如:(int)Week.Sunday,不过特别的,0不需要强制转换就可以和枚举进行比较。

Flag Enum

这是一个有趣的枚举,它支持你对枚举按位进行运算,使用flag enum需要在枚举名上面指定一个Attribute,也就是[Flags],通常来说,我们会使用2的幂作为枚举值,因为按位运算本质是2进制的运算。

具体实例如下

[Flags]
public enum Status
{
Success = 1,
NotFound = 2,
Fail = 4
}
//支持按位运算,运算步骤我们在之前已经有过详细的讲解
Status.Success | Status.NotFound

默认的,如果你输入了一个不合理的枚举值(也就是没定义),编译器会默认直接输出该数字,不过如果你使用了按位运算的枚举,那么他会将你输入的数字转换成二进制与每一个枚举值进行&运算,得出的结果会与枚举值进行比较,如果找到了就会输出。

例如以上例的Status:

Console.WriteLine((Status)7);
//输出是三个都输出
//7 = 0111,
//1 = 0001,
//2 = 0010
//4 = 0011

接口

接口这个东西,新手非常容易被误导,例如在WebApi开发中,你的前端朋友让你把接口给他,这个时候,他需要的东西在后端的口中叫做API,

当你的后端朋友说,你写一个接口,我们使用依赖注入进行统一管理实现了接口的类,这个时候,他需要的是一个约定,也是我们这里讲的接口(interface)。

接口是C#面向对象中实现多态的重要语法。接口的定义可以理解为是一种约定的规范。例如电脑的USB-A接口,全世界的厂商都是统一规范生产,如果大家不按着约定生产,后果会是什么?

在C#中,接口也一样起到了这个作用,但是还有一些更为广泛的应用。

接口的定义使用interface关键字,默认的,所有接口的成员的访问权限都是public,因为规范是需要公布给所有人看,如果定义了访问权限就没有实际的意义了

,并且接口中所有的函数都不存在函数体。总的来说就是,接口是一个提供类的规格的东西,却不提供实现。

接口的例子

//定义一个接口
public inteface IHuman
{
void Eat();
bool Alive();
}
//接口的实现,必须实现每一个接口中的函数并保持返回类型、函数签名,函数参数一致
public class Human:IHuman
{
void Eat()
{ }
bool Alive()
{
return default<bool>();
}
}

接口的实现会和我们后面讲到的继承非常相似,在这里,你只需要记住接口支持一个类实现多个接口,但只能继承一个类即可。

接口冲突

因为支持一个类实现多个接口,那么很有可能会造成A接口中拥有和B接口中完全一致的函数,这个时候我们就需要使用显式实现接口进行处理。

当你需要调用不同接口的同签名方法时,使用接口进行强制转换即可。

例如:

interface IApple
{
void Wash();
}
interface IFruit
{
void Wash();
}
class test : IApple,IFruit
{
void IApple.Wash()=>{};
void IFruit.Wash()=>{};
}
test t= new test();
((IApple)t).Wash();
((IFruit)t).Wash();

这样就可以避免接口在命名上的冲突。

并且接口如果你隐式的实现,所有接口函数默认都是sealed的。

如果存在一个多继承的问题,这个可能目前讲起来为之过早,我就顺口提一下,例如,人类继承与动物类,动物继承于生物接口,

那么对于人类,是隐式的继承了生物接口,但是对于人类和动物,进食的方式有很大区别,那么我们就应该重写进食这个方法。

我们就要把基类(父类)中的接口函数标记为virtual或者abstract,然后在子类中使用override进行重写。

这就已经说的太远了,后面我们会进行深入的刨析。

抽象

抽象可以有抽象字段、抽象类、抽象委托、抽象函数等等。我们就以其中常用的抽象函数和抽象类做一个解析。

抽象和接口非常相似,抽象类不能被实例化,抽象方法没有方法体,都是依赖子类(被继承类)进行操作。

抽象函数

这个就和接口几乎一模一样,也没有太多讲的必要,如果你声明了一个函数是抽象函数,那么它不存在方法体,你需要通过子类去重写(override)实现。

在实际应用中,子类仅能重写父类中的虚方法或者抽象方法,当不需要使用父类中方法的内容时,将其定义成抽象方法,否则将方法定义成虚方法。

抽象类

"一个包含一个或多个纯虚函数的类叫抽象类,抽象类不能被实例化,进一步

一个抽象类只能通过接口和作为其它类的基类使用."

一个抽象类可以包含抽象和非抽象方法,当一个类继承于抽象类,那么这个派生类必须实现所有的

的基类抽象方法。

但是通过声明派生类也为抽象,我们可以避免所有或特定的虚方法的实现,

这就是抽象类的部分实现。

看起来很高深?事实上抽象类就是一个提供了有部分没有方法体的函数和有具体实现的函数的集合。它相比于接口毫无实现而言,抽象类可以提供非抽象的方法,也就是说,抽象类中可以含有有实现方法的函数。

看这个例子

public abstract class A
{
public void GetSomeThing()
{
//todo
}
public abstract void SetSomeThing();
}
public class B:A
{
//实现抽象方法
public override void SetSomeThing()
{
//调用非抽象方法
base.GetSomeThing();
} }

这里面涉及到了base关键字以及":"继承符号,在后面的继承、多态的课程有会有更加深入的介绍。

Github

BiliBili主页

WarrenRyan's Blog

博客园

.NET Core CSharp初级篇 1-5 接口、枚举、抽象的更多相关文章

  1. NET Core CSharp初级篇 1-3面向对象

    .NET Core CSharp初级篇 1-3 本节内容为面向对象初级教程 类 简介 面向对象是整个C#中最核心最有特色的一个模块了,它很好的诠释了程序与现实世界的联系. 面向对象的三大特征:继承.多 ...

  2. .NET Core CSharp初级篇 1-6 类的多态与继承

    .NET Core CSharp初级篇 1-6 本节内容为类的多态与继承 简介 终于讲到了面向对象三大特性中的两大特性--继承与多态.通过继承与多态,我们能很好的将类的拓展性发挥到了极致.在下面的内容 ...

  3. .NET Core CSharp初级篇 类的生命历程

    .NET Core CSharp初级篇 1-7 本节内容为类的生命周期 引言 对象究竟是一个什么东西?对于许多初学者而言,对象都是一个非常抽象的知识点.如果非要用一句话描述,我觉得"万物皆对 ...

  4. .NET Core CSharp初级篇 1-8泛型、逆变与协变

    .NET Core CSharp初级篇 1-8 本节内容为泛型 为什么需要泛型 泛型是一个非常有趣的东西,他的出现对于减少代码复用率有了很大的帮助.比如说遇到两个模块的功能非常相似,只是一个是处理in ...

  5. .NET Core CSharp初级篇 1-2 循环与判断

    .NET Core CSharp初级篇 1-2 本节内容循环与判断 循环 循环是一个在任何语言都是极为重要的语法,它可以用于很多东西,例如迭代数组等等.在C#中,语法层面的循环有:for , fore ...

  6. .NET Core CSharp初级篇 1-1

    .NET Core CSharp初级篇 1-1 本节内容是对于C#基础类型的存储方式以及C#基础类型的理论介绍 基础数据类型介绍 例如以下这句话:"张三是一名程序员,今年15岁重50.3kg ...

  7. CSharp初级篇 1-4 this、索引器、静态、常量以及只读

    .NET Core CSharp初级篇 1-4 本节内容为this.索引器.静态.常量以及只读 简介 在之前的课程中,我们谈论过了静态函数和字段的一小部分知识,本节内容中,我们将详细的讲解关于对象操作 ...

  8. .NET Core CSharp 中级篇 2-2 List,ArrayList和Dictionary

    .NET Core CSharp 中级篇 2-2 本节内容为List,ArrayList,和Dictionary 简介 在此前的文章中我们学习了数组的使用,但是数组有一个很大的问题就是存储空间不足,我 ...

  9. .NET Core CSharp 中级篇 2-1 装箱与拆箱

    .NET Core CSharp 中级篇 2-1 本节内容为装箱与拆箱 简介 装箱和拆箱是一个相对抽象的概念.你可以想象一下一堆满载货物的大卡车,他是由许多工人将货物集中堆放装入的,对于我们而言在没有 ...

随机推荐

  1. Linux下如何查看高CPU占用率线程 专题

    Java 系统性能分析 命令 1. cpu分析 top , pidstat(sysstat) pid -p PID -t 1 10 vmstat 1 CPU上下文切换.运行队列.利用率 ps Hh - ...

  2. Qt 5.6.0 动态编译(VS2013 x86 target xp openssl icu webkit)

    经历了多次延期后,在3月16号,Qt发布了5.6.0版本(全面支持高DPI无疑是一个亮点),从5.6.0版本开始,Qt直接移除了webkit模块,让webengine作为其替代选择,不过webengi ...

  3. 代理Delegate的小应用(使用setModelData设置下拉日期对话框)

    前言 在平时关于表格一类的的控件使用中,不可避免需要修改每个Item的值,通过在Item中嵌入不同的控件对编辑的内容进行限定,然而在表格的Item中插入的控件始终显示,当表格中item项很多的时候,会 ...

  4. New,Getmem,ReallocMem联系与区别(转)

    procedure New(var P: Pointer);  {为一个指针变量分配内存,会自动计算指针所指数据结构需要空的空间大小} procedure GetMem(var P: Pointer; ...

  5. 使用熔断器仪表盘监控(hystrix)

    概述 在 Ribbon 和 Feign 项目增加 Hystrix 仪表盘功能,两个项目的改造方式相同. 在 pom.xml 中增加依赖 <dependency> <groupId&g ...

  6. spring boot单元测试之RestTemplate(一)

    写代码重要,写好的代码准确无误,且符合预期那更是必不可少. spring boot内嵌了专门的单元测试模块——RestTemplate,保证了程序员可以对自己的代码进行及时的测试. 闲言少叙,直接上代 ...

  7. 面试官:你了解过Redis对象底层实现吗

    上一章我们讲了Redis的底层数据结构,不了解的人可能会有疑问:这个和平时用的五大对象有啥关系呢?这一章我们就主要解释他们所建立的联系. 看这个文件之前,如果对ziplist.skiplist.int ...

  8. Free MP3 CD Ripper_缓冲区溢出远程代码执行_CVE-2019-9766漏洞复现

    Free MP3 CD Ripper_缓冲区溢出远程代码执行_CVE-2019-9766漏洞复现 一.漏洞描述 Free MP3 CD Ripper是一款音频格式转换器.Free MP3 CD Rip ...

  9. Python自学day-7

    一.静态方法(@staticmethod) class Dog(object): def __init__(self): pass @staticmethod def talk(): #静态方法 pa ...

  10. spring cloud 系列第2篇 —— eureka 高可用注册中心的搭建 (F版本)

    源码仓库地址:https://github.com/heibaiying/spring-samples-for-all 一.项目结构 eureka-server为服务注册中心,负责服务的管理: eur ...