What are the alternatives to public fields?

前端 未结 12 2665
刺人心
刺人心 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:31

    Getters and setters are part of the public interface of your class. It's a contract between the class designer/developer and the users of that class. When you define getters and setters, you should be committed to maintain them in future versions.

    Attributes should only correspond the implementation of a given version of the class. In this way, the class developer may unilaterally change the implementation, hence the field, without breaking his/her commitment to maintain the interfaces.

    Here is an example. Consider a class called Point. If you decide that a Point has x and y public attributes, then you may never change this. In contrast, if you have get/set X/Y methods, subsequent versions of the class may use various internal representations: rectangular coordinates (x, y), but also polar (r, theta), etc. All this without modifying the public interface.

    0 讨论(0)
  • 2021-02-19 15:34

    private fields and setters and getters is indeed your best way to go.

    Further note that this is in general good code in any language as it keeps your security nice and tight while also giving you a structure that is far easier to debug and maintain. (Don't forget to document btw!)

    All in all, go with setters and getters, it's just good practice even if you find options.

    0 讨论(0)
  • 2021-02-19 15:36

    A shorter version of your methods...

    public void beDamaged(double damage) {
        health = Math.max(0, health-damage);
    }
    
    public void gainHealth(double gainedHp) {
        health = Math.min(maxHealth, health + gainedHp);
    }
    

    or even the following which can be called with +1 to gain, -1 to lose 1 hp.

    public void adjustHealth(double adjustHp) {
        health = Math.max(0, Math.min(maxHealth, health + adjustHp));
    }
    
    0 讨论(0)
  • 2021-02-19 15:37

    In Java, using private fields with getters/setters is the recommend practice, provided external clients of your class really need access to those fields.

    Otherwise keep them as private fields and simply don't provide a getter/setter.

    There are various reasons why this is a best practice:

    1. If clients are using your field directly and later something needs to change regarding that, you're stuck. With a getter you can do a whole lot of things before the field is accessed.
    2. There is something called the JavaBeans specification that requires you to use getter/setters. Without them your class (then called bean) won't interoperate with that. JSP and JSF's EL is one example of something that required your class to comply with JavaBeans standards.

    (p.s. unrelated to your question, but you'd better not declare backPack as an ArrayList. Declare as List; code to interface, not to implementation)

    0 讨论(0)
  • 2021-02-19 15:37

    About this:

    The thing is that also from what i have seen, (and it seems logical) is that using private fields, but using getters and setters to access them is also not good as it defeats the point of using private fields in the first place.

    The main problem is that many developers automatically generate getters and setters for all private fields. And if you're going to do that, I agree, you might as well keep the field public (no, public fields are even worse).

    For every field that you have, you should check:

    a) does it need a Getter (do other classes need to know the value of this field)
    b) does it need a Setter (do other classes need to be able to change the value of this field)
    c) or does the field need to be immutable (final), if so it must be initialized during definition or in the constructor (and it can obviously have no setter)

    But you should hardly ever (exception: value objects) assume that all private fields will have getters and setters and let your IDE generate them all.

    0 讨论(0)
  • 2021-02-19 15:38

    One advantage not yet mentioned for avoiding public fields: if there aren't any public fields, one may define an interface that includes all the public features of the class, have the class implement that interface, and then have everyplace that uses the class use the interface instead. If that is done, one may later design a class which has completely different methods and fields, but which implements the same interface, and use that class interchangeably with the original. If this is done, it may be useful to have the class implement a static factory method in addition to the constructor, and have the factory return an object of the interface type. Doing that would allow later versions of the factory to return an object of some other type. For example, one may come up with a low-cost version of the object in which many properties return constants; the factory could see if such an object would be suitable, and if so return one instead of the normal object.

    Incidentally, the concept of using a mixture of constant and mutable objects in an adventure goes back at least to 1980. In Warren Robinett's "Adventure" cartridge for the 2600, each object has a number of pointers stored in ROM for things like position and state, so objects which aren't going to move (such as the castle gates or the "signature") don't need to have their position stored in RAM, and most grabbable objects (which don't have any state other than their position) won't need to store a state in RAM, but animated objects like the dragons and bat can store both state and position in RAM. On a machine with 128 bytes of RAM total, such savings were critical.

    0 讨论(0)
提交回复
热议问题