19.virtual,override,base

19.面向对象-多态-vob


19.1 知识点

知识回顾

封装

class ClassName
{
    #region 特征——成员变量
    #endregion
    #region 行为——成员方法
    #endregion
    #region 初始化调用——构造函数
    #endregion
    #region 释放时调用——析构函数
    #endregion
    #region 保护成员变量——成员属性
    #endregion
    #region 像数组一样使用——索引器
    #endregion
    #region 类名点出使用——静态成员
    #endregion
    #region 自定义对象可计算——运算符重载
    #endregion
}
#region 静态类和静态构造函数
#endregion
#region 拓展方法
#endregion

继承

#region 继承中的构造函数
#endregion
#region 里氏替换原则
#endregion
#region 万物之父
#endregion
#region 装箱拆箱
#endregion
#region 密封类
#endregion

多态的概念

  • 多态按字面的意思就是“多种状态”
  • 让继承同一父类的子类们在执行相同方法时有不同的表现(状态)
  • 主要目的:同一父类的对象执行相同行为(方法)有不同的表现
  • 解决的问题:让同一个对象有唯一行为的特征
  • vob是多态中三个关键字的首字母:virtual,override,base

没有多态时遇到的问题

示例代码

class Father
{
    public void SpeakName()
    {
        Console.WriteLine("Father的说话");
    }
}

class Son : Father
{
    public new void SpeakName()
    {
        Console.WriteLine("Son的说话");
    }
}

主函数

Father son1 = new Son();
son1.SpeakName();               // 输出:Father的说话
(son1 as Son).SpeakName();      // 输出:Son的说话
  • 没有多态时,同一个对象可能有不同的行为特征,给人感觉不是同一个对象
  • 想让对象有唯一的行为特征,要用到多态

多态的使用

示例代码

class GameObject
{
    public string name;

    public GameObject(string name)
    {
        this.name = name;
    }

    public virtual void Attack()
    {
        Console.WriteLine("游戏对象进行攻击");
    }
}

class Player : GameObject
{
    public Player(string name) : base(name)
    {
    }

    public override void Attack()
    {
        base.Attack();
        Console.WriteLine("玩家进行攻击");
    }
}

class Monster : GameObject
{
    public Monster(string name) : base(name)
    {
    }

    public override void Attack()
    {
        Console.WriteLine("怪物进行攻击");
    }
}

主函数

GameObject player1 = new Player("韬老狮");
player1.Attack();                           // 输出:游戏对象进行攻击 玩家进行攻击
(player1 as Player).Attack();               // 输出:游戏对象进行攻击 玩家进行攻击

GameObject monster1 = new Monster("小怪物");
monster1.Attack();                          // 输出:怪物进行攻击
(monster1 as Monster).Attack();             // 输出:怪物进行攻击

总结

  • 多态:让同一类型的对象,在执行相同行为时有不同的表现
  • 解决的问题:让同一对象有唯一的行为特征
  • vob 特点:
    • vo 一定是结合使用的,来实现多态
    • b 是否使用根据实际需求,保留父类行为

19.2 知识点代码

using System;

namespace Lesson17_多态_vob
{
    #region 知识回顾

    #region 封装——用程序语言来形容对象
    class 类名
    {
        #region 特征——成员变量

        #endregion

        #region 行为——成员方法

        #endregion

        #region 初始化调用——构造函数

        #endregion

        #region 释放时调用——析构函数

        #endregion

        #region 保护成员变量——成员属性

        #endregion

        #region 像数组一样使用——索引器

        #endregion

        #region 类名点出使用——静态成员

        #endregion

        #region 自定义对象可计算——运算符重载

        #endregion
    }

    #region 静态类和静态构造函数

    #endregion

    #region 拓展方法

    #endregion
    #endregion

    #region 继承——复用封装对象的代码;儿子继承父亲,复用现成代码

    #region 继承中的构造函数

    #endregion

    #region 里氏替换原则

    #endregion

    #region 万物之父

    #endregion

    #region 装箱拆箱

    #endregion

    #region 密封类

    #endregion

    #endregion

    #endregion

    #region 知识点一 多态的概念
    // 多态按字面的意思就是“多种状态”
    // 让继承同一父类的子类们 在执行相同方法时有不同的表现(状态)
    // 主要目的:同一父类的对象 执行相同行为(方法)有不同的表现
    // 解决的问题:让同一个对象有唯一行为的特征
    #endregion

    //class语句块外 namespace语句块内

    #region 知识点二 没有多态时遇到的问题

    //没有多态时 同一个对象可能有不同的行为特征 给人感觉不是同一个对象
    class Father
    {
        public void SpeakName()
        {
            Console.WriteLine("Father的说话");
        }
    }

    class Son:Father
    {
        //没学多态前 子类只能覆盖掉父类的同名方法来实现自己的同名方法
        public new void SpeakName()
        {
            Console.WriteLine("Son的说话");
        }
    }

    #endregion

    #region 知识点三 多态的使用

    //我们目前已经学过的多态:编译时多态——函数重载,开始就写好的
    //我们将学习的:运行时多态( vob、抽象函数、接口 )

    //我们今天学习 vob 三个关键字
    //v: virtual(虚函数)
    //o: override(重写)
    //b: base(父类)

    class GameObject
    {
        public string name;
        public GameObject(string name)
        {
            this.name = name;
        }

        //虚函数 可以被子类重写
        public virtual void Attack()
        {
            Console.WriteLine("游戏对象进行攻击");
        }
    }

    class Player:GameObject
    {
        public Player(string name):base(name)
        {

        }

        //override 重写虚函数
        public override void Attack()
        {
            //base的作用
            //代表父类 可以通过base来保留父类的行为
            base.Attack();//游戏对象进行攻击
            Console.WriteLine("玩家进行攻击");
        }
    }

    class Monster:GameObject
    {
        public Monster(string name):base(name)
        {

        }

        public override void Attack()
        {
            Console.WriteLine("怪物进行攻击");
        }
    }

    #endregion

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("多态vob");

            //主函数内

            #region 知识点二 没有多态时遇到的问题

            Father son1 = new Son();//里氏替换原则 父类装子类
            //拿父类装的时候 输出的是 Father的说话 转成子类装的时候 输出的是 Son的说话
            son1.SpeakName();//Father的说话
            (son1 as Son).SpeakName();//Son的说话

            //同一个对象有两个行为的特征 给人感觉不是同一个对象
            //想让对象有唯一的行为的特征 要用到多态

            #endregion

            #region 知识点三 多态的使用

            GameObject player1 = new Player("韬老狮");//里氏替换原则 父类装子类
            //无论拿父类装还是转成子类装 都输出 游戏对象进行攻击 玩家进行攻击
            player1.Attack();//游戏对象进行攻击 玩家进行攻击
            (player1 as Player).Attack();//游戏对象进行攻击 玩家进行攻击

            GameObject monster1 = new Monster("小怪物");
            //重写的虚函数没有base.Attack(); 所以没有输出游戏对象进行攻击
            monster1.Attack();//怪物进行攻击
            (monster1 as Monster).Attack();//怪物进行攻击

            #endregion
        }
    }

    //总结:
    //多态:让同一类型的对象,执行相同行为时有不同的表现
    //解决的问题:让同一对象有唯一的行为特征
    //vob:
    // v:virtual 虚函数
    // o:override 重写
    // b:base 父类
    //vob特点:
    // v和o一定是结合使用的 来实现多态
    // b是否使用根据实际需求 保留父类行为
}

19.3 练习题

真的鸭子嘎嘎叫,木头鸭子吱吱叫,橡皮鸭子唧唧叫,用多态实现

class语句块外 namespace语句块内

// 鸭子类
class Duck
{
    public virtual void Speak()
    {
        Console.WriteLine("嘎嘎叫");
    }
}

// 木头鸭子类,继承自Duck
class WoodDuck : Duck
{
    public override void Speak()
    {
        Console.WriteLine("吱吱叫");
    }
}

// 橡皮鸭子类,继承自Duck
class RubberDuck : Duck
{
    public override void Speak()
    {
        Console.WriteLine("唧唧叫");
    }
}

主函数内

// 主函数内
Duck duck = new Duck();
duck.Speak();//嘎嘎叫

WoodDuck woodDuck = new WoodDuck();
woodDuck.Speak();//吱吱叫

RubberDuck rubberDuck = new RubberDuck();
rubberDuck.Speak();//唧唧叫

所有员工9点打卡,但经理十一点打卡,程序员不打卡,用多态实现

class语句块外 namespace语句块内

// 员工类
class Staff
{
    public virtual void PunchTheClock()
    {
        Console.WriteLine("9点打卡");
    }
}

// 经理类,继承自Staff
class Manager : Staff
{
    public override void PunchTheClock()
    {
        Console.WriteLine("11点打卡");
    }
}

// 程序员类,继承自Staff
class Programmer : Staff
{
    public override void PunchTheClock()
    {
        Console.WriteLine("老子不打卡");
    }
}

主函数内

// 主函数内
Staff staff = new Staff();
staff.PunchTheClock();//9点打卡

Manager manager = new Manager();
manager.PunchTheClock();//11点打卡

Programmer programmer = new Programmer();
programmer.PunchTheClock();//老子不打卡

创建一个图形类,有求面积和周长两个方法

创建矩形类,正方形类,圆形类继承图形类
实例化矩形、正方形、圆形对象求面积和周长

class语句块外 namespace语句块内

// 图形类
class Graph
{
    public virtual float GetLength()
    {
        return 0;
    }

    public virtual float GetArea()
    {
        return 0;
    }
}

// 矩形类,继承自Graph
class Rect : Graph
{
    private float w;
    private float h;

    public Rect(float w, float h)
    {
        this.w = w;
        this.h = h;
    }

    public override float GetLength()
    {
        return 2 * (w + h);
    }

    public override float GetArea()
    {
        return w * h;
    }
}

// 正方形类,继承自Graph
class Square : Graph
{
    private float l;

    public Square(float l)
    {
        this.l = l;
    }

    public override float GetLength()
    {
        return 4 * l;
    }

    public override float GetArea()
    {
        return l * l;
    }
}

// 圆形类,继承自Graph
class Circular : Graph
{
    private float r;

    public Circular(float r)
    {
        this.r = r;
    }

    public override float GetLength()
    {
        return 2 * 3.14f * r;
    }

    public override float GetArea()
    {
        return 3.14f * r * r;
    }
}

主函数内

// 主函数内
Rect rect = new Rect(2, 3);
Console.WriteLine(rect.GetArea());//6
Console.WriteLine(rect.GetLength());//10

Square square = new Square(4);
Console.WriteLine(square.GetArea());//16
Console.WriteLine(square.GetLength());//16

Circular circular = new Circular(2);
Console.WriteLine(circular.GetArea());//12.56
Console.WriteLine(circular.GetLength());//12.56

19.4 练习题代码

using System;

namespace Lesson17_练习题
{
    //class语句块外 namespace语句块内

    #region 练习题一
    //真的鸭子嘎嘎叫,木头鸭子吱吱叫,橡皮鸭子唧唧叫,用多态实现

    //鸭子类
    class Duck
    {
        public virtual void Speak()
        {
            Console.WriteLine("嘎嘎叫");
        }
    }
    //木头鸭子类
    class WoodDuck : Duck
    {
        public override void Speak()
        {
            Console.WriteLine("吱吱叫");
        }
    }
    //橡皮鸭子类
    class RubberDuck : Duck
    {
        public override void Speak()
        {
            Console.WriteLine("唧唧叫");
        }
    }

    #endregion

    #region 练习题二
    //所有员工9点打卡,但经理十一点打卡,程序员不打卡,用多态实现

    //员工类
    class Staff
    {
        public virtual void PunchTheClock()
        {
            Console.WriteLine("9点打卡");
        }
    }
    //经理类
    class Manager : Staff
    {
        public override void PunchTheClock()
        {
            Console.WriteLine("11点打卡");
        }
    }
    //程序员类
    class Programmer : Staff
    {
        public override void PunchTheClock()
        {
            Console.WriteLine("老子不打卡");
        }
    }
    #endregion

    #region 练习题三
    //创建一个图形类,有求面积和周长两个方法
    //创建矩形类,正方形类,圆形类继承图形类
    //实例化矩形、正方形、圆形对象求面积和周长

    //图形类
    class Graph
    {
        public virtual float GetLength()
        {
            return 0;
        }

        public virtual float GetArea()
        {
            return 0;
        }
    }
    //矩形类
    class Rect : Graph
    {
        private float w;
        private float h;

        public Rect(int w, int h)
        {
            this.w = w;
            this.h = h;
        }
        public override float GetLength()
        {
            return 2 * (w + h);
        }

        public override float GetArea()
        {
            return w * h;
        }
    }
    //正方形类
    class Square : Graph
    {
        private float l;

        public Square(int l)
        {
            this.l = l;
        }

        public override float GetLength()
        {
            return 4 * l;
        }

        public override float GetArea()
        {
            return l * l;
        }
    }
    //圆形类
    class Circular : Graph
    {
        private float r;

        public Circular(float r)
        {
            this.r = r;
        }

        public override float GetLength()
        {
            return 2 * 3.14f * r;
        }

        public override float GetArea()
        {
            return 3.14f * r * r;
        }
    }

    #endregion
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("多态vob练习题");
            //主函数内

            #region 练习题一

            Duck duck = new Duck();
            duck.Speak();//嘎嘎叫

            WoodDuck woodDuck = new WoodDuck();
            woodDuck.Speak();//吱吱叫

            RubberDuck rubberDuck = new RubberDuck();
            rubberDuck.Speak();//唧唧叫

            #endregion

            #region 练习题二

            Staff staff = new Staff();
            staff.PunchTheClock();//9点打卡

            Manager manager = new Manager();
            manager.PunchTheClock();//11点打卡

            Programmer programmer = new Programmer();
            programmer.PunchTheClock();//老子不打卡

            #endregion

            #region 练习题三

            Rect rect = new Rect(2, 3);
            Console.WriteLine(rect.GetArea());//6
            Console.WriteLine(rect.GetLength());//10

            Square square = new Square(4);
            Console.WriteLine(square.GetArea());//16
            Console.WriteLine(square.GetLength());//16

            Circular circular = new Circular(2);
            Console.WriteLine(circular.GetArea());//12.56
            Console.WriteLine(circular.GetLength());//12.56

            #endregion
        }
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏