C#关于多态的一个有趣的例子
封装、继承、多态,面向对象的三大特性,前两项理解相对容易,但要理解多态,特别是深入的了解,对于初学者而言可能就会有一定困难了。我一直认为学习 面向对象(ObjectOriented,OO)的最好方法就是结合实践,封装、继承在实际工作中的应用随处可见,但多态呢?也许未必,可能不经意间用到也不会把它跟“多态”这个词对应起来。在此抛砖引玉,大家讨论,个人能力有限,不足之处还请指正。多态(Polymorphism)按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作(摘自“Delphi4 编程技术内幕”)。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。
通过继承,一个类可以用作多种类型:可以用作它自己的类型、任何基类型,或者在实现接口时用作任何接口类型。这称为多态性。C# 中的每种类型都是多态的。类型可用作它们自己的类型或用作 Object 实例,因为任何类型都自动将 Object 当作基类型。
多态性不仅对派生类很重要,对基类也很重要。任何情况下,使用基类实际上都可能是在使用已强制转换为基类类型的派生类对象。基类的设计者可以预测到其基类中可能会在派生类中发生更改的方面。
通过多态的使用可以使类与类事件的关系更加明确,类之间的继承关系让类之间的共性更加清晰,最现实的就是对于我们这些程序猿,了解了类与类之间的继承关系后就可以放心的调用所用类父类的所用方法。通过类的抽像减少大部分代码,增强项目的可维护性。
下面贴出一段有趣的代码供产考:
首先根据接口,引出多态的优点
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Data.OleDb; using System.Data.OracleClient; namespace 多态设计模式 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button3_Click(object sender, EventArgs e) { Cat cat = new Cat(); Dog dog = new Dog(); Mouse mouse = new Mouse(); List<Animal> animal = new List<Animal>(); animal.Add(cat); animal.Add(dog); animal.Add(mouse); foreach (Animal item in animal) { item.咬(dog); } } } public interface Animal { void 咬(Animal animal); void 叫(); } public class Cat : Animal { public void 咬(Animal animal) { MessageBox.Show("猫咬了"); animal.叫(); } public void 叫() { MessageBox.Show("喵喵喵"); } } public class Dog : Animal { public void 咬(Animal animal) { MessageBox.Show("狗咬了"); animal.叫(); } public void 叫() { MessageBox.Show("旺旺汪"); } } public class Mouse:Animal { public void 咬(Animal animal) { MessageBox.Show("老鼠咬了"); animal.叫(); } public void 叫() { MessageBox.Show("叽叽叽"); } } }
上述代码中包含了 Animal接口、Cat Dog Mouse三个类,Cat、 Dog、 Mouse实现Animal接口中的方法
void 咬(Animal animal);
void 叫();
结果: 窗口弹出顺序
猫咬了 汪汪汪
狗咬了 旺旺汪
老鼠咬了 汪汪汪
结果分析: item.咬(dog); 由于 咬() 的参数的对象传递都是 dog ,所以 void 叫(); 产生的结果都是 汪汪汪
通过这个简单的例子可以看出 三个子类都实现了接口但实现方式都不同,即多态。
下面通过类之间的继承关系,引出多态的优点
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Data.OleDb; using System.Data.OracleClient; namespace 多态设计模式 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button3_Click(object sender, EventArgs e) { Cat cat = new Cat(); Dog dog = new Dog(); Mouse mouse = new Mouse(); List<Animal> animal = new List<Animal>(); animal.Add(cat); animal.Add(dog); animal.Add(mouse); foreach (Animal item in animal) { item.咬(dog); } } } public class Animal { public virtual void 咬(Animal animal) { MessageBox.Show("Animal咬了"); } public virtual void 叫() { MessageBox.Show("Animal怎么叫啊,不知道"); } } public class Cat : Animal { public override void 咬(Animal animal) { MessageBox.Show("猫咬了"); animal.叫(); } public override void 叫() { MessageBox.Show("喵喵喵"); } } public class Dog : Animal { public override void 咬(Animal animal) { MessageBox.Show("狗咬了"); animal.叫(); } public override void 叫() { MessageBox.Show("旺旺汪"); } } public class Mouse:Animal { public override void 咬(Animal animal) { MessageBox.Show("老鼠咬了"); animal.叫(); } public override void 叫() { MessageBox.Show("叽叽叽"); } } }
上述代码中包含了 Animal、Cat 、Dog 、Mouse四个类,Cat、 Dog、 Mouse覆盖了Animal方法
public virtual void 咬(Animal animal)
{
MessageBox.Show("Animal咬了");
}
public virtual void 叫()
{
MessageBox.Show("Animal怎么叫啊,不知道");
}
结果: 窗口弹出顺序
猫咬了 汪汪汪
狗咬了 旺旺汪
老鼠咬了 汪汪汪
Animal类定义了两个虚方法,但在子类中都覆盖了父类的方法,在程序运行过程中各自会首先调用自身实现的方法,即多态。
注:本文章属个人学习总结,部分内容参考互联网上的相关文章。 其中如果发现个人总结有不正确的认知或遗漏的地方请评论告知,欢迎交流。