实例化不同类型的

时间:2017-10-15 16:30:31

标签: c# oop

仅仅出于好奇,我总是看到某人将实例化窗帘类型的对象然后将其分配给不同类型的代码。我的问题是你为什么要这样做以及我们想要完成什么,例如:

SampleClassA sampleclassA = new SambleClassB();

这段代码的意思是他试图演员或者是什么。提前谢谢。

3 个答案:

答案 0 :(得分:4)

在某些情况下,我们希望引用具有超类型变量的子类类型。

在您的案例中:

SampleClassA sampleclassA = new SambleClassB(); 

将为您提供灵活性,使变量sampleclassA引用任何派生自SampleClassA的类型。当你有许多类型派生自SampleClassA并且你想要执行下面提到的一个动作时,你说你只想这样做。如果只有SampleClassA的一个子类型,那么您只需执行SambleClassB sampleclassA = new SambleClassB();

有时我们也可以使用超类型作为方法参数,方法返回类型或对象集合的类型。

这样:

  • 使我们能够创建一个可以输入的方法参数 任何从超类型派生的类型,你都可以将其视为行为中的多态。
  • 同样,我们可以使用超类型作为方法返回类型,它将再次使我们能够返回从超类型派生的任何类型。
  • 使我们能够存储一组对象,这些对象都来自特定类型,并对集合中的所有对象执行一些通用逻辑。

答案 1 :(得分:3)

请注意,只有SampleClassB符合"兼容"与SampleClassA。可能是前者继承后者,或者前者实现后者,或者前者可以隐含地转换为后者。

在这个答案中,我将只讨论前两种情况(继承和接口实现)的有用性,因为我认为最后一种情况(隐式转换)的有用性非常清楚。

我们假设您有4种类型:

interface IPet {
    ...
}

class Dog : IPet {
    ...
}

class Cat : IPet {
    ...
}

class Person {
    public IPet Pet { get; set; }
}

如您所见,每个Person对象都可以拥有宠物。此Pet属性声明为IPet。使用此Person课程时,您会遇到将DogCat对象分配给IPet媒体资料的情况:

Person me = new Person();
me.Pet = new Dog();

然后将Pet声明为IPet的目的是什么? "为什么不将其声明为Dog?上面的代码仍然有效,"你说。好吧,如果你这样做了,那么一个人的对象就不能把那些可爱的小猫当宠物了!太遗憾了! :)

基本上,将属性/变量声明为接口而不是具体类通常是因为我们希望将来在其中存储不同类型的对象。这使它更灵活,对于基类/派生类也是如此。

答案 2 :(得分:0)

我同意当前的答案,并希望再添加一个理由:因为它减少了两个独立程序之间的纠缠。

想象一下,我有一个这样的课程:

public class Astronomy()
{
    public void CalculateOrbit()
    {
       Planet myVar = new Planet();
       // some code that does stuff with myVar
       // some *more* code that does stuff with myVar
       // etc
    }
}

那天文学'课堂 - 它与你的“星球”缠绕在一起。现在。每当你接触到Planet级别时,你很有可能无意中打破了更大的天文学课程。

但是呢......

public class Astronomy()
{
    public void CalculateOrbit()
    {
       StellarObjectInterface myVar = new Planet();
       // some code that does stuff with myVar
       // some *more* code that does stuff with myVar
       // etc
    }
}

改变了什么?你还在创建一个Planet实例......除了现在,你将它放入一个StellarObjectInterface'宾语。现在,无论何时操作myVar,您都无法直接使用Planet类中的任何方法/属性/字段/等等 - 您必须通过StellarObjectInterface。

这能带给你什么?这意味着只要Planet类服从它实现的界面,你就可以改变Planet,而不必担心在天文学课上造成不良副作用。

更好的是,你可以这样做:

public class Astronomy()
{
    public void CalculateOrbit(StellarObjectInterface myVar)
    {
       // some code that does stuff with myVar
       // some *more* code that does stuff with myVar
       // etc
    }
}

现在你的天文学课程根本没有与星球联系在一起!当然,如果你愿意,你可以传递一个星球,但你不能拥有。您可以传入任何 Stellar对象。

无论如何,希望有道理。如果您有兴趣深入研究这一点,请看一下S.O.L.I.D.更多信息的原则。