开发者

When and why would you upcast an object?

This is considered upcasting correct?

Derived d = new Derived();
Base b = d; // Always OK.

Why would someone upcast? When? Is it because we must turn the object into the base class so it does not have the functionality of the derived class?

How does this code look in memory开发者_JS百科? Derived class instantiates and memory is created for that object. Then a base class object is made that references d now.


I think you might be a bit confused about what the upcast does. The upcast does not disable the functionality of the derived object, nor does it create a new Base object. Rather, it just takes a more limited view of the object you upcasted. Through the base class reference, you can access only those methods declared in Base, but if any of those methods are overridden in the derived class, invoking them through the base reference will still call the derived version.

As for when you'd want to do this, it's uncommon to see people upcast for no particular reason. After all, that limits what you can do to the object. However, as other posters have pointed out, it's common to implicitly upcast when passing an object into a function or returning an object from a function. In those cases, the upcast allows function authors to either take in a parameter with the weakest set of requirements necessary to get the job done, or to return an object from a function that exhibits some set of behaviors without necessarily revealing the full type of the object.


Upcasts are normal because every Derived is Base.

When you write a class B that inherits from a class A, then B is a subclass of A. That means that you can use an object of type B anywhere that you can use an object of type A.

You should read about inheritance and how powerful it is.


When you want to use polymorphism you can use upcast, for example you have a method which accepts Base, but you like call it with your Derived:

public void DoAction(Base base)
{
 // do stuff
}

DoAction(drivedItem);

DoAction(baseItem);

both of above calls are true.

but in polymorphism you can't do downcasting you can use for example method overloading to overcome your problems.


Is it cause we must turn the object into the base class so it does not have the functionality of the derived class?

Because there's some piece of code that works whether or not your object is Derived1 or Derived2 and is written only based on the assumption that it supports Base functionality. This is called abstraction and will result in code reuse. You don't have to rewrite that function for Derived1 and Derived2 separately. You abstract away the details specific to Derived1 and Derived2.

By the way, many times, you don't do the cast explicitly. You simply take advantage of this fact when you pass an instance to a function. For instance, when you add a string to an ArrayList, you implicitly cast it to its base type object because the signature for Add is:

void Add(object o);


I'm not sure you'd write code like your example very often, but one application of this type of casting would be method calls:

void Test()
{
   Derived d = new Derived();
   this.DoSomething(d);
}

void DoSomething(Base b)
{
   // something
}

In this case, d isn't "turned into" a Base object, it's just treated like one. I don't know for sure, but I imagine the actual memory associated with the d object does not change at all.


Regarding your second question (how they look in memory), both of them look the same on the stack. On the stack, they are both simple pointers to the heap.


Reason One: If I write code in 2008 that knows about the Base class and does some things with it that only involve the functionality of that class, upcasting lets you create the Derived class in 2011 and pass an instance to my code without any changes.

Arguably, this could also be done (and perhaps more powerful) if I had written my code using generics in the first place.

Reason Two: If you need to store several instances of different classes in a single container, you need to upcast those instances to a shared base class. Consider, for instance, a list of "currently loading" data sources which may be local files, URLs, in-memory data and even sockets - all of these would be specific classes sharing a common data source class.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜