C#多态详解

编辑: admin 分类: c#语言 发布时间: 2021-11-25 来源:互联网
目录
  • 1.定义
  • 2.实现多态的两个因素
  • 3.案例
  • 4、使用多态的好处
  • 5、string类
    • 1、值类型
    • 2、引用类型
  • 6.运算符重载:
    • 总结

      1.定义

      多态是同一个行为具有多个不同表现形式或形态的能力。

      多态性意味着有多重形式。在面向对象编程范式中,多态性往往表现为"一个接口,多个功能"。

      多态性可以是静态的或动态的。在静态多态性中,函数的响应是在编译时发生的。在动态多态性中,函数的响应是在运行时发生的。

      静态多态性:在编译时,方法和对象的连接机制被称为早期绑定,也被称为静态绑定。C# 提供了两种技术来实现静态多态性。分别为:方法重载、运算符重载

      动态多态性是通过 抽象类 和 虚方法 实现的。

      在 C# 中,每个类型都是多态的,因为包括用户定义类型在内的所有类型都继承自 Object。

      多态就是同一个接口,使用不同的实例而执行不同操作,如图所示:

      2.实现多态的两个因素

      1)子类重写父类方法

      2)使用父类的类型(子类转换为父类:向上转型)

      class Animal
      {
      public virtual void call() {
      Console.WriteLine("无声的叫唤");
      }
      }
      
      class Dog : Animal
      {
      // new的作用是隐藏父类的同名方法
      //public new void call() {
      //Console.WriteLine("叫声:汪~汪~汪~");
      //}
      
      public override void call() {
      Console.WriteLine("叫声:汪~汪~汪~");
      }
      public void smell() {
      Console.WriteLine("嗅觉相当不错!");
      }
      }
      
      Animal animal = new Dog(); //向上转型
      animal.call();
      

      向上转型:将子类对象转为父类对象。此处父类对象可以是接口或抽象类。

      转化后的父类对象具有父类所有方法,若方法被子类重写override,那么实际调用时,调用的是重写后的实现。

      int a=(int)3.5;
      Dog dog = (Dog)animal;//向下转型
      dog.call();
      dog.smell();
      

      向下转型:把父类对象转为子类对象。

      转化后的子类对象,跟一般的继承子类对象一样。具有子类所有方法(包括重写方法)+父类所有方法(被重写的方法,按重写的算。)

      3.案例

      public class Shape
      {
      public int X { get; private set; }
      public int Y { get; private set; }
      public int Height { get; set; }
      public int Width { get; set; }
      // 虚方法
      
      public virtual void Draw()
      {
      Console.WriteLine("执行基类的画图任务");
      }
      }
      ​
      
      class Circle : Shape
      {
      public override void Draw()
      {
      base.Draw();
      Console.WriteLine("画一个圆形");
      }
      }
      
      class Rectangle : Shape
      {
      public override void Draw()
      {
      base.Draw();
      Console.WriteLine("画一个长方形");
      }
      }
      
      class Triangle : Shape
      {
      public override void Draw()
      {
      base.Draw();
      Console.WriteLine("画一个三角形");
      }
      }
      ​
      
      class Program
      {
      static void Main(string[] args)
      {
      Shape circle=new Circle();
      circle.Draw();
      Shape rectangle=new Rectangle();
      rectangle.Draw();
      Shape triangle=new Triangle();
      triangle.Draw();
      }
      }
      

      父类做返回值

      class Person
      {
      public virtual void Eat()
      {
      
      }
      }
      
      class WhitePerson:Person
      {
      public override void Eat()
      {
      Console.WriteLine("热狗");
      }
      }
      
      class YellowPerson:Person
      {
      public override void Eat()
      {
      Console.WriteLine("饺子");
      }
       
      //写一个GetPerson方法,返回值为父类,
      //根据传入的不同人种来确定吃什么
      
      Person GetPerson(string s)
      {
      Person p=null;
      if (s.Equals("中国人"))
      {
      p = new YellowPerson();
      }
      else if (s.Equals("外国人"))
      {
      p= new WhitePerson();
      }
      else
      {
      return p;
      }
      p.Eat();
      return p;
      }
      }
      

      父类做参数

      class Animal
      {
      public virtual void Swimming()
      {
      Console.WriteLine("动物游泳");
      }
      }
      
      class Cat:Animal
      {
      public override void Swimming()
      {
      Console.WriteLine("猫挠");
      }
      
      //写一个方法,完成动物游泳(对象做参数)
      void GetSwimming(Animal a)//a是引用
      {
      if (a is Cat)
      {
      Cat c = (Cat)a;//向下转型
      c.Swimming();
      }
      }
      
      static void Main(string[] args)
      {
      Cat c = new Cat();
      Dog d = new Dog();
      Animal a = c;
      // Animal a = d;
      c.GetSwimming(a);
      }
      }
      static void Main(string[] args)
      {
      Cat c = new Cat();
      Dog d = new Dog();
      Animal a = c;
      // Animal a = d;
      c.GetSwimming(a);
      }
      }
      

      4、使用多态的好处

      1. 应用程序不必为每一个派生类编写功能调用,只需要对抽象基类进行处理即可。大大提高程序的

      可复用性。//继承
      2. 派生类的功能可以被基类的方法或引用变量所调用,这叫向后兼容,可以提高可扩充性和可维护

      性。 //多态的真正作用

      5、string类

      ==和Equals的区别

      1、值类型

      ==和Equals比较的内容都是一致的,都是比较内容

      string a = "123";//值

      Console.WriteLine(a=="123");

      Console.WriteLine(a.Equals("123"));

      2、引用类型

      ==: 比较首地址是否相等 Equals:比较的是值是否相等

      char[] x={'1','2','3'};

      string b = new string(x);//引用

      Console.WriteLine(b=="123");

      Console.WriteLine(b.Equals("123"));

      1)字符串的比较

      Compare(str1, str2)
      str1.CompareTo(str2)
      string a = "hello",b="Hello",c="hello";
      Console.WriteLine(a.CompareTo(b));//-1
      Console.WriteLine(string.Compare(a,b));//-1
      Console.WriteLine(a.CompareTo(c));//0
      

      字符串的查找

      (1)Contains(Findstr):找指定字符串是否包含一个字串Findstr,返回值的bool类型,即只有

      true和false。

      (2)IndexOf(Findstr):查找FindStr在字符串中第一次出现的位置,返回值为第一次出现

      的下标,没有找到则返回-1.

      (3)LastIndexOf(FindStr):查找FindStr在字符串中最后一次出现的位置,返回值为最后

      一次出现的下标,没有找到则返回-1。

      Console.WriteLine(a.Contains("lo"));//true
      Console.WriteLine(a.IndexOf('e'));//1
      Console.WriteLine(a.LastIndexOf('l'));//3
      

      字符串的截取

      SubString(StartIndex):字符串中下标从StartIndex开始后面的全部字符串。
      SubString(StartIndex, Len):字符串中下标从StartIndex开始后面的Len个长度的字符串。
      Console.WriteLine(a.Substring(1));//ello
      Console.WriteLine(a.Substring(1,3));//ell
      

      字符串的分割

      Split(SplitCh):将字符串按SplitCh进行分割,它的返回值是一个字符串数组。
      string d="锄禾日当午#汗滴禾下土#谁知盘中餐#粒粒皆辛苦";
      string[] e = d.Split('#');
      for (int i = 0; i < e.Length; i++)
      {
      Console.WriteLine(e[i]);
      }
      

      字符串的合并

      string.Concat(str1, str2, …., strn):将n个字符串连接,中间没有连接符
      “+”连接符号
      string f = "world";
      Console.WriteLine(a+f);
      Console.WriteLine(1+2+3+a);//6hello
      Console.WriteLine(a+1+2+3);//hello123
      Console.WriteLine(string.Concat(a,f));//helloworld
      

      字符串的替换

      Replace(oldStr, newStr):用newStr来替换字符串中的oldStr
      Console.WriteLine(a.Replace("he","HE"));//HEllo
      

      字符串的插入

      Insert(index, str):index是需要插入的位置,str是要插入的字符
      Console.WriteLine(a.Insert(1,"ww"));//hwwello
      

      字符串的删除

      Trim():删除字符串中开始和结尾处的空格
      Remove(Start):Start为需要删除的起始位置,该方法是将位置后的所有字符全部删除
      Remove(Start, Len):Len是指需要删除的长度,与上面格式不同的是它是从起始位置开始
      

      删除Len个字符

      string s = " aaa bbb ccc ";
      Console.WriteLine(s.Trim());//aaa bbb ccc
      Console.WriteLine(s.Remove(6));// aaa b
      Console.WriteLine(s.Remove(2,7));// aaccc
      

      9)字符串的大小写转换

      ToLower():将字符串转化为小写形式
      ToUpper():将字符串转换威大写形式

      10)string.Format()

      string.Format("{0:d}",System.DateTime.Now) //结果为:2021-3-23 (月份位置不是03)
      string.Format("{0:D}",System.DateTime.Now) //结果为:2021年3月23日
      string.Format("{0:f}",System.DateTime.Now) //结果为:2021年3月23日 15:37
      string.Format("{0:F}",System.DateTime.Now) //结果为:2021年3月23日 15:37:52
      string.Format("{0:g}",System.DateTime.Now) //结果为:2021-3-23 15:38
      string.Format("{0:G}",System.DateTime.Now) //结果为:2021-3-23 15:39:27
      string.Format("{0:m}",System.DateTime.Now) 【转自:http://www.1234xp.com/kt.html 转载请说明出处】//结果为:3月23日
      string.Format("{0:t}",System.DateTime.Now) //结果为:15:41
      string.Format("{0:T}",System.DateTime.Now) //结果为:15:41:5
      

      6.运算符重载:

      关键字 abstract 声明抽象类:用于接口部分类的实现(派生类继承抽象类时,实现完成)。抽象类包含抽象方法,抽象方法可被派生类实现。

      抽象类规则:

      1.不能创建抽象类的实例

      2.不能在抽象类外定义抽象方法

      3.不能把抽象类声明为sealed(类前带关键字sealed代表该类是密封类,不能被继承)

      关键字virtual声明虚方法:用于方法在继承类中的实现(在不同的继承类中有不同的实现)。

      抽象类和虚方法共同实现动态多态性。

      注:继承类中的重写虚函数需要声明关键字 override,在方法参数传入中写(类名 形参名)例如 public void CallArea(Shape sh),意思是传入一个 shape 类型的类。

      总结

      本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注海外IDC网的更多内容!

      /r/n【文章原创作者:高防服务器ip】