简体   繁体   English

实例化其他类型的类型

[英]Instantiate a Type of a different type

Just from curiosity I've always seen code where a someone would instantiate an object of a curtain type then assign it to a different type. 出于好奇,我总是看到代码,有人可以实例化窗帘类型的对象,然后将其分配给其他类型。 My question is why would you do that and what are we trying to accomplish eg: 我的问题是,您为什么要这样做?我们将要完成什么工作,例如:

SampleClassA sampleclassA = new SambleClassB();

What does this code mean is he trying to cast or what. 此代码是什么意思,他试图投射还是什么。 Thanks in advance. 提前致谢。

There are several cases where we would want to reference a subclass type with a supertype variable. 在几种情况下,我们希望引用具有超类型变量的子类类型。

in your case doing: 就您而言:

SampleClassA sampleclassA = new SambleClassB(); 

will give you the flexibility of making the variable sampleclassA reference any type which derives from SampleClassA . 将使您能够灵活地使变量sampleclassA引用任何从SampleClassA派生的类型。 that said you'd only want to do this when you have many types which derive from SampleClassA and you'd want to perform one of the actions mentioned below. 那就是说,只有当您有许多衍生自SampleClassA类型并且想要执行以下提到的操作之一时,才想执行此操作。 if there is only one subtype of SampleClassA , then you'd rather just do SambleClassB sampleclassA = new SambleClassB(); 如果只有SampleClassA一个子类型,那么您宁愿做SambleClassB sampleclassA = new SambleClassB(); .


Sometimes we can also use the supertype as a method parameter, method return type or the type of a collection of objects. 有时我们也可以将超类型用作方法参数,方法返回类型或对象集合的类型。

this: 这个:

  • enables us to create a method parameter which can take an input of any type which derives from the supertype, you can think of this as polymorphism in action. 使我们能够创建一个方法参数,该参数可以接受从超类型派生的任何类型的输入,您可以将其视为实际的多态。
  • equally, we can use the supertype as a method return type which will again enable us to return any type which derives from the supertype. 同样,我们可以将超类型用作方法返回类型,这将再次使我们能够返回从超类型派生的任何类型。
  • enables us to store a collection of objects which all derive from a particular type and perform some common logic upon all the objects within the collection. 使我们能够存储所有从特定类型派生的对象集合,并对集合中的所有对象执行一些通用逻辑。

Note that you can only do this if SampleClassB is "compatible" with SampleClassA . 请注意,只有在SampleClassBSampleClassA “兼容”时,您才能执行此操作。 It could be that the former inherits from the latter, or the former implements the latter, or that the former can be implicitly converted to the latter. 可能是前者继承了后者,或者前者实现了后者,或者前者可以隐式转换为后者。

In this answer I will only discuss the usefulness of the first two situations (inheritance and interface implementation) because I think the usefulness of the last situation (implicit conversion) is pretty clear. 在这个答案中,我将只讨论前两种情况(继承和接口实现)的有用性,因为我认为最后一种情况(隐式转换)的有用性很明显。

Let's say you have 4 types like this: 假设您有以下4种类型:

interface IPet {
    ...
}

class Dog : IPet {
    ...
}

class Cat : IPet {
    ...
}

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

As you can see, every Person object can have a pet. 如您所见,每个Person对象都可以养宠物。 This Pet property is declared as IPet . Pet属性声明为IPet When you use this Person class, you will encounter the situation of assigning a Dog or Cat object to an IPet property: 使用此Person类时,将遇到为IPet属性分配DogCat对象的IPet

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

What is the purpose of declaring Pet as IPet then? 那么,将Pet声明为IPet的目的是什么? "Why not declare it as Dog ? The above code will still work," you said. 您说:“为什么不将其声明为Dog ?上面的代码仍然可以使用。” Well, if you did so, then a person object can't have those cute little cats as pets! 好吧,如果您这样做了,那么一个人对象就不能把那些可爱的小猫当作宠物! What a pity! 太遗憾了! :) :)

Basically, declaring a property/variable as an interface, instead of a concrete class is usually because we want to store different types of objects in it in the future. 基本上,将属性/变量声明为接口而不是具体类通常是因为我们希望将来在其中存储不同类型的对象。 This makes it more flexible, and it goes the same for base class/derived class. 这使其更灵活,并且对于基类/派生类也是如此。

I agree with the current answers, and wanted to add one more reason: because it reduces the entanglement between two separate bits of program. 我同意当前的答案,并想补充一个原因:因为它减少了程序两个不同位之间的纠缠。

Imagine I had a class like this: 想象一下我有一个这样的课程:

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
    }
}

That 'Astronomy' class - it's very entwined with your 'Planet' now. 那个“天文学”课-现在已经与您的“行星”交织在一起。 Any time you touch that Planet class, there's a good chance you're going to inadvertently break the larger Astronomy class. 每当您接触该“行星”课程时,您很有可能会无意中打破较大的“天文学”课程。

But what about... 但是关于...

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
    }
}

What's changed? 有什么变化? You're still creating an instance of Planet... except now, you're putting it into a 'StellarObjectInterface' object. 您仍在创建Planet的实例...除了现在,您将其放入'StellarObjectInterface'对象。 Now, whenever you operate on myVar, you're not able to just use any methods/properties/fields/etc from the Planet class willy-nilly - you have to go through the StellarObjectInterface. 现在,无论何时在myVar上进行操作,您都将无法仅使用Planet类willy-nilly的任何方法/属性/字段/等-您必须遍历StellarObjectInterface。

What does this get you? 这对你有什么帮助? It means as long as the Planet class obeys the interface it's implementing, you can change Planet around without having to worry about causing bad side-effects in the Astronomy class. 这意味着只要Planet类遵循其实现的接口,就可以更改Planet,而不必担心在Astronomy类中引起不良影响。

Better yet, you can do something like this: 更好的是,您可以执行以下操作:

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

Now your Astronomy class isn't tied to Planet at all! 现在,您的天文学课程不再与Planet相关! Sure, you can pass in a Planet if you like, but you don't have to. 当然,你可以传递一个地球,如果你喜欢,但你不必 You can pass in any Stellar Object. 您可以传入任何恒星对象。

Anyway, hope that makes sense. 无论如何,希望这是有道理的。 If you're interested in delving into this further, take a look at some of the SOLID principles for more info. 如果您有兴趣进一步研究,请查看一些SOLID原理以获取更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM