[英]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: 这个:
Note that you can only do this if SampleClassB
is "compatible" with SampleClassA
. 请注意,只有在
SampleClassB
与SampleClassA
“兼容”时,您才能执行此操作。 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
属性分配Dog
或Cat
对象的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.