之前没有仔细看,你这个说法是错误的。 下面的代码可以检测你是否是理解错误或者仅仅是表达不清:using System; using System.Collections.Generic; using System.Linq; using System.Text;namespace ConsoleApplication1 { class Program { static void Main(string[] args) { b _b = new b(); } } class a { public a() { Console.WriteLine("a"); } } class b : a { private c _c = new c(); public b() : base() { Console.WriteLine("b"); } } class c { public c() { Console.WriteLine("c"); } } } 请解释程序输出abc的顺序。
第一个问题,override不是覆盖而是重载,用这种方式不仅可以调用父类的方法,而且可以扩展。而第一种方式会直接覆盖父类的方法。这就是区别第二个问题,子类执行构造函数的时候会默认执行父类的构造函数, 如果你没有显示声明,比如像这样写public MySubClass(int a, string b) : base(b) 那么构造的时候会执行父类不带任何参数的构造函数,而你的父类里面并没有定义这个构造函数,所以编译器报错
2:子类调用父类构造函数其实是c#对象模型所决定的 new一个对象的时候会递归的调用其父类构造函数 直到最终的object类的构造函数
(1)修改后,子类的方法不会被调用,只会调用基类的方法,显然不符合设计意图。
(2)public MySubClass(int a, string b)其实相当于
public MySubClass(int a, string b) : base()的简写。
你好!
可以认识一下吗?我QQ:295101971 手机:13389255318
2、继承类与基类有相同签名的方法,则会隐藏基类的方法。在继承类调用此方法时,是调用继承类的方法,所以.NET里把此现象叫做隐藏。
3、因此需要有虚方法在基类,继承类则对基类的虚方法进行重写,以便对基类进行升级扩展,而不用去修改基类的方法。而且有些时候基类已经编译不能进行修改了。
下面的代码可以检测你是否是理解错误或者仅仅是表达不清:using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
b _b = new b();
}
}
class a
{
public a() { Console.WriteLine("a"); }
}
class b : a
{
private c _c = new c();
public b() : base() { Console.WriteLine("b"); }
}
class c
{
public c() { Console.WriteLine("c"); }
}
}
请解释程序输出abc的顺序。
如果你没有显示声明,比如像这样写public MySubClass(int a, string b) : base(b)
那么构造的时候会执行父类不带任何参数的构造函数,而你的父类里面并没有定义这个构造函数,所以编译器报错
谁跟你说结果一样的, 结果根本不一样
1 2 里面的 animal.Eat(); 实际运行的是基类(Animal)里面的Eat()函数
3 4 里面的 animal.Eat(); 实际运行的是派生类(Chameleon)里面的Eat()函数第二个问题
没有为什么,由语言特性和运行机制决定的,就是这么做的 -- 派生类对象必然先运行其基类的构造函数,然后再是自己的构造函数.
至于你说为什么会有这个错误,因为调用的是基类的默认构造函数(就是没参数的构造函数),如果你定义了任何构造函数,编译器就不为你写默认构造函数了,也就是说MyBaseClass不存在默认构造函数. 所以派生类的构造函数就找不到"MyBaseClass()"了-- 因为后面省略了":base()"就相当于调用基类默认构造函数. 参见8楼解释.