20.C# 多态性——《跟老吕学C#》
C# 多态性
一、重载(Overloading)
二、重写(Overriding)
三、接口实现(Interface Implementation)
四、多态性的应用实例
总结
C# 多态性
在C#编程中,多态性(Polymorphism)是面向对象编程的三大特性之一,它允许不同的对象对同一消息做出不同的响应。这意味着可以用父类的引用来引用子类的对象,同时子类对象能够根据自己的特征覆盖或在父类方法的基础上添加新的功能。
加粗样式C#中的多态性主要体现在以下三种类型上:
类型 描述
重载(Overloading) 这种方法允许在同一类中定义多个同名但参数列表不同的方法,称为方法重载。
重写(Overriding) 在面向对象编程中,子类可以重写父类中的方法,即定义一个与父类同名、同参数列表但实现不同的方法,从而覆盖父类的实现。
接口实现(Interface Implementation) 接口实现指的是一个类通过实现接口中定义的方法,来满足接口所规定的契约。当一个类实现了某个接口时,它必须提供该接口中所有方法的实现。
一、重载(Overloading)
重载是指在同一个类中,方法名相同但参数列表(参数类型、参数个数或参数顺序)不同的方法。编译器会根据提供的参数列表来决定调用哪个方法。这允许我们为同一操作提供多种实现方式,提高了代码的灵活性和可读性。
public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
public double Add(double a, double b)
{
return a + b;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
在这个Calculator类中,Add方法被重载了两次,分别用于处理整数和浮点数的加法。
二、重写(Overriding)
重写是指在子类中定义一个与父类中同名、同参数列表、同访问修饰符的方法,以覆盖父类中的方法实现。当通过子类对象调用该方法时,会执行子类中的方法,而不是父类中的方法。这允许子类在继承父类的基础上,对父类的行为进行扩展或修改。
public class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("The animal makes a sound");
}
}
public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("The dog barks");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
在这个例子中,Animal类定义了一个MakeSound的虚方法(使用virtual关键字),Dog类则重写了这个方法,提供了更具体的实现。
三、接口实现(Interface Implementation)
接口定义了一组方法的规范,但没有实现这些方法。任何实现了该接口的类都必须提供这些方法的具体实现。这允许不同的类以统一的方式响应相同的消息,从而实现了多态性。
public interface IMovable
{
void Move();
}
public class Car : IMovable
{
public void Move()
{
Console.WriteLine("The car is moving");
}
}
public class Plane : IMovable
{
public void Move()
{
Console.WriteLine("The plane is flying");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
在这个例子中,IMovable接口定义了一个Move方法,Car和Plane类都实现了这个接口,并提供了各自的具体实现。这样,我们就可以通过IMovable类型的引用来引用Car或Plane的对象,并调用它们的Move方法,而无需关心具体的对象类型。
四、多态性的应用实例
假设我们有一个简单的游戏场景,其中有两种角色:玩家(Player)和敌人(Enemy)。这两种角色都需要移动和攻击,但它们移动和攻击的方式是不同的。这时,我们可以使用多态性来设计这个系统。
首先,我们可以定义一个基类Character,它包含所有角色共有的属性和方法,如Move和Attack。由于不同的角色移动和攻击的方式不同,我们可以将这两个方法定义为虚方法(virtual)。
public abstract class Character
{
public string Name { get; set; }
public virtual void Move()
{
Console.WriteLine("The character is moving...");
}
public virtual void Attack()
{
Console.WriteLine("The character is attacking...");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
注意这里我们使用了abstract关键字来表示Character是一个抽象类,因为在实际的游戏中,我们不会直接创建Character的实例,而是创建其子类(如Player和Enemy)的实例。
接下来,我们可以创建Player和Enemy类,它们继承自Character类,并重写Move和Attack方法以提供具体的实现。
public class Player : Character
{
public override void Move()
{
Console.WriteLine("The player is walking...");
}
public override void Attack()
{
Console.WriteLine("The player is swinging a sword...");
}
}
public class Enemy : Character
{
public override void Move()
{
Console.WriteLine("The enemy is running...");
}
public override void Attack()
{
Console.WriteLine("The enemy is shooting an arrow...");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
现在,我们可以在游戏的主循环中创建一个Character数组或列表,其中可以包含Player和Enemy的实例。当我们需要移动或攻击所有角色时,我们可以遍历这个数组或列表,并调用每个角色的Move和Attack方法。由于多态性的存在,我们无需关心具体的角色类型,只需要调用方法即可。
List<Character> characters = new List<Character> { new Player(), new Enemy() };
foreach (var character in characters)
{
character.Move();
character.Attack();
}
1
2
3
4
5
6
7
这段代码会输出类似以下的结果:
The player is walking...
The player is swinging a sword...
The enemy is running...
The enemy is shooting an arrow...
1
2
3
4
通过多态性,我们能够在不修改已有代码的情况下,轻松地添加新的角色类型,并扩展游戏的功能。这就是多态性带来的好处之一。
总结
在C#编程中,多态性是一个强大的工具,它允许我们以更灵活、更可维护的方式编写代码。通过重载、重写和接口实现,我们可以实现不同的多态性形式,以满足不同的编程需求。在实际编程中,我们应该充分利用多态性的优势,以提高代码的质量和可维护性。
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.youkuaiyun.com/molangmolang/article/details/140070804