zoukankan      html  css  js  c++  java
  • 谈谈我对C# 多态的理解

    面向对象三要素:封装、继承、多态。
    封装和继承,这两个比较好理解,但要理解多态的话,可就稍微有点难度了。今天,我们就来讲讲多态的理解。
    我们应该经常会看到面试题目:请谈谈对多态的理解。
    其实呢,多态非常简单,就一句话:调用同一种方法产生了不同的结果
    具体实现方式有三种。

    一、重载

    重载很简单。

    public string GetValue(string x)
    {
          return x;
    }
    public string GetValue(string x, string y)
    {
          return x+y;
    }
    //调用
    string myValue=GetValue("测试");
    string myValue2=GetValue("测试","方法");//调用了GetValue同一种方法,只是多了个参数,但还是算得上“同一种方法”。
    

    二、重写父类中的虚方法

    public class BaseClass
    {
          public virtual void GetValue() //virtual关键字,供后面的子类重写该方法
          {
                Console.WriteLine("这是个虚方法");
          }
    }
    public class MyClass: BaseClass
    {
          public override void GetValue()
          {
                Console.WriteLine("MyClass重写了基类的虚方法");
          }
    }
    public class NewClass: BaseClass
    {
          public override void GetValue()
          {
                Console.WriteLine("NewClass重写了基类的方法");
          }
    }
    
    public class Program
    {
          static void Main()
          {
                BaseClass baseClass=new BaseClass();
                MyClass myClass=new MyClass();
                NewClass newClass=new NewClass();
                //在这里你会无意间想到一句很经典的话:不同的对象调用了同一种方法产生了不同的行为
                baseClass.GetValue();//这是个虚方法
                myClass.GetValue();//MyClass重写了基类的虚方法
                newClass.GetValue();//NewClass重写了基类的方法     
          }
    }
    

    关于继承,还是要谈一下is和as运算符的
    我们都知道,所有的类都是默认继承System.Object这个类的,也就是说所有的类都可以转化为Object。子类可以转换为父类,毕竟子类就属于父类。
    在上面这个例子,MyClass类是继承BaseClass类的,也就是说MyClass可以转为BaseClass。可能,我们会想到强制转换 baseClass=(BaseClass)myClass,这样做是可以的,但如果myClass继承的不是BaseClass则会抛出异常,这样不好。这时,应该用as与is运算符,BaseClass baseClass = myClass as BaseClass,这句话,如果运行出错的话,会将null赋值给baseClass,也就是说,在使用baseClass这个对象之前,我们只需判断是否为空就行了。

    MyClass myClass = new MyClass();
    BaseClass baseClass = myClass as BaseClass;//即使转换的不会,只会将null赋值给baseClass,不会抛出异常。
    if (baseClass != null)//只需判断一下是否为空即可
    {
          baseClass.GetValue();
    }
    if(myClass is baseClass)
    {
          Console.WriteLine("myClass是属于baseClass的");
    }
    

    三、实现抽象类中的方法,也是使用的override关键字

    老生常谈,抽象类是不可以实例化的,抽象类的目的就是为了让其他类继承,而且只能继承一个类,如果想要实现多重继承,便诞生了接口。

    public abstract class BaseClass
    {
          public abstract void GetValue();//抽象方法,不能有方法实体
          public void GetValue2()
          {
                Console.WriteLine("实体方法");//抽象类可以有实体方法,抽象类是不可以实例化的,但他的子类的实例可以调用这个方法
          }
    }
    public class MyClass: BaseClass
    {
          public override void GetValue()
          {
                Console.WriteLine("MyClass重写了基类的虚方法");
          }
    }
    public Class NewClass: BaseClass
    {
          public override void GetValue()
          {
                Console.WriteLine("NewClass重写了基类的方法");
          }
    }
    
    public class Program
    {
          static void Main()
          {
                MyClass myClass=new MyClass();
                NewClass newClass=new NewClass();
                myClass.GetValue();
                myClass.GetValue2();//子类的实例可以调用这个方法
                newClass.GetValue();          
          }
    }
    

    总结

    注意点:
    1、好好体会多态的实现,渐渐地会发现面向对象程序设计的魅力。

    2、抽象类的目的就是为了继承,想要实现多重继承,就需要接口了。

    3、抽象类不可以实例化,它是可以有实体方法的,继承这个抽象类的实例可以调用抽象类里面的实体方法。

    4、会熟练使用is和as运算符,不要一味地使用强制转换

  • 相关阅读:
    如何输出高精度时间差
    GetThreadTimes获取其它线程cpu时间
    12-Python基础之类与面向对象
    10-Python函数之递归
    09-Python基础之内置函数与匿名函数
    08-Python基础之迭代器与生成器
    07-Python基础之装饰器
    06-Python基础之函数进阶(嵌套,作用域)
    05-Python基础之函数基础
    04-Python基础之文件操作基础
  • 原文地址:https://www.cnblogs.com/ywjbokeyuan/p/13035462.html
Copyright © 2011-2022 走看看