实现多态的手段

1、虚方法
步骤:将父类的方法标记为虚方法,使用关键字virtual,这个方法可以被子类重新写一遍。(重写)
将子类的方法使用override —-(重写)

  1. using System;
  2. namespace _081_多态之虚方法
  3. {
  4. class Program
  5. {
  6. static void Main(string[] args)
  7. {
  8. //概念:让一个对象能够表现出多种的状态(类型)
  9. //实现多态的三种方法:1、虚方法 2、抽象类 3、接口
  10. Chinese cn1 = new Chinese("傻逼");
  11. Chinese cn2 = new Chinese("笨蛋");
  12. Japanese j1 = new Japanese("波多野结衣");
  13. Japanese j2 = new Japanese("冲田杏梨");
  14. Korea k1 = new Korea("金智秀");
  15. Korea k2 = new Korea("金秀智");
  16. American a1 = new American("Saber");
  17. American a2 = new American("WeXiao");
  18. //Person[] pers = new Person[8];
  19. Person[] pers = { cn1, cn2, j1, j2, k1, k2, a1, a2 };
  20. for (int i = 0; i < pers.Length; i++)
  21. {
  22. //if(pers[i] is Chinese)
  23. //{
  24. // ((Chinese)pers[i]).SayHello();
  25. //}
  26. //else if (pers[i] is Japanese)
  27. //{
  28. // ((Japanese)pers[i]).SayHello();
  29. //}
  30. //else if (pers[i] is Korea)
  31. //{
  32. // ((Korea)pers[i]).SayHello();
  33. //}
  34. //else //if (pers[i] is American)
  35. //{
  36. // ((American)pers[i]).SayHello();
  37. //}
  38. pers[i].SayHello();
  39. }
  40. Console.ReadKey();
  41. }
  42. }
  43. }
  44. using System;
  45. using System.Collections.Generic;
  46. using System.Text;
  47. namespace _081_多态之虚方法
  48. {
  49. class Person
  50. {
  51. private string _name;
  52. public string Name
  53. {
  54. get { return _name; }
  55. set { _name = value; }
  56. }
  57. public Person(string name)
  58. {
  59. this._name = name;
  60. }
  61. public virtual void SayHello()
  62. {
  63. Console.WriteLine("我是人类,我的名字是{0}", Name);
  64. }
  65. }
  66. }
  67. using System;
  68. using System.Collections.Generic;
  69. using System.Text;
  70. namespace _081_多态之虚方法
  71. {
  72. class Korea:Person
  73. {
  74. public Korea(string name) : base(name)
  75. { }
  76. public override void SayHello()
  77. {
  78. Console.WriteLine("我是韩国还是朝鲜,我的名字是{0}", Name);
  79. }
  80. }
  81. }
  82. using System;
  83. using System.Collections.Generic;
  84. using System.Text;
  85. namespace _081_多态之虚方法
  86. {
  87. class Japanese : Person
  88. {
  89. public Japanese(string name) : base(name)
  90. {
  91. }
  92. public override void SayHello()
  93. {
  94. Console.WriteLine("我是小日本,我的名字是{0}", Name);
  95. }
  96. }
  97. }
  98. using System;
  99. using System.Collections.Generic;
  100. using System.Text;
  101. namespace _081_多态之虚方法
  102. {
  103. class English:Person
  104. {
  105. public English(string name) : base(name)
  106. { }
  107. public override void SayHello()
  108. {
  109. Console.WriteLine("English");
  110. }
  111. }
  112. }
  113. using System;
  114. using System.Collections.Generic;
  115. using System.Text;
  116. namespace _081_多态之虚方法
  117. {
  118. class Chinese : Person
  119. {
  120. public Chinese(string name) : base(name)
  121. {
  122. }
  123. public override void SayHello()
  124. {
  125. Console.WriteLine("我是中国人,我的名字是{0}", Name);
  126. }
  127. }
  128. }
  129. using System;
  130. using System.Collections.Generic;
  131. using System.Text;
  132. namespace _081_多态之虚方法
  133. {
  134. class American : Person
  135. {
  136. public American(string name) : base(name)
  137. { }
  138. public override void SayHello()
  139. {
  140. Console.WriteLine("我是米国人,我的名字是{0}", Name);
  141. }
  142. }
  143. }

练习:

  1. using System;
  2. namespace _082_虚方法练习
  3. {
  4. class Program
  5. {
  6. static void Main(string[] args)
  7. {
  8. Duck duck=new Duck();
  9. RealDuck realDuck = new RealDuck();
  10. RubberDuck rubberDuck = new RubberDuck();
  11. WoodenDuck woodenDuck = new WoodenDuck();
  12. DeadDuck deadDuck = new DeadDuck();
  13. Duck[] ducks = { duck, realDuck, rubberDuck, woodenDuck, deadDuck };
  14. for (int i = 0; i < ducks.Length; i++)
  15. {
  16. ducks[i].Bark();
  17. }
  18. Console.ReadKey();
  19. }
  20. }
  21. }
  22. using System;
  23. using System.Collections.Generic;
  24. using System.Text;
  25. namespace _082_虚方法练习
  26. {
  27. class Duck
  28. {
  29. public virtual void Bark()
  30. {
  31. Console.WriteLine("鸭子叫");
  32. }
  33. }
  34. }
  35. using System;
  36. using System.Collections.Generic;
  37. using System.Text;
  38. namespace _082_虚方法练习
  39. {
  40. class RealDuck : Duck
  41. {
  42. public override void Bark()
  43. {
  44. Console.WriteLine("真的鸭子嘎嘎叫");
  45. }
  46. }
  47. }
  48. using System;
  49. using System.Collections.Generic;
  50. using System.Text;
  51. namespace _082_虚方法练习
  52. {
  53. class RubberDuck : Duck
  54. {
  55. public override void Bark()
  56. {
  57. Console.WriteLine("橡胶鸭子唧唧叫");
  58. }
  59. }
  60. }
  61. using System;
  62. using System.Collections.Generic;
  63. using System.Text;
  64. namespace _082_虚方法练习
  65. {
  66. class DeadDuck : Duck
  67. {
  68. public override void Bark()
  69. {
  70. Console.WriteLine("死的鸭子不会叫");
  71. }
  72. }
  73. }
  74. using System;
  75. using System.Collections.Generic;
  76. using System.Text;
  77. namespace _082_虚方法练习
  78. {
  79. class WoodenDuck : Duck
  80. {
  81. public override void Bark()
  82. {
  83. Console.WriteLine("木头鸭子吱吱叫");
  84. }
  85. }
  86. }

2、抽象类
当父类中的方法不知道如何去实现时,可以考虑将父类写成抽象类,将方法写成抽象方法。(抽象方法没有方法体)
特点:
1、抽象成员必须标记为abstract,并且不能有任何实现。
2、抽象成员必须在抽象类中。
3、抽象类不能被实例化。
4、子类继承抽象类后,必须把父类中的所有抽象成员都重写。
(除非子类也是一个抽象类,则可以不用重写)
5、抽象成员的访问修饰符不能是private。
6、在抽象类中可以包含实例成员,并且抽象类的实例成员可以不被子类实现。
7、抽象类是有构造函数的,虽然不能被实例化。
image.png

抽象类练习

image.png

  1. using System;
  2. namespace _084_抽象类练习
  3. {
  4. class Program
  5. {
  6. static void Main(string[] args)
  7. {
  8. //1|使用多态求矩形和圆的面积和周长
  9. Console.WriteLine("输入圆的半径:");
  10. double radius = Convert.ToDouble(Console.ReadLine());
  11. Shape circle = new Circle(radius);
  12. double circleArea = circle.Area();
  13. double circlePerimeter = circle.Perimeter();
  14. Console.WriteLine("圆的面积为:{0},圆的周长为:{1}", circleArea, circlePerimeter);
  15. Console.WriteLine("请输入矩形的长和宽:");
  16. double length = Convert.ToInt32(Console.ReadLine());
  17. double width = Convert.ToInt32(Console.ReadLine());
  18. Shape rectangle = new Rectangle(length, width);
  19. double rectangleArea = rectangle.Area();
  20. double rectanglePerimeter = rectangle.Perimeter();
  21. Console.WriteLine("矩形的面积为:{0},矩形的周长为:{1}", rectangleArea, rectanglePerimeter);
  22. //2、模拟移动硬盘、U盘、MP3插到电脑上读写数据
  23. //通过Computer含参数方法实现
  24. //1、
  25. //MobileDisk md = new MobileDisk();
  26. //UDisk ud = new UDisk();
  27. MP3 mp3 = new MP3();
  28. //Computer c = new Computer();
  29. //c.CpuRead(md);
  30. //c.CpuWrite(md);
  31. mp3.PlayMusic();
  32. //2、
  33. //MobileStorage ms = new UDisk();
  34. //Computer cpu = new Computer();
  35. //cpu.CpuRead(ms);
  36. //cpu.CpuWrite(ms);
  37. MobileStorage ms = new UDisk();
  38. Computer cpu = new Computer();
  39. cpu.Ms = ms;
  40. cpu.CpuRead();
  41. cpu.CpuWrite();
  42. Console.ReadKey();
  43. }
  44. }
  45. }

练习一的类:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. namespace _084_抽象类练习
  5. {
  6. abstract class Shape
  7. {
  8. public abstract double Perimeter();
  9. public abstract double Area();
  10. }
  11. }
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Text;
  15. namespace _084_抽象类练习
  16. {
  17. class Circle : Shape
  18. {
  19. private double _radius;
  20. public double Radius
  21. {
  22. get { return _radius; }
  23. set { _radius = value; }
  24. }
  25. public Circle(double r)
  26. {
  27. this._radius = r;
  28. }
  29. public override double Area()
  30. {
  31. return Math.PI * this._radius * this._radius;
  32. }
  33. public override double Perimeter()
  34. {
  35. return Math.PI * this._radius * 2;
  36. }
  37. }
  38. }
  39. using System;
  40. using System.Collections.Generic;
  41. using System.Text;
  42. namespace _084_抽象类练习
  43. {
  44. class Rectangle : Shape
  45. {
  46. private double _length;
  47. public double Length
  48. {
  49. get { return _length; }
  50. set { _length = value; }
  51. }
  52. private double _width;
  53. public double Width
  54. {
  55. get { return _width; }
  56. set { _width = value; }
  57. }
  58. public Rectangle(double l,double w)
  59. {
  60. this.Length = l;
  61. this.Width = w;
  62. }
  63. public override double Area()
  64. {
  65. return this.Length * this.Width;
  66. }
  67. public override double Perimeter()
  68. {
  69. return (this.Length + this.Width) * 2;
  70. }
  71. }
  72. }

练习二的类:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. namespace _084_抽象类练习
  5. {
  6. abstract class MobileStorage
  7. {
  8. public abstract void Read();
  9. public abstract void Write();
  10. }
  11. }
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Text;
  15. namespace _084_抽象类练习
  16. {
  17. class MobileDisk : MobileStorage
  18. {
  19. public override void Read()
  20. {
  21. Console.WriteLine("移动硬盘在读取数据");
  22. }
  23. public override void Write()
  24. {
  25. Console.WriteLine("移动硬盘在写入数据");
  26. }
  27. }
  28. }
  29. using System;
  30. using System.Collections.Generic;
  31. using System.Text;
  32. namespace _084_抽象类练习
  33. {
  34. class UDisk : MobileStorage
  35. {
  36. public override void Read()
  37. {
  38. Console.WriteLine("U盘在读取数据");
  39. }
  40. public override void Write()
  41. {
  42. Console.WriteLine("U盘在写入数据");
  43. }
  44. }
  45. }
  46. using System;
  47. using System.Collections.Generic;
  48. using System.Text;
  49. namespace _084_抽象类练习
  50. {
  51. class MP3 : MobileStorage
  52. {
  53. public override void Read()
  54. {
  55. Console.WriteLine("MP3在读取数据");
  56. }
  57. public override void Write()
  58. {
  59. Console.WriteLine("MP3在写入数据");
  60. }
  61. public void PlayMusic()
  62. {
  63. Console.WriteLine("MP3在放音乐");
  64. }
  65. }
  66. }
  67. using System;
  68. using System.Collections.Generic;
  69. using System.Text;
  70. namespace _084_抽象类练习
  71. {
  72. class Computer
  73. {
  74. private MobileStorage _ms;
  75. public MobileStorage Ms
  76. {
  77. get { return _ms; }
  78. set { _ms = value; }
  79. }
  80. public void CpuRead()
  81. {
  82. Ms.Read();
  83. }
  84. public void CpuWrite()
  85. {
  86. Ms.Write();
  87. }
  88. //使用方法来实现
  89. //public void CpuRead(MobileStorage ms)
  90. //{
  91. // ms.Read();
  92. //}
  93. //public void CpuWrite(MobileStorage ms)
  94. //{
  95. // ms.Write();
  96. //}
  97. }
  98. }