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

C#中修饰符——abstract、virtual

一、多态简介

        在面向对象编程的过程中,多态体现出来的是【一个接口,多个功能】;多态性体现在2个方面:

        1、程序运行时,在方法参数、集合或数组等位置,派生类对象可以作为基类的对象处理;这样该对象声明的类型就与运行时的类型不同了;

        2、基类可以定义并实现虚方法,派生类可以重写这些虚方法;在程序运行时,可以调用基类方法执行派生类的重写方法。

        在C#中要实现多态,必须使用abstract、virtual这个两个修饰符来定义,使用override来重写方法。 多态又可以分为:【静态多态性】、【动态多态性】;

二、静态多态性

         静态多态性(即:使用static修饰;变量、函数的响应是在程序编译时就发生了)若一个方法被static声明,则该方法就是静态方法,那么编译器就会在编译时保留这个静态方法的实现;也就是说这个静态方法只属于类,而不属于任何实例,无论实例是否存在,都可以可直接调用这个静态方法。

        C#中的静态多态性分为两种:【函数重载】、【运算符重载】

    //静态函数重载示例
    public class StaticReload
    {
        public static void Greet()
        {
            Console.WriteLine($"你好,欢迎访问");
        }
        public static void Greet(string greetMsg)
        {
            Console.WriteLine(greetMsg);
        }

    }//Class_end


    class Program
    {
        static async Task Main(string[] args)
        {
            StaticReload.Greet();
            StaticReload.Greet("Quartz定时任务测试");
        }
    }

 

运算符重载 - 定义一元运算符、算术运算符、相等运算符和比较运算符。 - C# reference | Microsoft Learnhttps://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/operator-overloading

三、动态多态性

        动态多态性(无static修饰;变量、函数的响应是在程序运行起来后发生的)。

 3.1、abstract(抽象)

abstract 关键字 - C# reference | Microsoft Learnhttps://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/abstract        【abstract】关键字可用于修饰类(Class)、方法(Method)、属性(attribute)、索引(index)和事件(Event);

  3.1.1、抽象类

         在类(class)前面放置修饰符【abstract】,则可以将类声明为抽象类;

抽象类的特点
序号抽象类特点
1抽象类不能实例化
2抽象类可能包含抽象方法和访问器
3

无法使用 sealed 修饰符来修改抽象类

因为两个修饰符的含义相反【 sealed 修饰符阻止类被继承;而 abstract 修饰符要求类被继承】

4派生自抽象类的非抽象类,必须实际实现所继承抽象类的全部抽象内容(抽象方法、属性、索引、事件)
    public abstract class MyShape
    {
        public abstract float GetArea();
        public abstract string Name { get;}
        public abstract Action<float> GetAction();
        

    }//Class_end


    public class Circle : MyShape
    {
        private int _radius;
        
        public Circle(int r)
        {
            _radius = r;
                
        }

        public override string Name {get => "我是圆";}

        public override Action<float> GetAction()
        {
            throw new NotImplementedException();
        }

        public override float GetArea()
        {
            var tmp =Math.PI * (_radius * _radius);
            float result =(float)tmp;
            return result;
        }

    }//Class_end


    class Program
    {
        static async Task Main(string[] args)
        {
            MyShape myShape = new Circle(3);
            float shapeArea = myShape.GetArea();
           
            Console.WriteLine($"Name:{myShape.Name}  ShapeArea: {shapeArea}");
        }
    }

 

抽象类、密封类及类成员 - C# | Microsoft Learnhttps://learn.microsoft.com/zh-cn/dotnet/csharp/programming-guide/classes-and-structs/abstract-and-sealed-classes-and-class-members 

  3.1.2、抽象方法

   在方法、属性、索引、事件前面放置修饰符【abstract,则可以声明为抽象方法、属性、索引、事件;且表明方法、属性、索引、事件不包含实现。

抽象方的法特点
序号抽象方法特点
1只有抽象类中才允许声明抽象方法
2

抽象方法不提供实际实现,所以声明仅以分号结尾,没有大括号{};具体实现由一般类继承抽象类使用 override重写

public abstract float GetArea();
3抽象方法声明中使用 static 或 virtual 修饰符是错误的

  3.1.3、abstract的使用场景

        内容有通用的共性特征和行为,且必须要在不同的派生类实现(即:内容必须存在的时候用abstract)。

 3.2、virtual(虚拟)

virtual 关键字 - C# reference | Microsoft Learnhttps://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/virtual  【virtual 】关键字用于修改方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。

  3.2.1、虚方法

    public class MyCar
    {
        public virtual string Name { get; set; }

        public virtual string Manufacturer { get; }

        public MyCar(string manufacturer)
        {
            this.Manufacturer = manufacturer;
        }
        public virtual void Function()
        {
            Console.WriteLine($"【{Manufacturer}】品牌车况运行状态良好");
        }

        public virtual Action<bool> Custom(bool start)
        {
            if (start)
            {
                Console.WriteLine($"【{Name}】仪表盘显示发动机转速");
            }

            return null;
        }

    }//Class


    public class SUVCar : MyCar
    {
        public SUVCar(string manufacturer) : base(manufacturer)
        {

        }

        public override void Function()
        {
            base.Function();
            Console.WriteLine($"【{Manufacturer}】品牌开始校验SUV的各个功能是否正常");
        }

        public override Action<bool> Custom(bool start)
        {
            Action<bool> action=new Action<bool>(Test);
            Console.WriteLine($"【{Name}】所有功能准备完毕,开始出发");

            return action;
        }

        private void Test(bool start)
        {
            if (start)
            {
                Console.WriteLine("启动智能驾驶功能");
            }
            
        }

    }//Class_end


    class Program
    {
        static async Task Main(string[] args)
        {
            MyCar car = new MyCar("自产");
            car.Name = "基础车";
            car.Function();
            car.Custom(true);

            Console.WriteLine("---------------------------\r\n");

            car = new SUVCar("问界");
            car.Name = "SUV越野";
            car.Function();
            car.Custom(true);
        }
    }

虚方法的特点
序号虚方法特点
1虚方法必须有实现
2虚方法可以不在派生类中重写
虚方法的2中使用情况
1基类定义了virtual方法,但是派生类没有重写基类virtual方法,则对派生类的实例调用中,使用的是基类定义的virtual方法内容
2基类定义了virtual方法,且派生类重写了基类的virtual方法,则对派生类的实例调用中,使用的是派生类重写的virtual方法内容

  3.2.2、virual的使用场景

        virtual的核心是多态【即:同一个方法能用不同的方式来做】;如:

1、支付方法Pay(),既可使用微信支付、也可使用支付宝支付或者其他方法支付;

2、消息发送方法MSGSend(),既可使用邮件发送、也可使用企业微信发送、或钉钉发送;

3.3、抽象方法与虚方法的区别与联系

抽象方法与虚方法的相同点是:都使用override重写。

抽象方法与虚方法的区别
序号抽象方法(abstract)虚方法(virtual)
1抽象方法必须在抽象类中没有要求
2抽象方法只是声明没有实际实现,必须在派生类中重写实现虚方法有声明与实际实现,派生类可完全重写、部分重写或不重写直接使用基类实现
3抽象类不能被实例化(new),只能用实现了全部抽象方法的派生类来实例化包含虚方法的类可以被实例化(new)

 3.4、普通类、接口与抽象类

抽象类主要用于关系密切的对象接口适合为不相关的类提供通用功能

普通类、接口、抽象类区别与联系
序号普通类接口抽象类
1普通类可有成员变量、常量、构造函数,没有抽象方法接口不能有常量、域、操作符、构造函数、析构函数及其任何静态成员【可包含属性、方法、索引和事件】抽象类有抽象方法
2普通类可继承一个基类,多个接口接口可继承多个接口抽象类也可继承一个基类和多个接口
3普通类可以定义具体的方法和实际实现接口只能定义方法,而没有具体实现抽象类的抽象方法不能有具体实现
4普通类成员没有限制接口成员必须是公共的抽象类不能对private抽象
5普通类可以实例化接口不能实例化抽象类不能实例化,只能使用实现了全部抽象方法的派生类来实例化

四、其他资料

访问修饰符 - C# reference | Microsoft Learnhttps://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/access-modifiers

面向对象编程 - 封装 - C# | Microsoft Learnhttps://learn.microsoft.com/zh-cn/dotnet/csharp/fundamentals/object-oriented/#encapsulation面向对象编程 - 继承 - C# | Microsoft Learnhttps://learn.microsoft.com/zh-cn/dotnet/csharp/fundamentals/object-oriented/inheritance面向对象编程 - 多态性 - C# | Microsoft Learnhttps://learn.microsoft.com/zh-cn/dotnet/csharp/fundamentals/object-oriented/polymorphismC#面向对象的三大特性(封装、继承、多态)_c# 三大特性-CSDN博客文章浏览阅读3.2k次,点赞3次,收藏43次。一、封装 把客观的事物封装成类,并将类的内部实现隐藏,以保证数据的完整性;每个对象都包含了他能进行操作所需要的所有信息,因此对象不必依靠其他的对象来完成自己的操作。【优点】 1. 将变化隔离; 2. 便于使用; 3. 提高复用性; 4. 提高安全性;【封装原则】 1. 将不需要对外提供的内容都隐藏起来; 2...._c# 三大特性 https://blog.csdn.net/xiaochenXIHUA/article/details/95037977

C#中抽象类和接口的区别与应用场景 https://www.cnblogs.com/yangzhou/p/3283994.html 搞了这么多年终于知道接口和抽象类的应用场景了https://cloud.tencent.com/developer/article/1677833

相关文章:

  • 天梯赛 PTAL2-009 抢红包
  • Hugging Face模型国内镜像HF Mirror下载
  • Python Pyecharts面试题及参考答案
  • OpenHarmony 开源鸿蒙北向开发——linux使用make交叉编译第三方库
  • 计算机四级 - 数据库原理(操作系统部分)- 第3章「进程线程模型」
  • 数据结构-------栈
  • AJAX的理解和原理还有概念
  • AI综合应用及办公应用
  • 工业控制系统中的信号传输格式解析
  • 函数闭包的学习
  • [JavaScript]如何利用作用域块避免闭包内存泄漏?
  • Moonlight-16B-A3B: 变革性的高效大语言模型,凭借Muon优化器打破训练效率极限
  • DNS缓存使用中有什么问题?DNS缓存有哪些作用?
  • 蓝桥杯day2:解码异或 后的数组
  • test_cases测试用例层/test_1_login
  • ubuntu中的环境变量文件 bashrc、profile、environment简要总结
  • 【Java篇】一气化三清:类的实例化与封装的智慧之道
  • 口袋书签功能上新,免费使用
  • 网络华为HCIA+HCIP AAA原理与配置
  • 8.4《同一直线上二力的合成》
  • 人民日报评论员:因势利导对经济布局进行调整优化
  • 北汽蓝谷一季度净亏损9.5亿元,拟定增募资不超60亿元
  • 俄罗斯总统普京:5月8日零时至11日零时实施停火
  • 深一度|“凑合过”的利物浦,英超第二冠只求性价比
  • 王一博赛车故障退赛冲上热搜,工作室回应:下次再战
  • 杨荫凯履新浙江省委常委、组织部部长,曾任中央财办副主任