What are the alternatives to public fields?

前端 未结 12 2748
刺人心
刺人心 2021-02-19 15:05

I am programming a game in java, and as the question title suggestions i am using public fields in my classes. (for the time being)

From what i have seen public fields a

12条回答
  •  自闭症患者
    2021-02-19 15:54

    One of the core concepts of object-oriented programming is encapsulation -- that is, hiding an object's state (for example, the data in the object) from the outside, and letting the object handle it's own state.

    When encapsulation is done well, the object's state can only be affected from the outside world through the interfaces provided by the object, such as methods the object has.

    I think your code is already starting to use encapsulation.

    Let's take a look at the code

    Let's take a look at the beDamaged method.

    public void beDamaged(double damage)
    {
        this.health -= damage;
    
        if (this.health < 0)
        {
            this.health = 0;
        }
    }
    

    Here's we can see that this method will be called by the outside world, and the player's health will be affected. It also contains logic, so the health cannot be a negative number. The player's beDamaged method that you wrote is keeping the state of the object within the parameters that you defined as being the valid state.

    Let's infer something about the player

    Now, from the above, I think I can infer the following about the player object:

    A player's health cannot be a negative number.

    Is what we inferred always true?

    Let's see if this can always be true from the code you've provided.

    Aha! We have a little problem here:

    public double health;
    

    With the health field being public, the outside world can directly manipulate the field in order to place the player object's state into one that is probably not desired, by some code like the following:

    Player player = new Player();
    player.health = -100
    

    I'm going to guess that the player shouldn't be in a state where the health is a negative number.

    What can we do about it?

    How could that have been avoided? -- by having the health field private.

    Now, the only way to affect the player's health would be through the beDamaged and gainHealth methods, and that's probably the right way for the outside world to affect your player's health.

    Which also means this -- when you make a field private, that does not automatically mean that you should make getters and setters for the field.

    Private fields does not necessitate getters and setters

    Getters and setters are usually a way to directly affect a field that an object has, maybe with some validation to prevent bad input from making your object have a state that it shouldn't, but there are going to be times where the object itself should be in charge of affecting the data, rather than an outside entity.

提交回复
热议问题