我对OOP比较陌生,所以想清除一些事情,
我有以下代码
class Parent
{
public Parent()
{
Console.WriteLine("Parent Class constructor");
}
public void Print()
{
Console.WriteLine("Parent->Print()");
}
}
class Child : Parent
{
public Child()
{
Console.WriteLine("Child class constructor");
}
public static void Main()
{
Child ChildObject = new Child();
Parent ParentObject = new Child();
ChildObject.Print();
ParentObject.Print();
}
}
输出:
Parent Class Constructor
Child Class constructor
Parent Class Constructor
Child Class constructor
Parent->Print()
Parent->Print()
我的问题如下:
1)为什么在使用ChildClass
构造函数实例化对象时调用基类构造函数?没有明确指定base
关键字。有没有办法避免调用基类构造函数?
2)为什么ParentClass ParentObj = new ChildClass();
可能?而不是相反。
答案 0 :(得分:6)
所有基类构造函数都会被调用继承树。构造函数始终以父类开始链接到最派生类。
ChildClass
“的实例是”ParentClass
的实例。他们模仿了“是一种”关系,但不是相反。
答案 1 :(得分:4)
总之,polymorphism。
通过Child
继承Parent
,子对象具有父对象的特征。如果从遗传角度考虑它,它可能更有意义。
1)为什么在实例化对象时调用基类构造函数 使用ChildClass构造函数?没有明确指定 基本关键字。有没有办法避免调用基类 构造
没有办法绕过被调用的基类构造函数(我知道)。调用基类构造函数的目的是实例化基类(传递参数,初始化其他对象,赋值等)。
2)为什么ParentClass ParentObj = new ChildClass();可能?并不是 反过来说。
由于多态性,Child
看起来像<{1}} ,因此可以实例化为Parent
。由于Parent不继承Child,因此Parent看起来不像Child,因此可能无法实例化为Parent
。
对于它的价值,使用父母和孩子有不同的含义。通常,在引用继承时,Child
是基类,其中Parent
将是派生的或子类型。
答案 2 :(得分:3)
: base()
如果您有构造函数: base("foo")
,则可以显式调用Parent(string s)
,然后不调用Parent()
。您不能跳过一起调用的基类构造函数。Animal animal = new Dog();
有意义而不是Dog dog = new Animal();
狗总是动物,但不一定是相反的。答案 3 :(得分:1)
1)可能令人困惑,因为您正在使用Child / Parent命名法。因为Child / Parent意味着两个不同的实例(所有者关系)。继承是一种Is-A关系。狗是动物。所以狗类可以继承动物。
2)同样,你可以拥有一只恰好是狗的动物,但你只有一只动物手柄。就像你可以拿着皮带一样,另一端可能有一只大象或跳蚤,但皮带可以容纳任何动物。
答案 4 :(得分:0)
1)基类中有(或可能)私有成员,子类对此一无所知,但是是必要的。因此,首先调用父构造函数来覆盖这种可能性。
2)ChildClass
是ParentClass
的一种类型,Square
是Rectangle
的一种类型。无论如何,这就是理论。这就是为什么没有相反的原因。
答案 5 :(得分:0)
1)在C#中,如果未使用base(blah)
之类的内容指定对不同构造函数的调用,则会调用默认构造函数。你在上面定义的那个。
2)每个ChildClass
始终为ParentClass
。但是,可能存在ParentClass
但不是ChildClass
的对象。例如,如果您有OtherChildClass : ParentClass
,那么它将是ParentClass
,但它不会是ChildClass
。