当前位置: 首页 > backend >正文

20250530-C#知识:抽象类、抽象方法、接口

C#知识:抽象类、抽象方法、接口

在开发过程中接口一般用得较多,程序框架往往定义一堆接口规范,然后程序员自己写逻辑来实现接口功能。掌握接口的知识还是很有必要的。


1、抽象类

  • 用abstract关键字修饰的类
  • 不能用来实例化对象
  • 可以包含抽象方法及普通方法,声明抽象方法时要加上abstract关键字
  • 继承抽象类必须重写其所有抽象方法
  • 抽象类变量容器可以装载子类对象
  • 抽象类主要是用来定义类规则的,子类来定义具体实现
    //动物就适合定义为抽象类,因为世界上并不存在名字叫动物的生物abstract class Animal{public string name;public Animal() { this.name = ""; }public Animal(string name) => this.name = name;public abstract void Eat();}

2、抽象方法

  • 用abstract修饰的方法
  • 只能在抽象类中声明
  • 在抽象类中声明的抽象方法没有方法体语句块
  • 不能是private,可以是protected
  • 继承抽象类的子类必须重写父类的抽象方法,加上override关键字
public abstract void Eat();

3、virtual方法 VS abstract方法

  • 两者都可以被子类无限重写
  • virtual方法可以有方法体,但abstract方法没有
  • 子类可以不重写父类的virtual方法,但必须重写父类的abstract方法

4、接口

  • 用interface关键字,与类声明类似
  • 接口本质是一组行为的规范
  • 接口不能实例化对象,但是可以用接口容器变量装载子类对象
    interface IMove2{void Move();}
  • 可以继承多个接口

  • 接口中不能包含成员变量

  • 接口只包含方法、属性、索引器、事件,子类必须实现接口中所有成员

  • 接口中的成员没有实现,具体实现由实现接口的类来完成

  • 接口可以继承接口

  • 接口中成员可以不加访问修饰符,只能是public的*

  • 类继承接口后,必须实现接口中所有成员,且访问权限为public

  • 接口继承接口本质是行为规范的合并,不用实现接口中的方法

  • 实现接口的方法,可以加上virtual关键字在子类中重写

  • 接口命名规范一般是IXxx

  • 接口中的方法可以重载,子类必须实现所有重载方法

    interface IMove{float Speed{get;set;}float this[int idx] { get;set;}void Move();void Move(float speed);Action MyEvent();}

5、显式实现接口

  • 若同时继承多个接口,接口中有同名方法,则需要显式实现接口
  • 显式实现接口不能写访问修饰符
  • 语法为:接口名.方法名
    class BadPlane : IMove, IMove2{void IMove.Move(){Console.WriteLine("一号龟速飞行");}void IMove2.Move(){Console.WriteLine("2号龟速飞行");}}
            IMove badPlane = new BadPlane();IMove2 badPlane2 = new BadPlane();badPlane.Move();    //一号龟速飞行badPlane2.Move();   //2号龟速飞行

6、接口VS抽象类

  • 可以实现多个接口、但只能继承一个抽象类
  • 接口中的方法都是抽象方法,抽象类可以包含抽象方法和普通方法
  • 接口中的方法默认访问权限为public,而抽象类中的方法必须加上访问修饰符
  • 接口不能有成员变量、构造函数,而抽象类可以有
  • 重写抽象方法要加override关键字,而实现接口方法不用
  • 优先组合而非继承,尽量用接口定义行为,避免复杂的类继承

7、完整代码示例:

namespace LearnAbstractAndinterface
{//飞机和人有移动方法,但是飞机和人之间没有继承关系,这里就可以用接口interface IMove{float Speed{get;set;}float this[int idx] { get;set;}void Move();void Move(float speed);Action MyEvent();}interface IMove2{void Move();}//动物就适合定义为抽象类,因为世界上并不存在名字叫动物的生物abstract class Animal{public string name;public Animal() { this.name = ""; }public Animal(string name) => this.name = name;public abstract void Eat();}class Person : Animal, IMove{public float Speed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }public float this[int idx] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }public Person() => this.name = "张飞";public Person(string name):base(name) { }public void Move(){Console.WriteLine("步行");}public override void Eat(){Console.WriteLine("吃隆江猪脚饭");}public void Move(float speed){throw new NotImplementedException();}public Action MyEvent(){throw new NotImplementedException();}}class Rabbit : Animal, IMove{public float Speed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }public float this[int idx] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }public Rabbit() => this.name = "流氓兔";public Rabbit(string name) : base(name) { }public void Move(){Console.WriteLine("跳");}public override void Eat(){Console.WriteLine("吃胡萝北");}public void Move(float speed){throw new NotImplementedException();}public Action MyEvent(){throw new NotImplementedException();}}class Plane : IMove{public float this[int idx] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }public float Speed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }public virtual void Move(){Console.WriteLine("飞行");}public void Move(float speed){throw new NotImplementedException();}public Action MyEvent(){throw new NotImplementedException();}}class GoodPlane: Plane,IMove2{public override void Move(){Console.WriteLine("一号光速飞行,免费");}void IMove2.Move(){Console.WriteLine("2号光速飞行,免费");}}class BadPlane : IMove, IMove2{public float this[int idx] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }public float Speed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }void IMove.Move(){Console.WriteLine("一号龟速飞行");}void IMove2.Move(){Console.WriteLine("2号龟速飞行");}public void Move(float speed){throw new NotImplementedException();}public Action MyEvent(){throw new NotImplementedException();}}internal class Program{static void Main(string[] args){Animal person = new Person();Animal rabbit = new Rabbit();person.Eat();   //吃隆江猪脚饭rabbit.Eat();   //吃胡萝北IMove person2 = new Person();   IMove rabbit2 = new Rabbit();IMove plane = new Plane();IMove goodPlane = new GoodPlane();person2.Move(); //步行rabbit2.Move(); //跳plane.Move();   //飞行goodPlane.Move();   //一号光速飞行,免费IMove2 goodPlane2 = new GoodPlane();IMove badPlane = new BadPlane();IMove2 badPlane2 = new BadPlane();goodPlane2.Move();  //2号光速飞行,免费badPlane.Move();    //一号龟速飞行badPlane2.Move();   //2号龟速飞行}}
}

8、参考资料

  1. 《唐老狮C#》

本篇结束,感谢您的阅阅阅阅阅阅读~

在这里插入图片描述

http://www.xdnf.cn/news/10191.html

相关文章:

  • nt!FsRtlFindLargeIndex函数分析计算在那个Mapping[(I)]数组中
  • 基于Java 实现 IM 业务回调
  • Java 之殇:从中流砥柱到“被温柔替代”
  • LeetCode Hot100(动态规划)
  • 04-redis-分布式锁-edisson
  • yum安装nginx后无法通过服务方式启动
  • 企业知识库问答系统避坑指南:检索优化与生成一致性解决方案
  • [ctfshow web入门] web80
  • 2.测试项目启动和研读需求文档
  • js 动画库、2048核心逻辑、面试题add[1][2][3]+4
  • Datatable和实体集合互转
  • 华锐视点助力,虚拟旅游绽放更璀璨光彩​
  • 图书管理系统的设计与实现
  • 北京大学肖臻老师《区块链技术与应用》公开课:06-BTC-网络
  • canoe 排查配置相关【graphics,capl】
  • Python基本运算符
  • python装饰器
  • DSP处理数字信号做什么用的?
  • Unsafe.putOrderedInt与Volatile
  • 驱动灯珠芯片LT3743手册理解
  • phpmyadmin
  • RTOS:启动调度器的作用(含源码逐行解读)
  • 微信小店推客系统达人用户管理的数据支持和便利
  • 【仿生机器人】Alice计划——仿生机器人需求
  • ABB HIEE300690R0001 AR C093 AE01 励磁调节器 PCB板特价
  • 第六十一节:深度学习-使用 OpenCV DNN 模块
  • 江科大SPI串行外设接口hal库实现
  • Linux 1.0.4
  • [硬件选型篇] 一文解决常用5V转3.3V电路选型困难(包括各选型的优缺点、纹波、效率等)
  • DAY 15 复习日