Is there an elegant way to recreate an object when I need to change its type?

104 Views Asked by At

A practice task of mine is about having Fighters taking part in Missions and an aggregator class that can count/filter/keep track of Fighters and Missions.

I have a Fighter abstract class and three different types of fighters (Junior, Medior and Senior) that inherit this abstract class with a number of fields.

The programme should be able to promote fighters to a higher rank - a Junior to Medior and a Medior to Senior. I understand it is not possible to change an object's type after it has been initialised, but is there a better / more elegant solution than my current one? i.e. I create a new object of a higher level fighter, copy the original object's data into it and then just delete the original object.

1

There are 1 best solutions below

4
Basil Bourque On BEST ANSWER

As Commented, it sounds like rank should simply be a property of your Fighter class.

You should not use inheritance unless the subclasses have additional data or behavior beyond that of the superclass.

Here is an entire example class. We define Rank as an enum with three named constant objects, your three levels of rank. We have a getter as well as a setter method for you to alter the rank field on an instance.

package work.basil.example;

import java.util.Objects;

public final class Fighter
{
    // Member fields
    private String name;
    private Rank rank;

    enum Rank { JUNIOR, MEDIOR, SENIOR; }

    // Constructor
    public Fighter ( String name ,
                     Rank rank )
    {
        this.name = name;
        this.rank = rank;
    }

    // Accessors
    public String getName ( )
    {
        return name;
    }

    public void setName ( final String name )
    {
       this.name = name ;
    }

    public Rank getRank ( )
    {
        return rank;
    }

    public void setRank ( final Rank rank )
    {
        this.rank = rank;
    }

    // `Object` overrides.
    @Override
    public boolean equals ( Object obj )
    {
        if ( obj == this ) return true;
        if ( obj == null || obj.getClass ( ) != this.getClass ( ) ) return false;
        var that = ( Fighter ) obj;
        return Objects.equals ( this.name , that.name ) &&
                Objects.equals ( this.rank , that.rank );
    }

    @Override
    public int hashCode ( )
    {
        return Objects.hash ( name , rank );
    }

    @Override
    public String toString ( )
    {
        return "Fighter[" +
                "name=" + name + ", " +
                "rank=" + rank + ']';
    }
}

Usage:

Fighter alice = new Fighter ( "Alice" , Fighter.Rank.MEDIOR ) ;
alice.setRank( Rank.SENIOR ) ;  // Alice earned a promotion.