Healthy Characters

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
-1
down vote

favorite












Let's say I have an abstract class Character that have fields health and maxHealth. maxHealth differs between subclasses. However, the first way I implemented it the health is always initialized as equals to maxHealth.




public abstract class Character 
protected Vector position;
protected int health;
protected int maxHealth;

public Character(float xLocation, float yLocation)
Vector position = new Vector(xLocation, yLocation);
health = maxHealth;



public class Grunt extends Character
public Grunt(float xLocation, float yLocation)
super(xLocation, yLocation);
maxHealth = 200;





But this didn't work correctly because health is assigned to maxHealth before maxHealth was initialized as 200.



I tried to change constructor parameters as follows and it works but I'm not sure that if this is a good practice. What do you think?



public abstract class Character 
protected Vector position;
protected int health;
protected int maxHealth;

public Character(float xLocation, float yLocation, int maxHealth)
Vector position = new Vector(xLocation, yLocation);
this.maxHealth = maxHealth;
health = maxHealth;



public class Grunt extends Character
public Grunt(float xLocation, float yLocation)
super(xLocation, yLocation, 200);








share|improve this question





















  • What is this: new Vector(xLocation, yLocation)? There is no constructor Vector(float, float), or Vector(double, double) (which would also accept two floats).
    – Stingy
    May 2 at 9:38











  • @Stingy, there's not even a type Vector in scope at that point, so we can't even guess what constructors it might have.
    – Toby Speight
    May 2 at 12:07










  • @TobySpeight I assumed Vector refers to java.util.Vector and the import was not included in the code sample. But you're right, theoretically, Vector might also refer to an entirely different class.
    – Stingy
    May 2 at 12:42










  • @Stingy: and I wasn't reading properly when I came here from Review (too used to reading C++ code). It might be a typo for javax.vecmath.Vector2f, of course (but without any imports, we're still guessing).
    – Toby Speight
    May 2 at 12:58










  • Vector class is written by me and it represents the geometrical 2D vectors with x and y coordinates.
    – Emre Sülün
    May 9 at 7:25
















up vote
-1
down vote

favorite












Let's say I have an abstract class Character that have fields health and maxHealth. maxHealth differs between subclasses. However, the first way I implemented it the health is always initialized as equals to maxHealth.




public abstract class Character 
protected Vector position;
protected int health;
protected int maxHealth;

public Character(float xLocation, float yLocation)
Vector position = new Vector(xLocation, yLocation);
health = maxHealth;



public class Grunt extends Character
public Grunt(float xLocation, float yLocation)
super(xLocation, yLocation);
maxHealth = 200;





But this didn't work correctly because health is assigned to maxHealth before maxHealth was initialized as 200.



I tried to change constructor parameters as follows and it works but I'm not sure that if this is a good practice. What do you think?



public abstract class Character 
protected Vector position;
protected int health;
protected int maxHealth;

public Character(float xLocation, float yLocation, int maxHealth)
Vector position = new Vector(xLocation, yLocation);
this.maxHealth = maxHealth;
health = maxHealth;



public class Grunt extends Character
public Grunt(float xLocation, float yLocation)
super(xLocation, yLocation, 200);








share|improve this question





















  • What is this: new Vector(xLocation, yLocation)? There is no constructor Vector(float, float), or Vector(double, double) (which would also accept two floats).
    – Stingy
    May 2 at 9:38











  • @Stingy, there's not even a type Vector in scope at that point, so we can't even guess what constructors it might have.
    – Toby Speight
    May 2 at 12:07










  • @TobySpeight I assumed Vector refers to java.util.Vector and the import was not included in the code sample. But you're right, theoretically, Vector might also refer to an entirely different class.
    – Stingy
    May 2 at 12:42










  • @Stingy: and I wasn't reading properly when I came here from Review (too used to reading C++ code). It might be a typo for javax.vecmath.Vector2f, of course (but without any imports, we're still guessing).
    – Toby Speight
    May 2 at 12:58










  • Vector class is written by me and it represents the geometrical 2D vectors with x and y coordinates.
    – Emre Sülün
    May 9 at 7:25












up vote
-1
down vote

favorite









up vote
-1
down vote

favorite











Let's say I have an abstract class Character that have fields health and maxHealth. maxHealth differs between subclasses. However, the first way I implemented it the health is always initialized as equals to maxHealth.




public abstract class Character 
protected Vector position;
protected int health;
protected int maxHealth;

public Character(float xLocation, float yLocation)
Vector position = new Vector(xLocation, yLocation);
health = maxHealth;



public class Grunt extends Character
public Grunt(float xLocation, float yLocation)
super(xLocation, yLocation);
maxHealth = 200;





But this didn't work correctly because health is assigned to maxHealth before maxHealth was initialized as 200.



I tried to change constructor parameters as follows and it works but I'm not sure that if this is a good practice. What do you think?



public abstract class Character 
protected Vector position;
protected int health;
protected int maxHealth;

public Character(float xLocation, float yLocation, int maxHealth)
Vector position = new Vector(xLocation, yLocation);
this.maxHealth = maxHealth;
health = maxHealth;



public class Grunt extends Character
public Grunt(float xLocation, float yLocation)
super(xLocation, yLocation, 200);








share|improve this question













Let's say I have an abstract class Character that have fields health and maxHealth. maxHealth differs between subclasses. However, the first way I implemented it the health is always initialized as equals to maxHealth.




public abstract class Character 
protected Vector position;
protected int health;
protected int maxHealth;

public Character(float xLocation, float yLocation)
Vector position = new Vector(xLocation, yLocation);
health = maxHealth;



public class Grunt extends Character
public Grunt(float xLocation, float yLocation)
super(xLocation, yLocation);
maxHealth = 200;





But this didn't work correctly because health is assigned to maxHealth before maxHealth was initialized as 200.



I tried to change constructor parameters as follows and it works but I'm not sure that if this is a good practice. What do you think?



public abstract class Character 
protected Vector position;
protected int health;
protected int maxHealth;

public Character(float xLocation, float yLocation, int maxHealth)
Vector position = new Vector(xLocation, yLocation);
this.maxHealth = maxHealth;
health = maxHealth;



public class Grunt extends Character
public Grunt(float xLocation, float yLocation)
super(xLocation, yLocation, 200);










share|improve this question












share|improve this question




share|improve this question








edited May 2 at 12:31









rolfl♦

90.2k13186390




90.2k13186390









asked May 2 at 9:01









Emre Sülün

31




31











  • What is this: new Vector(xLocation, yLocation)? There is no constructor Vector(float, float), or Vector(double, double) (which would also accept two floats).
    – Stingy
    May 2 at 9:38











  • @Stingy, there's not even a type Vector in scope at that point, so we can't even guess what constructors it might have.
    – Toby Speight
    May 2 at 12:07










  • @TobySpeight I assumed Vector refers to java.util.Vector and the import was not included in the code sample. But you're right, theoretically, Vector might also refer to an entirely different class.
    – Stingy
    May 2 at 12:42










  • @Stingy: and I wasn't reading properly when I came here from Review (too used to reading C++ code). It might be a typo for javax.vecmath.Vector2f, of course (but without any imports, we're still guessing).
    – Toby Speight
    May 2 at 12:58










  • Vector class is written by me and it represents the geometrical 2D vectors with x and y coordinates.
    – Emre Sülün
    May 9 at 7:25
















  • What is this: new Vector(xLocation, yLocation)? There is no constructor Vector(float, float), or Vector(double, double) (which would also accept two floats).
    – Stingy
    May 2 at 9:38











  • @Stingy, there's not even a type Vector in scope at that point, so we can't even guess what constructors it might have.
    – Toby Speight
    May 2 at 12:07










  • @TobySpeight I assumed Vector refers to java.util.Vector and the import was not included in the code sample. But you're right, theoretically, Vector might also refer to an entirely different class.
    – Stingy
    May 2 at 12:42










  • @Stingy: and I wasn't reading properly when I came here from Review (too used to reading C++ code). It might be a typo for javax.vecmath.Vector2f, of course (but without any imports, we're still guessing).
    – Toby Speight
    May 2 at 12:58










  • Vector class is written by me and it represents the geometrical 2D vectors with x and y coordinates.
    – Emre Sülün
    May 9 at 7:25















What is this: new Vector(xLocation, yLocation)? There is no constructor Vector(float, float), or Vector(double, double) (which would also accept two floats).
– Stingy
May 2 at 9:38





What is this: new Vector(xLocation, yLocation)? There is no constructor Vector(float, float), or Vector(double, double) (which would also accept two floats).
– Stingy
May 2 at 9:38













@Stingy, there's not even a type Vector in scope at that point, so we can't even guess what constructors it might have.
– Toby Speight
May 2 at 12:07




@Stingy, there's not even a type Vector in scope at that point, so we can't even guess what constructors it might have.
– Toby Speight
May 2 at 12:07












@TobySpeight I assumed Vector refers to java.util.Vector and the import was not included in the code sample. But you're right, theoretically, Vector might also refer to an entirely different class.
– Stingy
May 2 at 12:42




@TobySpeight I assumed Vector refers to java.util.Vector and the import was not included in the code sample. But you're right, theoretically, Vector might also refer to an entirely different class.
– Stingy
May 2 at 12:42












@Stingy: and I wasn't reading properly when I came here from Review (too used to reading C++ code). It might be a typo for javax.vecmath.Vector2f, of course (but without any imports, we're still guessing).
– Toby Speight
May 2 at 12:58




@Stingy: and I wasn't reading properly when I came here from Review (too used to reading C++ code). It might be a typo for javax.vecmath.Vector2f, of course (but without any imports, we're still guessing).
– Toby Speight
May 2 at 12:58












Vector class is written by me and it represents the geometrical 2D vectors with x and y coordinates.
– Emre Sülün
May 9 at 7:25




Vector class is written by me and it represents the geometrical 2D vectors with x and y coordinates.
– Emre Sülün
May 9 at 7:25










2 Answers
2






active

oldest

votes

















up vote
0
down vote



accepted










Another way, to be able to change the value later is to use a setter. MaxHealth could change in case of any bonus you might implements.



public void setMaxHealt(int maxHealth)
this.maxHealth = maxHealth;
this.health = maxHealth;



And in the constructor, simply use the setter.



public Grunt(float xLocation, float yLocation)
super(xLocation, yLocation);
setMaxHealth(200);



Using the constructor is fine, and is a good solution to be honest but when you will find constructor with 20 parameters... you will need other solution.



Note :

Since I said this could be nice to add this setter for a bonus, if you don't want to "heal" your character if is health wasn't full, you can simply check before change the value if this.health == this.maxHealth and set the value based on that.






share|improve this answer




























    up vote
    2
    down vote















    Instead of questioning whether it is a good practice, it would be more helpful to be aware of what your first code actually does. JLS §15.9.4 has this to say about the creation of an object:




    The new object contains new instances of all the fields declared in the specified class type and all its superclasses. As each new field instance is created, it is initialized to its default value (§4.12.5).




    This means that health and maxHealth are initialized to 0 even before the constructor is executed. So your statement health = maxHealth; is completely pointless, because health is only assigned the default value which is already assigned to it.



    I see no problem with your second version (apart from the usage of a non-existent Vector constructor, which I already hinted at in a comment). Every field is initialized in the constructor of the class in which it is declared, which, although not strictly necessary for non-final fields, still makes the code easier to read because you don't have to jump around classes to understand the fields' initializations.



    Also, the class Vector is antiquated. If you don't need synchronization, you'd be better off with an ArrayList (and if you do, there are still better solutions as explained in the link). Besides, you are using a raw type, thereby denying the additional type-safety provided by generics.



    Edit



    Actually, there is a problem in both of your versions that I hadn't spotted earlier: Your constructors never assign a value to the instance variable position. Instead, they declare a local variable with the name position that hides the instance variable. To rectify this, you need to remove the type declaration Vector from the assignment, so that this:



    Vector position = new Vector(xLocation, yLocation); //declares a local variable unrelated to `Character.position`


    Becomes this:



    position = new Vector(xLocation, yLocation); //refers to Character.position





    share|improve this answer























      Your Answer




      StackExchange.ifUsing("editor", function ()
      return StackExchange.using("mathjaxEditing", function ()
      StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
      StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
      );
      );
      , "mathjax-editing");

      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "196"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      convertImagesToLinks: false,
      noModals: false,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );








       

      draft saved


      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193432%2fhealthy-characters%23new-answer', 'question_page');

      );

      Post as a guest






























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      0
      down vote



      accepted










      Another way, to be able to change the value later is to use a setter. MaxHealth could change in case of any bonus you might implements.



      public void setMaxHealt(int maxHealth)
      this.maxHealth = maxHealth;
      this.health = maxHealth;



      And in the constructor, simply use the setter.



      public Grunt(float xLocation, float yLocation)
      super(xLocation, yLocation);
      setMaxHealth(200);



      Using the constructor is fine, and is a good solution to be honest but when you will find constructor with 20 parameters... you will need other solution.



      Note :

      Since I said this could be nice to add this setter for a bonus, if you don't want to "heal" your character if is health wasn't full, you can simply check before change the value if this.health == this.maxHealth and set the value based on that.






      share|improve this answer

























        up vote
        0
        down vote



        accepted










        Another way, to be able to change the value later is to use a setter. MaxHealth could change in case of any bonus you might implements.



        public void setMaxHealt(int maxHealth)
        this.maxHealth = maxHealth;
        this.health = maxHealth;



        And in the constructor, simply use the setter.



        public Grunt(float xLocation, float yLocation)
        super(xLocation, yLocation);
        setMaxHealth(200);



        Using the constructor is fine, and is a good solution to be honest but when you will find constructor with 20 parameters... you will need other solution.



        Note :

        Since I said this could be nice to add this setter for a bonus, if you don't want to "heal" your character if is health wasn't full, you can simply check before change the value if this.health == this.maxHealth and set the value based on that.






        share|improve this answer























          up vote
          0
          down vote



          accepted







          up vote
          0
          down vote



          accepted






          Another way, to be able to change the value later is to use a setter. MaxHealth could change in case of any bonus you might implements.



          public void setMaxHealt(int maxHealth)
          this.maxHealth = maxHealth;
          this.health = maxHealth;



          And in the constructor, simply use the setter.



          public Grunt(float xLocation, float yLocation)
          super(xLocation, yLocation);
          setMaxHealth(200);



          Using the constructor is fine, and is a good solution to be honest but when you will find constructor with 20 parameters... you will need other solution.



          Note :

          Since I said this could be nice to add this setter for a bonus, if you don't want to "heal" your character if is health wasn't full, you can simply check before change the value if this.health == this.maxHealth and set the value based on that.






          share|improve this answer













          Another way, to be able to change the value later is to use a setter. MaxHealth could change in case of any bonus you might implements.



          public void setMaxHealt(int maxHealth)
          this.maxHealth = maxHealth;
          this.health = maxHealth;



          And in the constructor, simply use the setter.



          public Grunt(float xLocation, float yLocation)
          super(xLocation, yLocation);
          setMaxHealth(200);



          Using the constructor is fine, and is a good solution to be honest but when you will find constructor with 20 parameters... you will need other solution.



          Note :

          Since I said this could be nice to add this setter for a bonus, if you don't want to "heal" your character if is health wasn't full, you can simply check before change the value if this.health == this.maxHealth and set the value based on that.







          share|improve this answer













          share|improve this answer



          share|improve this answer











          answered May 7 at 11:01









          AxelH

          31919




          31919






















              up vote
              2
              down vote















              Instead of questioning whether it is a good practice, it would be more helpful to be aware of what your first code actually does. JLS §15.9.4 has this to say about the creation of an object:




              The new object contains new instances of all the fields declared in the specified class type and all its superclasses. As each new field instance is created, it is initialized to its default value (§4.12.5).




              This means that health and maxHealth are initialized to 0 even before the constructor is executed. So your statement health = maxHealth; is completely pointless, because health is only assigned the default value which is already assigned to it.



              I see no problem with your second version (apart from the usage of a non-existent Vector constructor, which I already hinted at in a comment). Every field is initialized in the constructor of the class in which it is declared, which, although not strictly necessary for non-final fields, still makes the code easier to read because you don't have to jump around classes to understand the fields' initializations.



              Also, the class Vector is antiquated. If you don't need synchronization, you'd be better off with an ArrayList (and if you do, there are still better solutions as explained in the link). Besides, you are using a raw type, thereby denying the additional type-safety provided by generics.



              Edit



              Actually, there is a problem in both of your versions that I hadn't spotted earlier: Your constructors never assign a value to the instance variable position. Instead, they declare a local variable with the name position that hides the instance variable. To rectify this, you need to remove the type declaration Vector from the assignment, so that this:



              Vector position = new Vector(xLocation, yLocation); //declares a local variable unrelated to `Character.position`


              Becomes this:



              position = new Vector(xLocation, yLocation); //refers to Character.position





              share|improve this answer



























                up vote
                2
                down vote















                Instead of questioning whether it is a good practice, it would be more helpful to be aware of what your first code actually does. JLS §15.9.4 has this to say about the creation of an object:




                The new object contains new instances of all the fields declared in the specified class type and all its superclasses. As each new field instance is created, it is initialized to its default value (§4.12.5).




                This means that health and maxHealth are initialized to 0 even before the constructor is executed. So your statement health = maxHealth; is completely pointless, because health is only assigned the default value which is already assigned to it.



                I see no problem with your second version (apart from the usage of a non-existent Vector constructor, which I already hinted at in a comment). Every field is initialized in the constructor of the class in which it is declared, which, although not strictly necessary for non-final fields, still makes the code easier to read because you don't have to jump around classes to understand the fields' initializations.



                Also, the class Vector is antiquated. If you don't need synchronization, you'd be better off with an ArrayList (and if you do, there are still better solutions as explained in the link). Besides, you are using a raw type, thereby denying the additional type-safety provided by generics.



                Edit



                Actually, there is a problem in both of your versions that I hadn't spotted earlier: Your constructors never assign a value to the instance variable position. Instead, they declare a local variable with the name position that hides the instance variable. To rectify this, you need to remove the type declaration Vector from the assignment, so that this:



                Vector position = new Vector(xLocation, yLocation); //declares a local variable unrelated to `Character.position`


                Becomes this:



                position = new Vector(xLocation, yLocation); //refers to Character.position





                share|improve this answer

























                  up vote
                  2
                  down vote










                  up vote
                  2
                  down vote











                  Instead of questioning whether it is a good practice, it would be more helpful to be aware of what your first code actually does. JLS §15.9.4 has this to say about the creation of an object:




                  The new object contains new instances of all the fields declared in the specified class type and all its superclasses. As each new field instance is created, it is initialized to its default value (§4.12.5).




                  This means that health and maxHealth are initialized to 0 even before the constructor is executed. So your statement health = maxHealth; is completely pointless, because health is only assigned the default value which is already assigned to it.



                  I see no problem with your second version (apart from the usage of a non-existent Vector constructor, which I already hinted at in a comment). Every field is initialized in the constructor of the class in which it is declared, which, although not strictly necessary for non-final fields, still makes the code easier to read because you don't have to jump around classes to understand the fields' initializations.



                  Also, the class Vector is antiquated. If you don't need synchronization, you'd be better off with an ArrayList (and if you do, there are still better solutions as explained in the link). Besides, you are using a raw type, thereby denying the additional type-safety provided by generics.



                  Edit



                  Actually, there is a problem in both of your versions that I hadn't spotted earlier: Your constructors never assign a value to the instance variable position. Instead, they declare a local variable with the name position that hides the instance variable. To rectify this, you need to remove the type declaration Vector from the assignment, so that this:



                  Vector position = new Vector(xLocation, yLocation); //declares a local variable unrelated to `Character.position`


                  Becomes this:



                  position = new Vector(xLocation, yLocation); //refers to Character.position





                  share|improve this answer

















                  Instead of questioning whether it is a good practice, it would be more helpful to be aware of what your first code actually does. JLS §15.9.4 has this to say about the creation of an object:




                  The new object contains new instances of all the fields declared in the specified class type and all its superclasses. As each new field instance is created, it is initialized to its default value (§4.12.5).




                  This means that health and maxHealth are initialized to 0 even before the constructor is executed. So your statement health = maxHealth; is completely pointless, because health is only assigned the default value which is already assigned to it.



                  I see no problem with your second version (apart from the usage of a non-existent Vector constructor, which I already hinted at in a comment). Every field is initialized in the constructor of the class in which it is declared, which, although not strictly necessary for non-final fields, still makes the code easier to read because you don't have to jump around classes to understand the fields' initializations.



                  Also, the class Vector is antiquated. If you don't need synchronization, you'd be better off with an ArrayList (and if you do, there are still better solutions as explained in the link). Besides, you are using a raw type, thereby denying the additional type-safety provided by generics.



                  Edit



                  Actually, there is a problem in both of your versions that I hadn't spotted earlier: Your constructors never assign a value to the instance variable position. Instead, they declare a local variable with the name position that hides the instance variable. To rectify this, you need to remove the type declaration Vector from the assignment, so that this:



                  Vector position = new Vector(xLocation, yLocation); //declares a local variable unrelated to `Character.position`


                  Becomes this:



                  position = new Vector(xLocation, yLocation); //refers to Character.position






                  share|improve this answer















                  share|improve this answer



                  share|improve this answer








                  edited May 2 at 10:57


























                  answered May 2 at 10:46









                  Stingy

                  1,888212




                  1,888212






















                       

                      draft saved


                      draft discarded


























                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193432%2fhealthy-characters%23new-answer', 'question_page');

                      );

                      Post as a guest













































































                      Popular posts from this blog

                      Greedy Best First Search implementation in Rust

                      Function to Return a JSON Like Objects Using VBA Collections and Arrays

                      C++11 CLH Lock Implementation