views:

56

answers:

6

I have to Classes. lets say Invoice and TempInvoice. Both have same properties(all are same). let say i created a object using Invoice Class. Can i cast that object to another object that i created using tempInvoice ??

ex:

Invoice invoiceobj= getInvoice(int? id) //a method return a invoice object

TempInvoice tempInvoiceObject = invoiceobj// (Need to do it and fill tempInvoice by Invoice Values.even as a new memory location o set by reference.)
+4  A: 

Not unless Invoice derives from TempInvoice.

Marcelo Cantos
+1  A: 

You can only cast one object to another if they are related.

So if TempInvoice is created like this:

public class TempInvoice : Invoice
{
}

then it will work.

If they are two unrelated classes then no you can't.

However, why do you need two separate classes in this case? You can simply have two objects of the same class, given that you state that all the properties are the same:

Invoice invoiceobj= getInvoice(int? id) //a method return a invoice object

Invoice tempInvoiceObject = invoiceobj;
ChrisF
+2  A: 

If the classes are exactly the same, why use 2 classes? I think you have a design problem here. Use the Invoice class for multiple instances and you will be fine.

If you absolutely need to use 2 different classes, then make TempInvoice a subclass of Invoice and you will be able to cast. But I don't think there's really a point to it.

axel_c
+2  A: 

+1 to Marcelo. TempInvoice has to be the base class of Invoice to do this.

Alternatively you could create an operator implicit that would do the conversion - but you'd still have to write code by hand that would convert from one to the other.

Vilx-
Usually better to make such operators explicit (to avoid unexpected conversions), but defining your own conversion is the way to convert from one type to an unrelated type.
Richard
+1  A: 

What you could consider also is this:

  • Create an interface, e.g. IInvoice, and declare all the common properties and methods from both Invoice and TempInvoice in it.

  • Have both Invoice and TempInvoice implement this interface.

After having done this, you still cannot convert a Invoice object to TempInvoice (unless the former type derives from the latter), but you can convert either object type to IInvoice.

stakx
+1  A: 

You didn't mention which language you are using, but since the concept is pretty much the same across all OOP languages, I'll assume C# for the moment.

The only way you can do an implicit conversion like the one you sited in your example is if Invoice is a subclass of TempInvoice, like so:

public class Invoice : TemplInvoice { }

However, you can do an explicit conversion if the opposite is true (i.e. TempInvoice derives from Invoice), but only if the getInvoice method is truely creating a TempInvoice object, or an object derived from TempInvoice. Otherwise, you will get an InvalidCastException when you try to do the explicit conversion. Keep in mind that only platforms like Java or Microsoft.NET will throw a nice, clean exception for you to catch. Things can get much nastier from languages like C or C++, as they will allow you to do things like a blind cast without so much as warning (static_cast and dynamic_cast will fail to compile), which often results in either garbage data (best case), or an access violation (worst case) at random points farther down in the code.

If you absolutely need to have two objects, probably the best thing to do is to either derive one from the other, or break out the common methods into a seperate base class that both can inherit from. However, you should never blindly downcast a return value from a function call. If you have a case where you know a function will always return the same type, you should use that type directly, and avoid downcasting, anyway. It's safer and more efficient for the generated code. If you are using the factory pattern, you can build some form of RTTI into the base interface so that you aren't doing a (mostly) blind cast. A good example of this (albiet a bit complicated) is the QueryInterface method for COM objects, but you can do something as simple as adding an Invoice.Type property.

Javert93