javaclassobjectabstract

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


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.


Solution

  • 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.