C# 抽象类与接口

news/2024/11/15 8:40:37/

        抽象类接口是C#“封装、继承、多态”三大特性中比较重要的组成部分。抽象类和接口这两种类型用于完全不同的目的。抽象类主要用作对象的基类,贡献某些主要的特性,例如共同的目的和结构。接口则主要是用于类,为这些类去添加不同的方法(行为)。下面分别对它们的概念,代码定义,特点区别,应用场景进行说明。

概念

抽象类概念

        抽象类是一种不能被实例化的类,用于作为其他类的基类。它可以包含抽象方法、非抽象方法、字段、属性等成员,用于定义一种通用的类结构和行为,而具体的实现则留给其派生类来完成。

接口概念

        接口是从抽象类演变而来的,接口是一种定义了一组方法、属性、事件或索引器的规范,用于描述类应该具有的行为和功能。类可以实现一个或多个接口,从而遵循接口定义的规范。

代码定义

抽象类定义

        抽象类在C#中通过abstract关键字来声明。

    internal abstract class Animal{//抽象属性声明不提供属性访问器的实现,它声明该类支持属性,而将访问器实现留给派生类public abstract double height { get; }//普通属性public  double weidth { get; set; }//普通字段public  double age;//抽象方法public abstract void Run();//普通方法public void Eat(){Console.WriteLine("Animal can eat.");}//虚方法,子类继承重写public virtual void Move(){Console.WriteLine("Animal can move.");}}internal class Dog : Animal{private double _height;public override double height{get => _height;}public Dog(){_height = 200;}//抽象方法子类必须重写public override void Run(){Console.WriteLine("Dog can run.");}//虚方法子类可以重写也可单继承public override void Move(){Console.WriteLine("Animal move by leg.");}}void Main(){Dog dog = new Dog();Animal animal = dog;animal.weidth = 50;animal.age = 10;animal.Run();Console.WriteLine($"Dog's age->{dog.age},width->{dog.weidth},height->{dog.height}");Console.ReadLine();}

   运行结果为:

Dog can run.
Dog's age->10,width->50,height->200

接口定义

        接口在C#中通过interface关键字来声明。

    public  interface FlyInterface{//属性string Name { get; }//委托和事件event EventHandler Clicked;void Fly();void Move();}public interface RunInterface{void Run();void Move();}//可以继承多个接口internal class Plane : FlyInterface, RunInterface{public string Name => "Play";public event EventHandler Clicked;/*如果类实现两个接口且两个接口包含具有相同签名的成员,显示接口实现是通过使用接口名称和一个句点命名该类成员来进行实现*/void FlyInterface.Move(){Console.WriteLine("Plane move by fly.");}void RunInterface.Move(){Console.WriteLine("Plane move by run.");}public void Fly(){Console.WriteLine("Plane can Fly.");}public void Run(){Console.WriteLine("Plane can Run.");}}void Main(){Plane plane = new Plane();FlyInterface fly = plane;fly.Fly();fly.Move();RunInterface run = plane;run.Run();run.Move();Console.ReadLine();}

   运行结果为:

Plane can Fly.
Plane move by fly.
Plane can Run.
Plane move by run.

特点区别

抽象类的特点

  • 不能被实例化: 抽象类不能被直接实例化,只能被用作其他类的基类。
  • 可以包含抽象方法: 抽象类中可以包含抽象方法,这些方法只有声明,没有实际实现。抽象方法用于强制派生类实现特定的行为。
  • 可以包含非抽象方法: 抽象类中也可以包含普通的非抽象方法,这些方法可以有默认的实现。
  • 可以包含字段和属性: 抽象类可以包含字段和属性,用于存储数据和提供接口。

接口的特点

  • 只能定义方法、属性、事件和索引器: 接口只能包含成员的声明,而不能包含具体的实现。
  • 不能包含字段: 接口不能包含字段,因为字段是具体的数据存储,而接口只定义行为。
  • 类可以实现多个接口: 一个类可以同时实现多个接口,从而具有多个不同的行为。
  • 类必须实现接口成员: 类实现接口后,必须提供接口中定义的所有成员的实现。

主要区别

  • 他们的派生类只能继承一个基类,即只能直接继承一个抽象类,但可以继承任意多个接口;
  • 抽象类中可以定义成员的实现,但接口中不可以;
  • 抽象类中可以包含字段、构造函数、析构函数、静态成员或常量等,接口中不可以;
  • 抽象类中的成员可以是私有的(只要他们不是抽象的)、受保护的、内部的或受保护的内部成员(受保护的内部成员只能在应用程序的代码或派生类中访问),但接口中的成员必须是公共的。

应用场景

抽象类应用场景

  • 当要定义一个类的通用结构和行为,并为派生类提供一些默认实现时,可以使用抽象类。
  • 当要强制派生类实现特定方法,但不需要强制实现所有方法时,可以将部分方法声明为抽象方法。
  • 当需要为基类提供一些具体的实现,但又希望派生类能够重写这些实现时,可以使用抽象类。

接口应用场景

  • 当需要定义一组方法、属性或事件,以实现不同类的多态性时,可以使用接口。
  • 当需要在不同的类中实现共同的行为,而这些类已经继承了其他类时,可以通过实现接口来避免多重继承带来的问题。
  • 当需要在一个类中实现多个不相关的功能时,可以通过实现多个接口来达到目的。

在选择使用抽象类还是接口时,需要根据具体的情况选择:

  • 如果想要定义一组相关的类,共享一些通用的实现,但又要求派生类实现特定的行为,可以使用抽象类。
  • 如果想要定义一组不相关的类,使它们实现共同的行为,可以使用接口。

补充说明

1、接口可以用于定义事件和委托的契约,使不同类能够统一实现事件和委托的处理

2、C#虚方法和抽象方法的区别

  • 抽象方法是只有方法名称,没有方法体,即没有方法的具体实现,子类必须重写父类抽象方法才能实现具体功能;虚函数有方法名称也也有方法体,但是子类可以覆盖,也可不覆盖。
  • 抽象方法是一种强制派生类覆盖的方法,否则派生类将不能被实例化。
  • 抽象方法只能在抽象类中声明,虚方法不是。
  • 派生类必须重写抽象类中的抽象方法,虚方法则不必要。

参考:

【C# 基础精讲】抽象类与接口_c#抽象类不能被实例化-CSDN博客

C#-抽象类与接口_c# 接口与抽象类-CSDN博客


http://www.ppmy.cn/news/1281679.html

相关文章

WPF StackPanel

StackPanel是一个控件容器,它按照一个方向(水平或垂直)堆叠子元素,使得它们沿一个轴线对齐。你可以在StackPanel中放置其他控件,如按钮、标签、文本框、图片等等。这些控件的排列方式由StackPanel按照指定的方向自动确…

jQuery: 整理5---删除元素和遍历元素

1. 删除元素 span{color: white;padding: 8px;margin: 5px;float: left;}.green {background-color: green;}.blue {background-color: blue;}<span class"green">green</span><span class"blue">blue</span><span class"…

快速排序之C++实现

描述 快速排序是一种常用的排序算法&#xff0c;它的思想是选取一个基准元素&#xff0c;将数组分成左右两部分&#xff0c;使得左边的元素都小于等于基准元素&#xff0c;右边的元素都大于等于基准元素&#xff0c;然后递归地对左右两部分进行快速排序。 实现步骤 选择一个…

Arduino/Android 蓝牙通信系统设计解决方案

随着当今安全管理的发展需求以及国家对安全监控行业的支持&#xff0c;这几年&#xff0c;安全监控行业发展迅猛&#xff0c;各类监控系统百花齐放。传统的温度监控系统通过有线或其他方式传送温度数据&#xff0c;而本文提出了利用蓝牙无线传输数据的设计方案&#xff0c;这种…

Oracle 学习(2)

过滤和排序数据 where条件过滤 日期格式 查询10号部门的员工信息&#xff1a;SQL> select * from emp where deptno10 查询”KING”的信息&#xff1a;SQL> select * from emp where ename KiNg 未选定行。 注意&#xff1a;字符串大小写敏感。 SQL> selec…

数据仓库【4】:最佳实践

数据仓库【4】&#xff1a;最佳实践 1、表的分类1.1、事实表1.2、维度表1.3、事务事实表1.4、周期快照事实表1.5、累积快照事实表1.6、拉链表 2、ETL策略2.1、全量同步2.2、增量同步 3、任务调度3.1、为什么需要任务调度&#xff1f;3.2、常见任务类型3.3、常见调度工具 1、表的…

谷歌 SGE 和生成式 AI 在搜索中:2024 年会发生什么

2024 年&#xff0c;Google 的搜索生成体验将如何影响营销&#xff1f;探索 AI 驱动的搜索趋势、SERP 中的 SGE、自然流量影响等。 最初&#xff0c;Labs 中的 Google 搜索生成体验 &#xff08;SGE&#xff09; 实验预计将于 2023 年 12 月“结束”。但随着谷歌实验室网站的最…

【Qt-编码】

Qt编程指南 ■ 编码■ ASCII■ ANSI■ GB2312■ GBK■ GB18030 编码■ Unicode■ UTF-8&#xff1a; ■ Qt接收注射泵GBK编码后显示乱码■■ ■ 编码 ■ ASCII &#xff08;American Standard Code for Information Interchange&#xff0c;美国信息交换标准代码&#xff09;…