C#多态详解

目录
  • 1.定义
  • 2.实现多态的两个因素
  • 3.案例
  • 4、使用多态的好处
  • 5、string类
    • 1、值类型
    • 2、引用类型
  • 6.运算符重载:
  • 总结

1.定义

多态是同一个行为具有多个不同表现形式或形态的能力。

多态性意味着有多重形式。在面向对象编程范式中,多态性往往表现为"一个接口,多个功能"。

多态性可以是静态的或动态的。在静态多态性中,函数的响应是在编译时发生的。在动态多态性中,函数的响应是在运行时发生的。

静态多态性:在编译时,方法和对象的连接机制被称为早期绑定,也被称为静态绑定。C# 提供了两种技术来实现静态多态性。分别为:方法重载、运算符重载

动态多态性是通过 抽象类 和 虚方法 实现的。

在 C# 中,每个类型都是多态的,因为包括用户定义类型在内的所有类型都继承自 Object。

多态就是同一个接口,使用不同的实例而执行不同操作,如图所示:

2.实现多态的两个因素

1)子类重写父类方法

2)使用父类的类型(子类转换为父类:向上转型)

class Animal
{
public virtual void call() {
Console.WriteLine("无声的叫唤");
}
}
class Dog : Animal
{
// new的作用是隐藏父类的同名方法
//public new void call() {
//Console.WriteLine("叫声:汪~汪~汪~");
//}
public override void call() {
Console.WriteLine("叫声:汪~汪~汪~");
}
public void smell() {
Console.WriteLine("嗅觉相当不错!");
}
}
Animal animal = new Dog(); //向上转型
animal.call();

向上转型:将子类对象转为父类对象。此处父类对象可以是接口或抽象类。

转化后的父类对象具有父类所有方法,若方法被子类重写override,那么实际调用时,调用的是重写后的实现。

int a=(int)3.5;
Dog dog = (Dog)animal;//向下转型
dog.call();
dog.smell();

向下转型:把父类对象转为子类对象。

转化后的子类对象,跟一般的继承子类对象一样。具有子类所有方法(包括重写方法)+父类所有方法(被重写的方法,按重写的算。)

3.案例

public class Shape
{
public int X { get; private set; }
public int Y { get; private set; }
public int Height { get; set; }
public int Width { get; set; }
// 虚方法
public virtual void Draw()
{
Console.WriteLine("执行基类的画图任务");
}
}
​
class Circle : Shape
{
public override void Draw()
{
base.Draw();
Console.WriteLine("画一个圆形");
}
}
class Rectangle : Shape
{
public override void Draw()
{
base.Draw();
Console.WriteLine("画一个长方形");
}
}
class Triangle : Shape
{
public override void Draw()
{
base.Draw();
Console.WriteLine("画一个三角形");
}
}
​
class Program
{
static void Main(string[] args)
{
Shape circle=new Circle();
circle.Draw();
Shape rectangle=new Rectangle();
rectangle.Draw();
Shape triangle=new Triangle();
triangle.Draw();
}
}

父类做返回值

class Person
{
public virtual void Eat()
{

}
}
class WhitePerson:Person
{
public override void Eat()
{
Console.WriteLine("热狗");
}
}
class YellowPerson:Person
{
public override void Eat()
{
Console.WriteLine("饺子");
}

//写一个GetPerson方法,返回值为父类,
//根据传入的不同人种来确定吃什么
Person GetPerson(string s)
{
Person p=null;
if (s.Equals("中国人"))
{
p = new YellowPerson();
}
else if (s.Equals("外国人"))
{
p= new WhitePerson();
}
else
{
return p;
}
p.Eat();
return p;
}
}

父类做参数

class Animal
{
public virtual void Swimming()
{
Console.WriteLine("动物游泳");
}
}
class Cat:Animal
{
public override void Swimming()
{
Console.WriteLine("猫挠");
}
//写一个方法,完成动物游泳(对象做参数)
void GetSwimming(Animal a)//a是引用
{
if (a is Cat)
{
Cat c = (Cat)a;//向下转型
c.Swimming();
}
}
static void Main(string[] args)
{
Cat c = new Cat();
Dog d = new Dog();
Animal a = c;
// Animal a = d;
c.GetSwimming(a);
}
}
static void Main(string[] args)
{
Cat c = new Cat();
Dog d = new Dog();
Animal a = c;
// Animal a = d;
c.GetSwimming(a);
}
}

4、使用多态的好处

1. 应用程序不必为每一个派生类编写功能调用,只需要对抽象基类进行处理即可。大大提高程序的

可复用性。//继承
2. 派生类的功能可以被基类的方法或引用变量所调用,这叫向后兼容,可以提高可扩充性和可维护

性。 //多态的真正作用

5、string类

==和Equals的区别

1、值类型

==和Equals比较的内容都是一致的,都是比较内容

string a = "123";//值

Console.WriteLine(a=="123");

Console.WriteLine(a.Equals("123"));

2、引用类型

==: 比较首地址是否相等 Equals:比较的是值是否相等

char[] x={'1','2','3'};

string b = new string(x);//引用

Console.WriteLine(b=="123");

Console.WriteLine(b.Equals("123"));

1)字符串的比较

Compare(str1, str2)
str1.CompareTo(str2)
string a = "hello",b="Hello",c="hello";
Console.WriteLine(a.CompareTo(b));//-1
Console.WriteLine(string.Compare(a,b));//-1
Console.WriteLine(a.CompareTo(c));//0

字符串的查找

(1)Contains(Findstr):找指定字符串是否包含一个字串Findstr,返回值的bool类型,即只有

true和false。

(2)IndexOf(Findstr):查找FindStr在字符串中第一次出现的位置,返回值为第一次出现

的下标,没有找到则返回-1.

(3)LastIndexOf(FindStr):查找FindStr在字符串中最后一次出现的位置,返回值为最后

一次出现的下标,没有找到则返回-1。

Console.WriteLine(a.Contains("lo"));//true
Console.WriteLine(a.IndexOf('e'));//1
Console.WriteLine(a.LastIndexOf('l'));//3

字符串的截取

SubString(StartIndex):字符串中下标从StartIndex开始后面的全部字符串。
SubString(StartIndex, Len):字符串中下标从StartIndex开始后面的Len个长度的字符串。
Console.WriteLine(a.Substring(1));//ello
Console.WriteLine(a.Substring(1,3));//ell

字符串的分割

Split(SplitCh):将字符串按SplitCh进行分割,它的返回值是一个字符串数组。
string d="锄禾日当午#汗滴禾下土#谁知盘中餐#粒粒皆辛苦";
string[] e = d.Split('#');
for (int i = 0; i < e.Length; i++)
{
Console.WriteLine(e[i]);
}

字符串的合并

string.Concat(str1, str2, …., strn):将n个字符串连接,中间没有连接符
“+”连接符号
string f = "world";
Console.WriteLine(a+f);
Console.WriteLine(1+2+3+a);//6hello
Console.WriteLine(a+1+2+3);//hello123
Console.WriteLine(string.Concat(a,f));//helloworld

字符串的替换

Replace(oldStr, newStr):用newStr来替换字符串中的oldStr
Console.WriteLine(a.Replace("he","HE"));//HEllo

字符串的插入

Insert(index, str):index是需要插入的位置,str是要插入的字符
Console.WriteLine(a.Insert(1,"ww"));//hwwello

字符串的删除

Trim():删除字符串中开始和结尾处的空格
Remove(Start):Start为需要删除的起始位置,该方法是将位置后的所有字符全部删除
Remove(Start, Len):Len是指需要删除的长度,与上面格式不同的是它是从起始位置开始

删除Len个字符

string s = " aaa bbb ccc ";
Console.WriteLine(s.Trim());//aaa bbb ccc
Console.WriteLine(s.Remove(6));// aaa b
Console.WriteLine(s.Remove(2,7));// aaccc

9)字符串的大小写转换

ToLower():将字符串转化为小写形式
ToUpper():将字符串转换威大写形式

10)string.Format()

string.Format("{0:d}",System.DateTime.Now) //结果为:2021-3-23 (月份位置不是03)
string.Format("{0:D}",System.DateTime.Now) //结果为:2021年3月23日
string.Format("{0:f}",System.DateTime.Now) //结果为:2021年3月23日 15:37
string.Format("{0:F}",System.DateTime.Now) //结果为:2021年3月23日 15:37:52
string.Format("{0:g}",System.DateTime.Now) //结果为:2021-3-23 15:38
string.Format("{0:G}",System.DateTime.Now) //结果为:2021-3-23 15:39:27
string.Format("{0:m}",System.DateTime.Now) //结果为:3月23日
string.Format("{0:t}",System.DateTime.Now) //结果为:15:41
string.Format("{0:T}",System.DateTime.Now) //结果为:15:41:5

6.运算符重载:

关键字 abstract 声明抽象类:用于接口部分类的实现(派生类继承抽象类时,实现完成)。抽象类包含抽象方法,抽象方法可被派生类实现。

抽象类规则:

1.不能创建抽象类的实例

2.不能在抽象类外定义抽象方法

3.不能把抽象类声明为sealed(类前带关键字sealed代表该类是密封类,不能被继承)

关键字virtual声明虚方法:用于方法在继承类中的实现(在不同的继承类中有不同的实现)。

抽象类和虚方法共同实现动态多态性。

注:继承类中的重写虚函数需要声明关键字 override,在方法参数传入中写(类名 形参名)例如 public void CallArea(Shape sh),意思是传入一个 shape 类型的类。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • C#中的多态深入理解

    封装.继承.多态,面向对象的三大特性,前两项理解相对容易,但要理解多态,特别是深入的了解,对于初学者而言可能就会有一定困难了.我一直认为学习OO的最好方法就是结合实践,封装.继承在实际工作中的应用随处可见,但多态呢?也许未必,可能不经意间用到也不会把它跟"多态"这个词对应起来.在此抛砖引玉,大家讨论,个人能力有限,不足之处还请指正. 之前看到过类似的问题:如果面试时主考官要求你用一句话来描述多态,尽可能的精炼,你会怎么回答?当然答案有很多,每个人的理解和表达不尽相同,但我比较趋向这样描

  • 详解c# 多态

    多态是同一个行为具有多个不同表现形式或形态的能力. 多态性意味着有多重形式.在面向对象编程范式中,多态性往往表现为"一个接口,多个功能". 多态性可以是静态的或动态的.在静态多态性中,函数的响应是在编译时发生的.在动态多态性中,函数的响应是在运行时发生的. 在 C# 中,每个类型都是多态的,因为包括用户定义类型在内的所有类型都继承自 Object. 多态就是同一个接口,使用不同的实例而执行不同操作,如图所示: 现实中,比如我们按下 F1 键这个动作: 如果当前在 Flash 界面下弹出

  • C# 多态性的深入理解

    MSDN 上面的定义:通过继承,一个类可以有多种类型:可以用作它自己的类型,任何基类型,或者在实现接口时用作任何接口的类型.从两个方面来说明多态1.在运行时,方法参数和集合或者是数组等位置,派生类的对象都可以作为基类的对象处理,发生此情况时,该对象的声明类型不再与运行时类型相同.2.基类定义实现虚方法,派生类重写这些方法,在运行时,CLR会查找运行时类型,并且调用派生类重写的方法. 复制代码 代码如下: class Shape    {        public virtual void Dr

  • C#基础继承和多态详解

    继承 在现有类(称为基类.父类)上建立新类(称为派生类.子类)的处理过程为继承.派生类能自动获取基类(除了构造函数和析构函数外的所有成员),可以在派生类中添加新的属性和方法扩展其功能. 复制代码 代码如下: using System;using System.Collections.Generic;using System.Linq;using System.Web; public class Person{ private string _id;    public string id   

  • C#类的多态性详解

    第一种:编译时的多态性,直接这样说不知道说啥?程序执行过程主要分为三步:编译,链接,运行.在编译时体现的多态性是通过方法的重载来实现的.方法的重载我们听过,就是一个类对象调用若干同名,但参数类型.个数不同.类对象是根据参数类型,个数来决定调用哪个同名方法,实现何种操作.C#语言的方法重载与C++.java基本是一样的,但是C#还包含C++的运算符重载,java里面没有这个概念. 第二种:运行时的多态性,是在系统运行时,调用一个名字相同,参数类型也相同以及个数也完全一样的方法,但会完成不同的操作.

  • 从汇编看c++中的多态详解

    在c++中,当一个类含有虚函数的时候,类就具有了多态性.构造函数的一项重要功能就是初始化vptr指针,这是保证多态性的关键步骤. 构造函数初始化vptr指针 下面是c++源码: class X { private: int i; public: X(int ii) { i = ii; } virtual void set(int ii) {//虚函数 i = ii; } }; int main() { X x(1); } 下面是对应的main函数汇编码: _main PROC ; 16 : in

  • C++/java 继承类的多态详解及实例代码

    C++/java 继承类的多态详解 学过C++和Java的人都知道,他们二者由于都可以进行面向对象编程,而面向对象编程的三大特性就是封装.继承.多态,所有今天我们就来简单了解一下C++和Java在多态这方面的不同. 首先我们各看一个案例. C++ //测试继承与多态 class Animal { public: char name[128]; char behavior[128]; void outPut() { cout << "Animal" << endl

  • Python面向对象编程之继承与多态详解

    本文实例讲述了Python面向对象编程之继承与多态.分享给大家供大家参考,具体如下: Python 类的继承 在OOP(Object Oriented Programming)程序设计中,当我们定义一个class的时候,可以从某个现有的class 继承,新的class称为子类(Subclass),而被继承的class称为基类.父类或超类(Base class.Super class). 我们先来定义一个class Person,表示人,定义属性变量 name 及 sex (姓名和性别): 定义一

  • Java之理解多态详解

    目录 一.多态的概念 二.多态的特点 三.instanceof操作符 四.多态的转型 1.向上转型 2.向下转型 五.方法重写 六.小结 一.多态的概念        继承关系使一个子类能继承父类的特征,并且附加一些新特征.子类是它的父类的特殊化,每个子类的实例都是其父类的实例,但是反过来不成立.例如:每个圆都是一个几何对象,但并非每个几何对象都是圆.因此,总可以将子类的实例传给需要父类型的参数.参考案例如下: public class PolymorphismDemo{ /** Main me

  • C++类和对象之多态详解

    目录 多态基本概念和原理剖析 多态案例1 计算器类 纯虚函数和抽象类 多态案例2 制作饮品 虚析构和纯虚析构 多态案例3 电脑组装 多态基本概念和原理剖析 多态:多态是C++面向对象的三大特性之一.多态分为静态多态和动态多态. 静态多态:函数重载和运算符重载属于静态多态,复用函数名. 动态多态:派生类和虚函数实现运行时多态. 区别: 静态多态的函数地址早绑定,编译阶段确定函数地址. 动态多态的函数地址晚绑定,运行阶段确定函数地址. #include <iostream> using names

  • Java中接口的多态详解

    目录 多态参数 多态数组 接口的多态传递现象 总结 多态参数 就像我们现实生活中电脑的usb接口,我们既可以接受手机对象,又可以接受相机对象,等等,体现了接口的多态,查看以下代码 接口: package InterfaceM; public interface Interface { public void join(); public void stop(); } 手机类: package InterfaceM; public class Phone implements Interface{

  • Java OOP三大特征之封装继承与多态详解

    目录 封装 继承 多态 OOP语言的三大特征即:面向对象的三个比较重要的思想 封装 官话:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口进行交互 通俗讲,不让类外看到实现的细节,通过技术手段对这些细节包装一个外壳,同时提供几个公开的接口,让你进行交互即可(例如:手机,内部的具体零件,不会让你观察到,使用者只能看到外壳,通过外壳的显示屏,充电口进行交互)简而言之——套壳屏蔽细节 实际上通过private来实现 例如: 继承 面向对象的思想中提出了继承的概念,专门用来进

  • c++中为什么可以通过指针或引用实现多态详解

    引言: 在c++中司空见惯的事情就是:可以通过指针和引用可以实现多态,而对象不可以. 那为什么?让我们来解开这神秘的暗纱! 1. 类对象的存储方式: 在一个类的实例中,只会存放非静态的成员变量. 如果该类中存在虚函数的话,再多加一个指向虚函数列表指针-vptr. 例如声明如下两个类,并分别实例化两个对象,它们的内存分配大致如下:(vptr具体在什么位置,与编译器有关,大多数都在开始处) class base { public: virtual ~base() {}; virtual string

  • Python 的类、继承和多态详解

    类的定义 假如要定义一个类 Point,表示二维的坐标点: # point.py class Point: def __init__(self, x=0, y=0): self.x, self.y = x, y 最最基本的就是 __init__ 方法,相当于 C++ / Java 的构造函数.带双下划线 __ 的方法都是特殊方法,除了 __init__ 还有很多,后面会有介绍. 参数 self 相当于 C++ 的 this,表示当前实例,所有方法都有这个参数,但是调用时并不需要指定. >>&g

随机推荐