简体   繁体   中英

How to in a simple way cast one object to another when they both inherit from the same class

I have a question. For example, let's take into consideration two classes:

class Car extends Vehicle
class Train extends Vehicle

Let's assume that the Vehicle has a lot of fields . I want to cast object Car to object Train. They both extends the Vehicle class so they have many fields in common. I don't want to waste time on setting each field. Is there any way in Java (some nice library maybe?) to do it with the least effort?

PS. Reflection might be the answer, however, if the Vehicle class has many fields of more 'complicated' type it would also take a lot of time.

EDIT: I want to create an object based on common fields from the other object. Maybe the 'cast' word is wrong. Yes, I know they are different, I just want to copy the common fields. And yes, I know it's a bad design, I just don't have other option, I need to quickly fix sth which was badly written.

That's not possible in Java. The reason is that a Car is not a Train, even though they might have most of their functionality in common. What would happen if Train had a method ChooChoo , which clearly doesn't make sense for a car, but you tried to call it on a Car casted as a Train.


The way to go about this is to try to work with Vehicle. If you currently have some code which works with Trains, but doesn't make any use of the Train specifics, it should be safe to change the code to work with Vehicle. If it does make use of Train specifics, how do you expect it to work when it's passed non-Trains?

Note that Car and Train are two different concrete classes of Vehicle , so you cannot "cast" between them. I guess what you want is to copy common properties between two objects. You can use bean utils from Apache or Spring to do that.

What you're saying is definitely possible with some reflection mojo; with small effort one can write up a generic implementation which would take two distinct classes and try to match fields by name/type and transfer values over each other. For example this question have some crude implementation of what you are looking for.

But I think the way you should handle this is through inheritance. If both Car and Train are Vehicle s but they can not be interchanged even though they still have some similarities between them, then you should create a Vehicle implementation which will contain all similarities. Then you can simply extend your Car and Train classes from that common Vehicle implementation.

eg

class MovingVehicle extends Vehicle //(class which contains similiarities)
class Car extends MovingVehicle
class Train extends MovingVehicle

If you just want to copy over the common fields, and if your objects are beans, look into Dozer .

Mapper mapper = new DozerBeanMapper();
Car car = new Car();
mapper.map(train, car);

If your objects are not beans, then you'll have to write the mapping code yourself.

PS: indeed, the word 'cast' was an unfortunate choice :)

  1. Create a new constructor in your Train class that accepts a Vehicle as parameter. This constructor will copy all fields present in Vehicle.

     // Constructor public Train(Vehicle v){ // Copy all common variables here } 
  2. You can now instantiate a Train object from an existing Car object

     Car car = new Car(); Train train = new Train(car); 

Edit: Outsourcing constructor to Vehicle as suggested by Turing85

  1. Create a new constructor in your Vehicle class that accepts a Vehicle as parameter. This constructor will copy all fields present in Vehicle.

     // Constructor for Vehicle.java public Vehicle(Vehicle vehicle){ // Copy all common variables here } 
  2. Create a new constructor in your Train/Car class that accepts a Vehicle as parameter and call super(vehicle).

     // Constructor for Car.java public Car(Vehicle vehicle){ super(vehicle); } // Constructor for Train.java public Train(Vehicle vehicle){ super(vehicle); } 
  3. You can now copy the common fields by instantiating the object with an existing object.

     // Creating a new Train from an existing car object Car existingCar = new Car(); Train train = new Train(existingCar); // Creating a new Car from an existing Train object Train existingTrain = new Train(); Car car = new Car(existingTrain); 

Explanation: Car car = new Car(existingTrain); works because the Car constructor accepts a Vehicle object, and a Train is a type of Vehicle.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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