在基类构造器中调用虚方法需谨慎
2014-11-21 09:39
239 查看
最近,在基类的构造函数中调用虚方法时,发现了一个问题。先把问题重现如下:
运行以上的代码,结果会是以下两种情况之一吗?
基类说我今年18岁了
子类说我今年18岁了
都不是!而是:
为什么?
→调用子类构造函数
→先调用父类无参构造函数,并调用虚方法
→发现虚方法
如何避免呢?
--去掉在基类构造函数中调用虚方法的代码
--用子类实例调用重载方法
总结:当在基类构造函数中调用虚方法需谨慎,因为当父类调用虚方法重载的时候,子类还没有被初始化,可能会涉及到一些成员还未被初始化。
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岁了
都不是!而是:
为什么?
→调用子类构造函数
new Chinese(18)
→先调用父类无参构造函数,并调用虚方法
Say
→发现虚方法
Say有重载,就调用子类
Chinese中
Say的重载,但此时子类
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));
}
}
总结:当在基类构造函数中调用虚方法需谨慎,因为当父类调用虚方法重载的时候,子类还没有被初始化,可能会涉及到一些成员还未被初始化。
相关文章推荐
- C#基类构造器调用虚方法
- 通过基类调用子类中override 、 new 方法和构造函数的表现
- 学习C#高级编程--在重写基类的方法中,如何调用基类的函数
- JNI学习之---用jni API 访问java对象的属性,方法,调用构造器。
- javascript四种调用方式——方法调用模式、函数调用模式、构造器调用模式和Apply或Call调用模式
- 用jni API 访问java对象的属性,方法,调用构造器
- 调用方法的基类版本
- 继承的约束:构造器不可调用被覆盖的方法
- 千万不要在构造器中调用可覆 写的方法。
- C#中接口通过基类或派生类对方法的调用
- 基类方法的隐藏与调用——《C#入门经典》
- 在派生类中调用基类方法。
- asp.net MVC中怎样让LINQ Designer自动生成的类从别的类继承并调用其基类构造器?
- asp.net MVC中怎样让LINQ Designer自动生成的类从别的类继承并调用其基类构造器?
- JAVA笔试题总结3:父类构造器调用被子类重写方法
- asp.net MVC中怎样让LINQ Designer自动生成的类从别的类继承并调用其基类构造器?
- 数据库基类方法(直接使用SQL语句或存储过程调用)
- asp.net MVC中怎样让LINQ Designer自动生成的类从别的类继承并调用其基类构造器?
- asp.net MVC中怎样让LINQ Designer自动生成的类从别的类继承并调用其基类构造器?
- base方法调用基类构造函数