09.多态

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了09.多态相关的知识,希望对你有一定的参考价值。

多态的概率:
多态是面向对象当中最重要的概念.

多态的概念:
让一个对象能够表现出多种状态(类型)

实现多态:
通常实现多态有三种手段:
(1).虚方法
(2).抽象类
(3).接口

多态就是对象可以表现多个类型的能力

虚方法:
将父类的方法标记为虚方法使用关键字 virtual 来修饰
在父类中使用virtual修饰的方法,在子类中重写时,要加override来修饰.

override与重载(overload)的区别

重载是方法的名称相同。参数或参数类型不同,进行多次重载以适应不同的需要。重载(overload)是面向过程的概念。

Override 是进行基类中函数的重写。Override是面向对象的概念

重写 和重载 不一样 要区分开


使用虚函数的多态实例1:
  1. namespace _23.虚方法的练习01
  2. {
  3. class Program
  4. {
  5. static void Main(string[] args)
  6. {
  7. //用虚方法来实现 真的鸭子嘎嘎叫 木头鸭子吱吱叫 橡皮鸭子唧唧叫
  8. RealDuck rd1 = new RealDuck();
  9. MuDuck md1 = new MuDuck();
  10. XPDuck xd1 = new XPDuck();
  11. RealDuck[] rd = new RealDuck[3] { rd1,md1,xd1} ;
  12. for (int i = 0; i < rd.Length; i++)
  13. {
  14. rd[i].Bark();
  15. }
  16. Console.ReadKey();
  17. }
  18. }
  19. public class RealDuck
  20. {
  21. public virtual void Bark()
  22. {
  23. Console.WriteLine("真的鸭子嘎嘎叫");
  24. }
  25. }
  26. public class MuDuck:RealDuck
  27. {
  28. public override void Bark()
  29. {
  30. Console.WriteLine("木头鸭子吱吱叫");
  31. }
  32. }
  33. public class XPDuck:RealDuck
  34. {
  35. public override void Bark()
  36. {
  37. Console.WriteLine("橡皮鸭子唧唧叫");
  38. }
  39. }
  40. }
技术分享
使用虚函数的多态实例2:
  1. namespace _24.虚方法的练习02
  2. {
  3. class Program
  4. {
  5. static void Main(string[] args)
  6. {
  7. //经理十一点打卡 员工九点打卡 程序员不打卡
  8. Employee emp = new Employee();
  9. Manager mg = new Manager();
  10. Programmer pm = new Programmer();
  11. Employee[] emps = {emp,mg,pm};
  12. for (int i = 0; i < emps.Length; i++)
  13. {
  14. emps[i].DaKa();
  15. }
  16. Console.ReadKey();
  17. }
  18. }
  19. /// <summary>
  20. /// 员工类
  21. /// </summary>
  22. public class Employee
  23. {
  24. public virtual void DaKa()
  25. {
  26. Console.WriteLine("员工,九点打卡");
  27. }
  28. }
  29. public class Manager : Employee
  30. {
  31. public override void DaKa()
  32. {
  33. Console.WriteLine("经理十一点打卡");
  34. }
  35. }
  36. public class Programmer : Employee
  37. {
  38. public override void DaKa()
  39. {
  40. Console.WriteLine("程序员不打卡");
  41. }
  42. }
  43. }
技术分享
 

抽象类:
?抽象类与抽象方法由abstract修饰
?abstract的使用注意
–抽象方法没有方法体
–抽象成员只能存在于抽象类中
–抽象类可以有非抽象成员
–抽象类的派生类必须实现抽象方法体
–抽象类只能用作基类,无法实例化
–抽象类的子类必须实现抽象类中所有抽象方法

使用抽象类来实现多态的示例代码1:
  1. namespace _25.抽象类的练习01
  2. {
  3. class Program
  4. {
  5. static void Main(string[] args)
  6. {
  7. //狗狗会叫 猫咪也会叫
  8. Dog dg = new Dog();
  9. Cat ct = new Cat();
  10. Animal[] am = { dg,ct};
  11. for (int i = 0; i < am.Length; i++)
  12. {
  13. am[i].Shout();
  14. }
  15. Console.ReadKey();
  16. }
  17. }
  18. public abstract class Animal
  19. {
  20. public abstract void Shout();
  21. }
  22. public class Dog : Animal
  23. {
  24. public override void Shout()
  25. {
  26. Console.WriteLine("小狗汪汪叫");
  27. }
  28. }
  29. public class Cat : Animal
  30. {
  31. public override void Shout()
  32. {
  33. Console.WriteLine("小猫喵喵叫");
  34. }
  35. }
  36. }
技术分享

使用抽象类来实现多态的示例代码:
  1. namespace _26.使用多态来解决实际问题01
  2. {
  3. class Program
  4. {
  5. static void Main(string[] args)
  6. {
  7. //使用多态求矩形的面积和周长以及圆形的面积和周长
  8. //思考过程:
  9. //矩形不能作为圆形的父类 因为计算方法不一样
  10. //圆形也不能作为矩形的父类 因为计算方法不一样
  11. //所以 虚方法不能解决问题
  12. //我们 采用抽象类来实现
  13. Shape s1 = new Rectangle(5, 3);
  14. Console.WriteLine("矩形的面积为:{0},矩形的周长为:{1}.",s1.area(),s1.Perimeter());
  15. Shape s2 = new Circle(3);
  16. Console.WriteLine("圆的面积为:{0:#.##},圆形的周长为:{1:#.##}.", s2.Perimeter(), s2.Perimeter());
  17. Console.ReadKey();
  18. }
  19. }
  20. public abstract class Shape
  21. {
  22. public abstract double area(); //没有实现的求面积的方法
  23. public abstract double Perimeter(); //没有实现的求周长的方法
  24. }
  25. public class Rectangle : Shape
  26. {
  27. private double _chang;
  28. private double _kuan;
  29. public double Chang
  30. {
  31. get
  32. {
  33. return _chang;
  34. }
  35. set
  36. {
  37. _chang = value;
  38. }
  39. }
  40. public double Kuan
  41. {
  42. get
  43. {
  44. return _kuan;
  45. }
  46. set
  47. {
  48. _kuan = value;
  49. }
  50. }
  51. public Rectangle(double chang, double kuan)
  52. {
  53. this.Chang = chang;
  54. this.Kuan=kuan;
  55. }
  56. public override double area()
  57. {
  58. return Chang * Kuan;
  59. }
  60. public override double Perimeter()
  61. {
  62. return (Chang + Kuan) * 2;
  63. }
  64. }
  65. public class Circle : Shape
  66. {
  67. private double r;
  68. public double R
  69. {
  70. get
  71. {
  72. return r;
  73. }
  74. set
  75. {
  76. r = value;
  77. }
  78. }
  79. public Circle(double r)
  80. {
  81. this.R = r;
  82. }
  83. public override double area()
  84. {
  85. return Math.PI * Math.Pow(R, 2);
  86. }
  87. public override double Perimeter()
  88. {
  89. return 2*Math.PI*R;
  90. }
  91. }
  92. }
技术分享
 

 
虚方法和抽象类的比较:
技术分享
 
虚函数,抽象类,以及接口都可以用来实现多态,那么他们之间有什么区别,或者用途上的
不同呢?

(1).虚方法,就是在已知条件中,可以找到一个父类的时候,我们可以使用虚方法,来完成多态.   比如 例题:经理,员工,程序员,三个类,他们都需要打卡上班,这个时候,我们可以以员工
类为父类,因为本质上,经理,员工,程序员 他们都是属于员工的,故可以使用员工类,作为所有类型的父类. 


 

























以上是关于09.多态的主要内容,如果未能解决你的问题,请参考以下文章

java中封装,继承,多态,接口学习总结

多态性和动态铸造

09.面向对象多态的概述及其代码体现

09-02 java 多态

Python入门-6面向对象编程:09多态

# Java 常用代码片段