多态Polymorphism是C# 面向对象编程OOP的三大特性之一封装Encapsulation继承Inheritance多态Polymorphism多态的核心思想同一个行为在不同对象中表现出不同的结果。简单理解父类引用指向子类对象调用同一个方法时根据实际对象类型执行不同代码。例如Animal animal; animal new Dog(); animal.Speak(); // 输出汪汪 animal new Cat(); animal.Speak(); // 输出喵喵虽然变量类型都是Animal但是执行结果不同这就是多态。一、多态的作用多态主要解决1. 提高代码扩展性没有多态Dog dog new Dog(); dog.Speak(); Cat cat new Cat(); cat.Speak();以后增加Bird bird new Bird(); bird.Speak();需要不断修改代码。使用多态Animal animal; animal new Dog(); animal.Speak(); animal new Cat(); animal.Speak(); animal new Bird(); animal.Speak();以后增加动物只需要继承Animal。二、C# 多态的实现方式C# 中主要有三种多态类型实现方式编译时多态方法重载Overload运行时多态虚方法virtual/override接口多态interface三、编译时多态方法重载1. 什么是方法重载同一个类中方法名相同参数列表不同例如class Calculator { public int Add(int a, int b) { return a b; } public double Add(double a, double b) { return a b; } public int Add(int a, int b, int c) { return a b c; } }调用Calculator c new Calculator(); Console.WriteLine(c.Add(1,2)); Console.WriteLine(c.Add(1.5,2.5)); Console.WriteLine(c.Add(1,2,3));输出3 4 6为什么叫编译时多态因为编译器根据参数类型决定调用哪个方法。例如Add(10,20)编译器看到int,int选择Add(int,int)四、运行时多态重点运行时多态是 C# 最常用的多态形式。依靠virtualoverridebase实现。1. virtual虚方法父类定义class Animal { public virtual void Speak() { Console.WriteLine(动物叫); } }virtual表示这个方法允许子类重新实现。2. override重写子类class Dog : Animal { public override void Speak() { Console.WriteLine(汪汪); } }另一个子类class Cat : Animal { public override void Speak() { Console.WriteLine(喵喵); } }3. 使用父类引用调用Animal a; a new Dog(); a.Speak(); a new Cat(); a.Speak();输出汪汪 喵喵这里发生了什么变量Animal a;编译类型Animal实际对象第一次Dog第二次Cat运行时根据对象真实类型决定调用哪个方法。这就是动态绑定Dynamic Binding五、完整运行时多态案例假设开发一个游戏所有角色都有攻击方法class Role { public virtual void Attack() { Console.WriteLine(普通攻击); } }战士class Warrior : Role { public override void Attack() { Console.WriteLine(挥剑攻击); } }法师class Mage : Role { public override void Attack() { Console.WriteLine(释放魔法); } }弓箭手class Archer : Role { public override void Attack() { Console.WriteLine(射箭攻击); } }统一调用ListRole roles new ListRole() { new Warrior(), new Mage(), new Archer() }; foreach(Role role in roles) { role.Attack(); }输出挥剑攻击 释放魔法 射箭攻击优势以后增加class Assassin : Role { public override void Attack() { Console.WriteLine(暗杀); } }原代码foreach(Role role in roles) { role.Attack(); }无需修改。这就是开闭原则Open Closed Principle六、隐藏方法 new 与 override 区别很多初学者容易混淆override真正实现多态class Dog:Animal { public override void Speak() { Console.WriteLine(狗叫); } }调用Animal anew Dog(); a.Speak();输出狗叫new 隐藏方法class Dog:Animal { public new void Speak() { Console.WriteLine(狗叫); } }调用Animal anew Dog(); a.Speak();输出动物叫因为new不产生多态只隐藏父类方法。七、抽象类实现多态如果父类没有具体实现可以使用abstract父类abstract class Shape { public abstract double Area(); }圆class Circle : Shape { public double Radius; public override double Area() { return Math.PI * Radius * Radius; } }矩形class Rectangle : Shape { public double Width; public double Height; public override double Area() { return Width * Height; } }调用Shape s; snew Circle(); Console.WriteLine(s.Area()); snew Rectangle(); Console.WriteLine(s.Area());八、接口实现多态接口是 C# 中非常重要的多态方式。定义interface IAnimal { void Speak(); }实现class Dog:IAnimal { public void Speak() { Console.WriteLine(汪汪); } }class Cat:IAnimal { public void Speak() { Console.WriteLine(喵喵); } }调用IAnimal animal; animalnew Dog(); animal.Speak(); animalnew Cat(); animal.Speak();输出汪汪 喵喵九、virtual、abstract、interface区别特性virtualabstractinterface是否有实现可以有没有没有子类是否必须重写否必须必须所在位置普通类抽象类接口支持多继承否否是用途扩展已有行为定义规范定义能力十、多态的底层原理简单理解例如Animal a new Dog(); a.Speak();内存a | | ---- Dog对象 | Speak()运行时找到对象真实类型查看虚方法表Virtual Table调用 Dog 的 Speak()因此Animal | | Dog可以执行Dog.Speak()十一、多态常见应用场景1. 游戏开发角色Character ├── Warrior ├── Mage └── Archer统一character.Attack();2. 支付系统Payment | -- Alipay | -- WeChatPay | -- BankPay调用payment.Pay();3. 数据库访问Database | -- MySQL | -- SQLServer | -- Oracle统一database.Connect();十二、多态设计原则优秀的多态设计面向抽象编程不要Dog dognew Dog();推荐Animal animalnew Dog();少使用类型判断不推荐if(animal is Dog) { } else if(animal is Cat) { }应该animal.Speak();让对象自己处理行为。十三、总结概念关键字说明方法重载无编译时多态虚方法virtual允许重写方法重写override实现运行时多态抽象方法abstract强制子类实现接口interface规范多态一句话总结C# 多态就是通过父类或接口引用指向不同子类对象让同一个方法调用产生不同的行为从而提高程序的扩展性和可维护性。
C# 多态性详解
多态Polymorphism是C# 面向对象编程OOP的三大特性之一封装Encapsulation继承Inheritance多态Polymorphism多态的核心思想同一个行为在不同对象中表现出不同的结果。简单理解父类引用指向子类对象调用同一个方法时根据实际对象类型执行不同代码。例如Animal animal; animal new Dog(); animal.Speak(); // 输出汪汪 animal new Cat(); animal.Speak(); // 输出喵喵虽然变量类型都是Animal但是执行结果不同这就是多态。一、多态的作用多态主要解决1. 提高代码扩展性没有多态Dog dog new Dog(); dog.Speak(); Cat cat new Cat(); cat.Speak();以后增加Bird bird new Bird(); bird.Speak();需要不断修改代码。使用多态Animal animal; animal new Dog(); animal.Speak(); animal new Cat(); animal.Speak(); animal new Bird(); animal.Speak();以后增加动物只需要继承Animal。二、C# 多态的实现方式C# 中主要有三种多态类型实现方式编译时多态方法重载Overload运行时多态虚方法virtual/override接口多态interface三、编译时多态方法重载1. 什么是方法重载同一个类中方法名相同参数列表不同例如class Calculator { public int Add(int a, int b) { return a b; } public double Add(double a, double b) { return a b; } public int Add(int a, int b, int c) { return a b c; } }调用Calculator c new Calculator(); Console.WriteLine(c.Add(1,2)); Console.WriteLine(c.Add(1.5,2.5)); Console.WriteLine(c.Add(1,2,3));输出3 4 6为什么叫编译时多态因为编译器根据参数类型决定调用哪个方法。例如Add(10,20)编译器看到int,int选择Add(int,int)四、运行时多态重点运行时多态是 C# 最常用的多态形式。依靠virtualoverridebase实现。1. virtual虚方法父类定义class Animal { public virtual void Speak() { Console.WriteLine(动物叫); } }virtual表示这个方法允许子类重新实现。2. override重写子类class Dog : Animal { public override void Speak() { Console.WriteLine(汪汪); } }另一个子类class Cat : Animal { public override void Speak() { Console.WriteLine(喵喵); } }3. 使用父类引用调用Animal a; a new Dog(); a.Speak(); a new Cat(); a.Speak();输出汪汪 喵喵这里发生了什么变量Animal a;编译类型Animal实际对象第一次Dog第二次Cat运行时根据对象真实类型决定调用哪个方法。这就是动态绑定Dynamic Binding五、完整运行时多态案例假设开发一个游戏所有角色都有攻击方法class Role { public virtual void Attack() { Console.WriteLine(普通攻击); } }战士class Warrior : Role { public override void Attack() { Console.WriteLine(挥剑攻击); } }法师class Mage : Role { public override void Attack() { Console.WriteLine(释放魔法); } }弓箭手class Archer : Role { public override void Attack() { Console.WriteLine(射箭攻击); } }统一调用ListRole roles new ListRole() { new Warrior(), new Mage(), new Archer() }; foreach(Role role in roles) { role.Attack(); }输出挥剑攻击 释放魔法 射箭攻击优势以后增加class Assassin : Role { public override void Attack() { Console.WriteLine(暗杀); } }原代码foreach(Role role in roles) { role.Attack(); }无需修改。这就是开闭原则Open Closed Principle六、隐藏方法 new 与 override 区别很多初学者容易混淆override真正实现多态class Dog:Animal { public override void Speak() { Console.WriteLine(狗叫); } }调用Animal anew Dog(); a.Speak();输出狗叫new 隐藏方法class Dog:Animal { public new void Speak() { Console.WriteLine(狗叫); } }调用Animal anew Dog(); a.Speak();输出动物叫因为new不产生多态只隐藏父类方法。七、抽象类实现多态如果父类没有具体实现可以使用abstract父类abstract class Shape { public abstract double Area(); }圆class Circle : Shape { public double Radius; public override double Area() { return Math.PI * Radius * Radius; } }矩形class Rectangle : Shape { public double Width; public double Height; public override double Area() { return Width * Height; } }调用Shape s; snew Circle(); Console.WriteLine(s.Area()); snew Rectangle(); Console.WriteLine(s.Area());八、接口实现多态接口是 C# 中非常重要的多态方式。定义interface IAnimal { void Speak(); }实现class Dog:IAnimal { public void Speak() { Console.WriteLine(汪汪); } }class Cat:IAnimal { public void Speak() { Console.WriteLine(喵喵); } }调用IAnimal animal; animalnew Dog(); animal.Speak(); animalnew Cat(); animal.Speak();输出汪汪 喵喵九、virtual、abstract、interface区别特性virtualabstractinterface是否有实现可以有没有没有子类是否必须重写否必须必须所在位置普通类抽象类接口支持多继承否否是用途扩展已有行为定义规范定义能力十、多态的底层原理简单理解例如Animal a new Dog(); a.Speak();内存a | | ---- Dog对象 | Speak()运行时找到对象真实类型查看虚方法表Virtual Table调用 Dog 的 Speak()因此Animal | | Dog可以执行Dog.Speak()十一、多态常见应用场景1. 游戏开发角色Character ├── Warrior ├── Mage └── Archer统一character.Attack();2. 支付系统Payment | -- Alipay | -- WeChatPay | -- BankPay调用payment.Pay();3. 数据库访问Database | -- MySQL | -- SQLServer | -- Oracle统一database.Connect();十二、多态设计原则优秀的多态设计面向抽象编程不要Dog dognew Dog();推荐Animal animalnew Dog();少使用类型判断不推荐if(animal is Dog) { } else if(animal is Cat) { }应该animal.Speak();让对象自己处理行为。十三、总结概念关键字说明方法重载无编译时多态虚方法virtual允许重写方法重写override实现运行时多态抽象方法abstract强制子类实现接口interface规范多态一句话总结C# 多态就是通过父类或接口引用指向不同子类对象让同一个方法调用产生不同的行为从而提高程序的扩展性和可维护性。