Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object-Oriented programming private class field + get / set or public class field?

I'm a junior developer (currently exercise Java) and I have one question about the correctness of my code, here is an example: I am writing a simple MMO-game representation on Java, I have 2 classes (Character and spell). Character has properties (mName, mHealth and mEnergy), Spell class has properties (mSpellName, mSpellCost, mSpellDamage). And Spell class also have a method called execute, here is a code

public void spellExecute(Character caster, Character target) {
caster.mEnergy -= this.spellCost;
target.mHealth -= this.spellDamage
}

This construction implies that Character fields are public and can be accessed directly, but in some examples I seen that all fields must be private and can be accessed only via get/set methods. My question is: Which way is more correct, in general? It's important to me because I wanna write a good code :)

like image 542
Vitaly Sulimov Avatar asked Mar 18 '23 00:03

Vitaly Sulimov


1 Answers

Generally, you would use get/set methods, because they allow the class to control access, via those methods

Any other class which uses your class, should only be able to access and change your fields in the way you describe.

For example let's look at a simple (oversimplified) fuel pump

class Pump
{
    constant int PRICE_PER_LITRE = 100; //in pence

    private int litresDispensed;
    private bool nozzleUp;
    private int litresAvailable;
    private int price; //in pence

    construct()
    {
        litresDispensed = 0;
        nozzleUp = false;
    }

    startFuelling()
    {
        nozzleUp = true;
    }

    stopFuelling()
    {
        nozzleUp = false;
    }

    takeFuel(int litresTaken)
    {
        if(nozzleUp = true)
        {
            litresAvailable -= litresTaken;
            price += litresTaken * PRICE_PER_LITRE;
        }
        else
        {
            error("You must lift the nozzle before taking fuel!");
        }
    }

    getPrice()
    {
        if(nozzleUp = true)
        {
            error("You can't pay until you've finished fuelling! Please return the nozzle");
        }
        else
        {
            return price;
        }
    }
}

Our final get method is important to ensure that the rest of the transaction is complete before the person tries to pay.

If we allowed direct access to the price, they could do it before they've finished taking fuel! And that would let them steal all our fuel.

As this shows, a get method protects the field from outside influence. It can still be manipulated, but only in the ways we want to allow it to be manipulated. Note also that there's no set method at all for this field: we don't want the user to be able to set their own price, only the one we dictate!

If you write get/set methods which only return and set the field, without any validation or checks, then you could simply make the field public (or, alternately, you need to decide whether that field should be accessed directly at all): that said, it's good practice to use get/set methods where possible, because it allows you to add validation in the future without breaking code.

like image 112
Jon Story Avatar answered Mar 19 '23 14:03

Jon Story