C#中面向对象编程机制之多态学习笔记
作者:junjie 发布时间:2023-12-06 20:16:33
C#的多态性:
我的理解是:同一个操作,作用于不同的对象时,会有不同的结果,即同一个方法根据需要,作用于不同的对象时,会有不同的实现。
C#的多态包括:接口多态,继承多态。
其中继承多态又包括通过虚拟方法实现的多态和通过抽象方法实现的多态性
例如:基类动物都有吃的方法,但是不同的动物吃的东西就会不一样,例如狼吃肉,羊吃草,这样“吃”的这个方法就要在派生类里面重新实现以下,运行时,通过指向基类的指针,来调用实现派生类中的方法。
接下来举例实现多态性。
1. 接口多态性
把动物“吃”的方法放到一个接口(IAnimal)里,然后让具体的动物类(Wolf/Sheep)继承这个接口,并根据自己的需要实现这个接口。
代码实现:
class Program {
static void Main(string[] args) {
new Wolf().Eat();
new Sheep().Eat();
}
}
public class Wolf : IAnimal {
//多态实现
public void Eat() {
Console.WriteLine("狼吃肉!");
}
}
public class Sheep : IAnimal {
//多态实现
public void Eat() {
Console.WriteLine("羊吃草!");
}
}
//接口
public interface IAnimal {
void Eat();
}
接口的多态性就是当不同的类继承了相同的接口以后,都要根据自己的需要重新实现继承的接口,这样同样的方法签名在不同的类中就会实现不同的操作。
2. 继承的多态性
2.1.通过虚拟方法实现的多态(virtual,override)
首先要在基类中实现virtual方法,然后在派生类中根据自己的需要用override重写virtual方法。如果不希望这个方法被继续重写,则把这个方法写成sealed方法。
virtual方法必须在基类中实现。
代码实现:
class Program {
static void Main(string[] args) {
new Wolf().Eat();
new Sheep().Eat();
new Goat().Eat();
}
}
public class Wolf : Animal {
//多态实现
public override void Eat() {
base.Eat();
Console.WriteLine("狼吃肉!");
}
}
public class Sheep : Animal {
//多态实现
public override void Eat() {
base.Eat();
Console.WriteLine("羊吃草!");
}
}
public class Goat : Sheep {
//多态实现被终结,此Eat方法不能被override,因为用sealed了
public sealed override void Eat() {
//base.Eat();
Console.WriteLine("山羊吃草!");
}
}
//基类实现虚方法
public class Animal {
public virtual void Eat() { }
}
2.2.通过抽象方法实现的多态(abstract,override)
抽象方法必须定义在抽象类里。抽象类不能被创建实例。
基类中的抽象方法只能被声明,不需要实现,所以派生类中重写抽象方法的时候没有base方法。
代码实现如下:
class Program {
static void Main(string[] args) {
new Wolf().Eat();
new Sheep().Eat();
new Goat().Eat();
}
}
public class Wolf : Animal {
//多态实现
public override void Eat() {
Console.WriteLine("狼吃肉!");
}
}
public class Sheep : Animal {
//多态实现
public override void Eat() {
Console.WriteLine("羊吃草!");
}
}
public class Goat : Sheep {
//多态实现被终结,此Eat方法不能被override,因为用sealed了
public sealed override void Eat() {
Console.WriteLine("山羊吃草!");
}
}
//基类只需声明方法
public abstract class Animal {
public abstract void Eat();
}
总结:
1.虚方法重写的时候可以有base方法(base.Eat()),抽象方法重写的时候没有base方法,原因是:虚方法必须在基类中实现,抽象方法只在基类中声明,不需要实现。
2.派生类中可以 不重写虚方法的实现,但是派生类必须重写抽象方法的实现,原因同1.
3.包含虚方法的非抽象类可以被创建实例(对象),但是包含抽象方法的抽象类不能被创建实例。
4.继承接口的派生类必须实现接口的方法,因为接口也是只负责声明方法,不负责实现。
5.接口的多态性不需要用override重写方法。
猜你喜欢
- 在java 编程中,我们常常有这样的需求:需要将一段字符串内的特定字符串,按照一定规则查找出来或替换,比如匹配文本开头规则和结束规则。以下就
- 本文实例为大家分享了Flutter自定义圆盘取色器的具体代码,供大家参考,具体内容如下下面展示一些 内联代码片。圆盘取色器效果图完整代码im
- 鉴于各种复杂的网络环境,笔者决定采用不同的编程接口进行下载尝试,以增加程序的可用性。这里仅介绍使用 WebClient 的方法,后续的文章会
- 本文实例讲述了JAVA快速排序实现方法。分享给大家供大家参考,具体如下:package com.ethan.sort.java;import
- 本文所述实例为使用伪随机数进行用户密码加密,这段代码为核心部分主要代码,需要配合其它的程序实现,感兴趣的读者可以自己进一步加以完善,不费话了
- 一、JVM 类加载机制JVM 类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程。1. 加载:加载是类
- goto在Java中是一个保留字,但在语言中并没有用到它;Java没有goto。但是,Java也能完成一些类似于跳转的操作,主要是依靠:标签
- 现在有很多库、实用工具和程序任Java开发人员选择。每个工具都有其优点,但其中有一些因它的知名度、多功能性和有效性从众多选项中脱颖而出。以下
- 前言在java中遍历Map有不少的方法。这篇文章我们就来看一下Java读取Map的两种方法以及这两种方法的对比。一、 遍历Map方
- 前言今天遇到一个问题,我们有个ip.dat二进制文件,通过里面内容可以解析ip所在的地域信息,本地单元测试都是OK的,部署到测试环境后,发现
- 一、水平分表当业务需求的数据量过大时,一个表格存储数据会非常之多,故时长采用水平分表的方式来减少每张表的数据量即是提升查询数据库时的效率。水
- java 中Spark中将对象序列化存储到hdfs摘要: Spark应用中经常会遇到这样一个需求: 需要将JAVA对象序列化并存储到HDFS
- 数据类型大小范围默认值byte(字节)8-128 - 1270shot(短整型)16-32768 - 327680int(整型)32-214
- Spring Boot中的那些Conditionalspring boot中为我们提供了丰富的Conditional来让我们得以非常方便的在
- SpringBoot使用protobuf格式的接口建立SpringBoot项目,pom.xml内容如下:<?xml version=&
- 本文实例讲述了C#实现DataTable映射成Model的方法。分享给大家供大家参考,具体如下:这是数据库开发中经常遇到的问题,当然,这可以
- 在做在线编程题目的时候,需要了解一下数据的输入格式。这样可以对数据处理有比较好的把握,不需要把太多的时间放在这个上面,注重主要的算法逻辑即可
- 1.登录腾讯云点击登录选择浏览器登录。输入用户名 按回车键 然后输入 密码。2.安装java环境直接命令:yum -y install ja
- 场景做一个消息中心,专门负责发送消息。消息分为几种渠道,包括手机通知(Push)、短信(SMS)、邮件(Email),Websocket等渠
- 在项目开发中经常会遇到调用第三方接口的情况,比如说调用第三方的天气预报接口。使用流程【1】准备工作:在项目的工具包下导入HttpClient