C#基础9:虚函数与多态

 

PS:注释和讲解全在代码中

  • 虚方法等同于虚函数
  • 抽象方法等同于纯虚函数

1. 虚函数与里氏转换原则

虚方法使用细节:

  • 将父类的方法标记为虚方法,就是在父类方法的返回值前加virtual关键字,表示这个方法可以被子类重写
  • 子类重写父类方法:在子类的方法的返回值前加override关键字,当然子类也可以不重写,或者是用new隐藏
  • 父类中用virtual修饰的方法,可以在子类重写该的方法中,使用base关键字先调用父类中的该方法

里氏转换原则:

  • 子类对象可以直接赋值给父类变量
  • 子类对象可以调用父类中的成员,但是父类对象永远只能调用自己的成员
  • 如果父类对象中装的是子类对象,可以将这个父类对象强转为子类对象
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace C4_程序设计
{
    class Father
    {
        public virtual void Print()     //虚函数当然不能是私有的
        {
            Console.WriteLine("Father!");
        }
    }
    class SonA: Father
    {
        public override void Print()
        {
            //base.Print();           //可以用base.访问父类的函数/变量
            Console.WriteLine("SonA!");
        }
    }
    class SonB: Father
    {
        public new void Print()
        {
            Console.WriteLine("SonB!");
        }
    }
    class GrandsonA: SonA
    {
        public override void Print()
        {
            Console.WriteLine("Grandson!");
        }
    }
    class GrandsonB: SonA
    {
        public new void Print()
        {
            Console.WriteLine("Grandson!");
        }
    }
    class 虚函数与里氏转换原则
    {
        static void Main()
        {
            Father fa = new Father();
            Father me = new SonA();     //me的申明类是Father,实例类是SonA
            Father you = new SonB();
            fa.Print();         //Father!
            me.Print();         //SonA!             //体现了多态性
            you.Print();        //Father!           //申明类不是SonB,所以SonB的new Print()当然不会起效,这也是new(隐藏)和override(重写)的区别

            me = new GrandsonA();
            me.Print();       //Grandson!
            you = new GrandsonB();
            you.Print();        //SonA!
            //you.Print流程如下:先检测申明类Father → 检测到虚函数 → 转去检查实例类GrandsonB,发现并没有override重写
                               //→再转去检查它的父类,也就是SonA,找到override,执行函数输出SonA!
            GrandsonB text = (GrandsonB)you;        //里氏转换原则③
            text.Print();       //Grandson!

            //is关键字:判断当前变量是否可以是当前类的对象,也就是是否可以强制转换成功,返回bool
            Console.WriteLine(you is GrandsonB);            //True
            Console.WriteLine(you is Father);               //True
            Console.WriteLine(you is GrandsonA);            //False

            //as关键字:判断当前变量是否可以是当前类的对象,也就是是否可以强制转换成功,成功返回对应对象,失败返回null
            fa.Print();     //Father!
            fa = you as GrandsonB;
            fa.Print();     //SonA!
        }
    }
}

 

2. 抽象类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace C4_程序设计
{
    //抽象类中不一定要有抽象方法,但是抽象方法必须存在于抽象类中
    abstract class Base     //在定义类的关键字class前面加abstract修饰的类就是抽象类,抽象类不可以实例化
    {
        public abstract void Dis();     //抽象方法
        public virtual void Dis2()
        {
            Console.WriteLine("虚函数");
        }
        public void Dis3()
        {
            Console.WriteLine("普通函数");
        }
    }
    class Text: Base
    {
        public override void Dis()      //子类继承抽象类,必须使用override关键字重写父类中所有的抽象方法
        {
            Console.WriteLine("纯虚函数");
        }
        public override void Dis2()
        {
            Console.WriteLine("虚函数->子类");
        }
        public new void Dis3()
        {
            Console.WriteLine("普通函数->子类");
        }
    }
    class 抽象类
    {
        static void Main()
        {
            Base me = new Text();
            me.Dis();
            me.Dis2();
            me.Dis3();
        }
    }
}
/*
纯虚函数
虚函数->子类
普通函数
*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值