服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - C#多态详解

C#多态详解

2022-12-06 11:41时始 C#

这篇文章主要介绍了C#中的多态,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

1.定义

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

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

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

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

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

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

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

C#多态详解

2.实现多态的两个因素

1)子类重写父类方法

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

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

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

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

?
1
2
3
4
int a=(int)3.5;
Dog dog = (Dog)animal;//向下转型
dog.call();
dog.smell();

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

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

3.案例

?
1
2
3
4
5
6
7
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; }
// 虚方法
?
1
2
3
4
5
6
public virtual void Draw()
{
Console.WriteLine("执行基类的画图任务");
}
}
?
1
2
3
4
5
6
7
8
class Circle : Shape
{
public override void Draw()
{
base.Draw();
Console.WriteLine("画一个圆形");
}
}
?
1
2
3
4
5
6
7
8
class Rectangle : Shape
{
public override void Draw()
{
base.Draw();
Console.WriteLine("画一个长方形");
}
}
?
1
2
3
4
5
6
7
8
9
class Triangle : Shape
{
public override void Draw()
{
base.Draw();
Console.WriteLine("画一个三角形");
}
}
?
1
2
3
4
5
6
7
8
9
10
11
12
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();
}
}

父类做返回值

?
1
2
3
4
5
6
7
class Person
{
public virtual void Eat()
{
 
}
}
?
1
2
3
4
5
6
7
class WhitePerson:Person
{
public override void Eat()
{
Console.WriteLine("热狗");
}
}
?
1
2
3
4
5
6
7
8
9
class YellowPerson:Person
{
public override void Eat()
{
Console.WriteLine("饺子");
}
 
//写一个GetPerson方法,返回值为父类,
//根据传入的不同人种来确定吃什么
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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;
}
}

父类做参数

?
1
2
3
4
5
6
7
class Animal
{
public virtual void Swimming()
{
Console.WriteLine("动物游泳");
}
}
?
1
2
3
4
5
6
class Cat:Animal
{
public override void Swimming()
{
Console.WriteLine("猫挠");
}
?
1
2
3
4
5
6
7
8
9
//写一个方法,完成动物游泳(对象做参数)
void GetSwimming(Animal a)//a是引用
{
if (a is Cat)
{
Cat c = (Cat)a;//向下转型
c.Swimming();
}
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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)字符串的比较

?
1
2
3
4
5
6
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。

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

字符串的截取

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

字符串的分割

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

字符串的合并

?
1
2
3
4
5
6
7
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

字符串的替换

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

字符串的插入

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

字符串的删除

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

删除Len个字符

?
1
2
3
4
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)字符串的大小写转换

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

10)string.Format()

?
1
2
3
4
5
6
7
8
9
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 类型的类。

总结

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

原文链接:https://blog.csdn.net/m0_62705032/article/details/120724432

延伸 · 阅读

精彩推荐
  • C#C#自定义IP输入框控件

    C#自定义IP输入框控件

    这篇文章主要为大家详细介绍了C#自定义IP输入框控件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    程序猿老黄4962022-02-23
  • C#C# 获取硬件参数的实现方法

    C# 获取硬件参数的实现方法

    这篇文章主要介绍了C# 获取硬件参数的实现方法的相关资料,希望通过本文能帮助到大家,让大家实现这样的功能,需要的朋友可以参考下...

    lan_liang8192022-01-25
  • C#C#基础入门之值类型和引用类型的区别详析

    C#基础入门之值类型和引用类型的区别详析

    在C#中值类型的变量直接存储数据,而引用类型的变量持有的是数据的引用,数据存储在数据堆中,下面这篇文章主要给大家介绍了关于C#基础入门之值类型和引...

    .NET开发菜鸟9382022-12-05
  • C#C#委托与匿名委托详解

    C#委托与匿名委托详解

    这篇文章主要为大家详细介绍了C#委托与匿名委托的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    DW03910552022-01-20
  • C#轻松学习C#的异常处理

    轻松学习C#的异常处理

    轻松学习C#的异常处理,对C#的异常处理感兴趣的朋友可以参考本篇文章,帮助大家更灵活的运用C#的异常处理。...

    C#教程网8732021-11-04
  • C#C#连接MySQL的两个简单代码示例

    C#连接MySQL的两个简单代码示例

    这篇文章主要介绍了C#连接MySQL的简单代码示例,需要的朋友可以参考下...

    C#教程网11972022-01-11
  • C#C#获取文件MD5值的实现示例

    C#获取文件MD5值的实现示例

    文件的md5值,即文件签名,为了验证文件的正确性,是否被恶意篡改等。每个文件有一个唯一的md5。下面这篇文中就给大家介绍了如何利用C#获取文件MD5值...

    辰晓晨11682021-12-14
  • C#C# 单元测试全解析

    C# 单元测试全解析

    这篇文章主要介绍了C# 单元测试的相关资料,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下...

    五维思考5302022-11-11