21实现多态之虚方法

虚方法 实现多态的三种手段:1、虚方法 2,抽象类 3,接口

有如下三个有继承关系的类 父类:Person 子类:Chinese、American 他们都有一个SayHello方法

//父类
    public class Person
    {
        private string _name;//姓名字段

        public string Name//姓名属性
        {
            get { return _name; }
            set { _name = value; }
        }

        public void SayHello()//方法
        {
            Console.WriteLine("Hello,我是人类");
        }

        //构造函数
        public Person(string name)
        {
            this.Name = name;
        }
    }


    //子类,中国人
    public class Chinese : Person
    {
        public Chinese(string name) : base(name)
        {

        }
        public void SayHello()
        {
            Console.WriteLine("我是中国人,我叫{0}", this.Name);
        }
    }



    //子类,美国人 
    public class American : Person
    {
        public American(string name) : base(name)
        {
        
        }
        public void SayHello()
        {
            Console.WriteLine("我是美国人,我叫{0}", this.Name);
        }
    }

我们尝试用一个父类数组装两个子类对象,然后输出自己的SayHello方法
//创建中国人对象
            Chinese chinese = new Chinese("张三");

            //创建美国人对象
            American american = new American("迈克尔杰克逊");

            Person person = new Person("人类");

            //父类数组
            Person[] people = { chinese, american, person };

            //循环调用他们自己的方法
            for (int i = 0; i < people.Length; i++)
            {

                if (people[i] is Chinese)//判断是否是自己子类对应的类型
                {
                    ((Chinese)people[i]).SayHello();
                }
                else if (people[i] is American)
                {
                    ((American)people[i]).SayHello();
                }
                else
                {
                    people[i].SayHello();
                }

            }
可以看到,在循环输出自己的SayHello方法时,很麻烦,要判断,然后将子类转为对应的类型再调用

使用虚方法,解决

步骤:
1、将父类的方法标记为虚方法 ,使用关键字 virtual,这个函数可以被子类重新写一遍。
2、子类重写用override重写

我们只需要在父类的SayHello方法改为虚方法,再在子类的SayHello里重写父类的SayHello方法就行了,如:
//父类
    public class Person
    {
        private string _name;//姓名字段

        public string Name//姓名属性
        {
            get { return _name; }
            set { _name = value; }
        }


        public virtual void SayHello()//方法
        {
            Console.WriteLine("Hello,我是人类");
        }

        //构造函数
        public Person(string name)
        {
            this.Name = name;
        }



    }





    //子类,中国人
    public class Chinese : Person
    {

        public Chinese(string name) : base(name)
        {

        }


        public override void SayHello()
        {
            Console.WriteLine("我是中国人,我叫{0}", this.Name);
        }


    }



    //子类,美国人
    public class American : Person
    {

        public American(string name) : base(name)
        {

        }


        public override void SayHello()
        {
            Console.WriteLine("我是美国人,我叫{0}", this.Name);
        }


    }

这样在循环调用的时候就不用把父类数组里的子类依依判断然后转为子类再调用方法,可以直接调用SayHello方法,因为子类重写了,所以循环调用SayHello的时候,表面上虽然是Person父类的类型,实际上调用的却是子类自己的SayHello方法
 //创建中国人对象
            Chinese chinese = new Chinese("张三");

            //创建美国人对象
            American american = new American("迈克尔杰克逊");

            Person person = new Person("人类");

            //父类数组
            Person[] people = { chinese, american, person };

            //循环调用他们自己的方法
            for (int i = 0; i < people.Length; i++)
            {
                people[i].SayHello();
            }

这样也实现了判断转子类调用SayHello方法


使用虚方法的目的

原本父类只能调父类方法,但是重写后可以调子类,
相当于实例父类,但是根据对象不同,方法也就不同。
比如写一个通用方法,主体是父类,参数是子类,以后拓展代码只要改下参数就好

也就是,让子类自己实现这个方法,父类这个SayHello方法就不会写死了。这样如果还有一个新的子类,
也只需要重写这个SayHello方法,这样就实现父类的方法在不同的子类实现不同的功能,也就是多态

virtual:将父类的方法标记为虚方法,这样子类就可以重写这个方法

override的效果是实例父类,根据对象子类不同,可以实现不同方法,可以写出通用代码。

override表示想不想重写

posted @   青仙  阅读(107)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示