Unity基础之C#核心篇笔记4:多态

多态

1.多态的概念

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

2.解决的问题

//让同一个对象有唯一行为的特征
class Father
    {
        public void SpeakName()
        {
            Console.WriteLine("Father的方法");
        }
    }

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

3.多态的实现

    //我们目前已经学过的多态
    //编译时多态——函数重载,开始就写好的

    //我们将学习的:
    //运行时多态( vob、抽象函数、接口 )
    //我们今天学习 vob
    //v: virtual(虚函数)
    //o: override(重写)
    //b: base(父类)
        class GameObject
    {
        public string name;
        public GameObject(string name)
        {
            this.name = name;
        }

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

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

        }

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

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

        }

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

    #endregion

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

            #region 解决的问题
            Father f = new Son();
            f.SpeakName();
            (f as Son).SpeakName();
            #endregion

            #region 多态的使用
            GameObject p = new Player("唐老狮");
            p.Atk();
            (p as Player).Atk();

            GameObject m = new Monster("小怪物");
            m.Atk();
            (m as Monster).Atk();
            #endregion
        }
    }

4.总结

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

抽象类和抽象方法

1.抽象类

    //概念
    //被抽象关键字abstract修饰的类
    //特点:
    //1.不能被实例化的类
    //2.可以包含抽象方法
    //3.继承抽象类必须重写其抽象方法
     abstract class Thing
    {
        //抽象类中 封装的所有知识点都可以在其中书写
        public string name;
        //可以在抽象类中写抽象函数
    }

    class Water:Thing
    {

    }

2.抽象函数

//又叫 纯虚方法
    //用 abstract关键字修饰的方法
    //特点:
    //1.只能在抽象类中申明
    //2.没有方法体
    //3.不能是私有的
    //4.继承后必须实现 用override重写

    abstract class Fruits
    {
        public string name;

        //抽象方法 是一定不能有函数体的
        public abstract void Bad();

        public virtual void Test()
        {
            //可以选择是否写逻辑
        }
    }

    class Apple : Fruits
    {
        public override void Bad()
        {
            
        }
        //虚方法是可以由我们子类选择性来实现的
        //抽象方法必须要实现
    }

    class SuperApple:Apple
    {

        //虚方法和抽象方法 都可以被子类无限的 去重写
        public override void Bad()
        {
            base.Bad();
        }

        public override void Test()
        {
            base.Test();
        }
    }

    #endregion

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("抽象类和抽象方法");
            //抽象不能被实例化
            //Thing t = new Thing();
            //但是 可以遵循里氏替换原则 用父类容器装子类
            Thing t = new Water();
        }
    }

3.总结

//抽象类 被abstract修饰的类 不能被实例化 可以包含抽象方法
    //抽象方法  没有方法体的纯虚方法 继承后必须去实现的方法 
    //注意:
    //如何选择普通类还是抽象类
    //不希望被实例化的对象,相对比较抽象的类可以使用抽象类
    //父类中的行为不太需要被实现的,只希望子类去定义具体的规则的 可以选择 抽象类然后使用其中的抽象方法来定义规则
    //作用:
    //整体框架设计时  会使用

4.练习题

1.练习题1*

//写一个动物抽象类,写三个子类
    //人叫,狗叫,猫叫
    abstract class Animal
    {
        public abstract void Speak();
    }

    class Person : Animal
    {
        public override void Speak()
        {
            Console.WriteLine("你好");
        }
    }

    class Dog:Animal
    {
        public override void Speak()
        {
            Console.WriteLine("汪汪");
        }
    }

    class Cat:Animal
    {
        public override void Speak()
        {
            Console.WriteLine("喵喵");
        }
    }

2.练习题2*

 //创建一个图形类,有求面积和周长两个方法
    //创建矩形类,正方形类,圆形类继承图形类
    //实例化矩形、正方形、圆形对象求面积和周长
    abstract class Graph
    {
        public abstract float GetLength();
        public abstract float GetArea();
    }

    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;
        }
    }

接口

1.接口的概念

 //接口是行为的抽象规范
    //它也是一种自定义类型
    //关键字 :interface

    //接口申明的规范
    //1.不包含成员变量
    //2.只包含方法、属性、索引器、事件
    //3.成员不能被实现
    //4.成员可以不用写访问修饰符,不能是私有的
    //5.接口不能继承类,但是可以继承另一个接口

    //接口的使用规范
    //1.类可以继承多个接口
    //2.类继承接口后,必须实现接口中所有成员

    //特点:
    //1.它和类的申明类似
    //2.接口是用来继承的
    //3.接口不能被实例化,但是可以作为容器存储对象

2. 接口的申明

//接口关键字:interface
    //语法:
    // interface 接口名
    // {
    // }
    //一句话记忆:接口是抽象行为的“基类”
    //接口命名规范 帕斯卡前面加个I

    interface IFly
    {
        void Fly();

        string Name
        {
            get;
            set;
        }

        int this[int index]
        {
            get;
            set;
        }

        event Action doSomthing;
    }

3.接口的使用

//接口用来继承
    class Animal
    {

    }

    //1.类可以继承1个类,n个接口
    //2.继承了接口后 必须实现其中的内容 并且必须是public的
    class Person : Animal, IFly
    {
        //3.实现的接口函数,可以加v再在子类重写
        public virtual void Fly()
        {

        }

        public string Name
        {
            get;
            set;
        }

        public int this[int index]
        {
            get
            {
                return 0;
            }
            set
            {

            }
        }

        public event Action doSomthing;
    }

4.接口可以继承接口

 //接口继承接口时  不需要实现
    //待类继承接口后  类自己去实现所有内容
    interface IWalk
    {
        void Walk();
    }

    interface IMove : IFly, IWalk
    { 
    }

    class Test : IMove
    {
        public int this[int index] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }

        public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }

        public event Action doSomthing;

        public void Fly()
        {
            throw new NotImplementedException();
        }

        public void Walk()
        {
            throw new NotImplementedException();
        }
    }

5.显示实现接口

//当一个类继承两个接口
    //但是接口中存在着同名方法时
    //注意:显示实现接口时 不能写访问修饰符

    interface IAtk
    {
        void Atk();
    }

    interface ISuperAtk
    {
        void Atk();
    }

    class Player : IAtk, ISuperAtk
    {
        //显示实现接口 就是用 接口名.行为名 去实现
        void IAtk.Atk()
        {
            
        }

        void ISuperAtk.Atk()
        {
            
        }

        public void Atk()
        {

        }
    }

6.总结

继承类:是对象间的继承,包括特征行为等等
继承接口:是行为间的继承,继承接口的行为规范,按照规范去实现内容
由于接口也是遵循里氏替换原则,所以可以用接口容器装对象
那么就可以实现装载各种毫无关系,但是却有相同行为的对象
注意:
1.接口值包含 成员方法、属性、索引器、事件,并且都不实现,都没有访问修饰符
2.可以继承多个接口,但是只能继承一个类
3.接口可以继承接口,相当于在进行行为合并,待子类继承时再去实现具体的行为
4.接口可以被显示实现 主要用于实现不同接口中的同名函数的不同表现
5.实现的接口方法 可以加 virtual关键字 之后,让子类进行重写

7.练习题

1.练习题1

//人、汽车、房子都需要登记,人需要到派出所登记,汽车需要去车管所登记,房子需要去房管局登记
    //使用接口实现登记方法
    interface IRegister
    {
        void Register();
    }

    class Person:IRegister
    {
        public void Register()
        {
            Console.WriteLine("派出所登记");
        }
    }

    class Car:IRegister
    {
        public void Register()
        {
            Console.WriteLine("车管所登记");
        }
    }

    class Home:IRegister
    {
        public void Register()
        {
            Console.WriteLine("房管局登记");
        }
    }

2.练习题2

    //麻雀、鸵鸟、企鹅、鹦鹉、直升机、天鹅
    //直升机和部分鸟能飞
    //鸵鸟和企鹅不能飞
    //企鹅和天鹅能游泳
    //除直升机,其它都能走
    //请用面向对象相关知识实现

    abstract class Bird
    {
        public abstract void Walk();
    }

    interface IFly
    {
        void Fly();
    }

    interface ISwimming
    {
        void Swimming();
    }

    class Sparrow : Bird, IFly
    {
        public void Fly()
        {
           
        }

        public override void Walk()
        {
            
        }
    }

    class Ostrich:Bird
    {
        public override void Walk()
        {

        }
    }

    class Penguin : Bird,ISwimming
    {
        public void Swimming()
        {
            
        }

        public override void Walk()
        {

        }
    }

    class Parrot : Bird,IFly
    {
        public void Fly()
        {
            
        }

        public override void Walk()
        {

        }
    }

    class Swan : Bird,IFly,ISwimming
    {
        public void Fly()
        {
            
        }

        public void Swimming()
        {
            
        }

        public override void Walk()
        {

        }
    }

    class Helicopter : IFly
    {
        public void Fly()
        {
            
        }
    }

3.练习题3

    //多态来模拟移动硬盘、U盘、MP3查到电脑上读取数据
    //移动硬盘与U盘都属于存储设备
    //MP3属于播放设备
    //但他们都能插在电脑上传输数据
    //电脑提供了一个USB接口
    //请实现电脑的传输数据的功能

    interface IUSB
    {
        void ReadData();
    }

    class StorageDevice : IUSB
    {
        public string name;
        public StorageDevice(string name)
        {
            this.name = name;
        }

        public void ReadData()
        {
            Console.WriteLine("{0}传输数据", name);
        }
    }

    class MP3 : IUSB
    {
        public void ReadData()
        {
            Console.WriteLine("MP3传输数据");
        }
    }

    class Computer
    {
        public IUSB usb1;
    }

    #endregion
    class Program
    {
        static void Main(string[] args)
        {
            StorageDevice hd = new StorageDevice("移动硬盘");
            StorageDevice ud = new StorageDevice("U盘");
            MP3 mp3 = new MP3();

            Computer c = new Computer();

            c.usb1 = hd;
            c.usb1.ReadData();

            c.usb1 = ud;
            c.usb1.ReadData();

            c.usb1 = mp3;
            c.usb1.ReadData();

        }
    }

密封方法

1.密封方法基本概念

用密封关键字sealed 修饰的重写函数
作用:让虚方法或者抽象方法之后不能再被重写
特点:和override一起出现

2.实例

abstract class Animal
    {
        public string name;
        public abstract void Eat();

        public virtual void Speak()
        {
            Console.WriteLine("叫");
        }
    }

    class Person:Animal
    {
        public override void Eat()
        {
            
        }

        public override void Speak()
        {
            
        }
    }

    class WhitePerson:Person
    {
        public sealed override void Eat()
        {
            base.Eat();
        }

        public sealed override void Speak()
        {
            base.Speak();
        }
    }

3.总结

 密封方法 可以让虚方法和抽象方法不能再被子类重写
 特点:一定是和override一起出现
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

四月的白羊座

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值