zoukankan      html  css  js  c++  java
  • 在基类构造器中调用虚方法需谨慎

    最近,在基类的构造函数中调用虚方法时,发现了一个问题。先把问题重现如下:

        class Program
    
        {
    
            static void Main(string[] args)
    
            {
    
                var c = new Chinese(18);
    
                Console.ReadKey();
    
            }
    
        }
    
        public class People
    
        {
    
            public int Age { get; protected set; }
    
            protected People()
    
            {
    
                this.Say();
    
            }
    
            public virtual void Say()
    
            {
    
                Console.WriteLine(string.Format("基类说我今年{0}岁了", Age));
    
            }
    
        }
    
        public class Chinese : People
    
        {
    
            public Chinese(int age)
    
            {
    
                this.Age = age;
    
            }
    
            public override void Say()
    
            {
    
                Console.WriteLine(string.Format("子类说我今年{0}岁了",Age));
    
            }
    
        }
    

     

    运行以上的代码,结果会是以下两种情况之一吗?
    基类说我今年18岁了
    子类说我今年18岁了

     

    都不是!而是:
    1

     

    为什么?
    →调用子类构造函数
    new Chinese(18)
    →先调用父类无参构造函数,并调用虚方法Say
    →发现虚方法Say有重载,就调用子类ChineseSay的重载,但此时子类Chinese还没有对Age属性初始化,此时的Age属性值为默认值0


    如何避免呢?
    --去掉在基类构造函数中调用虚方法的代码
    --用子类实例调用重载方法

     

        class Program
    
        {
    
            static void Main(string[] args)
    
            {
    
                var c = new Chinese(18);
    
                c.Say();
    
                Console.ReadKey();
    
            }
    
        }
    
        public class People
    
        {
    
            public int Age { get; protected set; }
    
            protected People()
    
            {
    
            }
    
            public virtual void Say()
    
            {
    
                Console.WriteLine(string.Format("基类说我今年{0}岁了", Age));
    
            }
    
        }
    
        public class Chinese : People
    
        {
    
            public Chinese(int age)
    
            {
    
                this.Age = age;
    
            }
    
            public override void Say()
    
            {
    
                Console.WriteLine(string.Format("子类说我今年{0}岁了",Age));
    
            }
    
        }
    

     

    2

    总结:当在基类构造函数中调用虚方法需谨慎,因为当父类调用虚方法重载的时候,子类还没有被初始化,可能会涉及到一些成员还未被初始化。

  • 相关阅读:
    工作中的几个问题
    linux初学之二
    VMWARE虚拟机卡死
    记昨天、今天的部分工作内容及问题
    linux初学之一
    今日阅读项目源码
    python POST XML
    python的超简单WEB服务器
    在notepad++中运行python
    安装python图形库:Matplotlib
  • 原文地址:https://www.cnblogs.com/darrenji/p/4112092.html
Copyright © 2011-2022 走看看