I'm currently learning Java and learning about encapsulation and I'm unsure which of the following is a better practice:

  1. Use a getter to return a field value from one class to another and then print it through a method in another class.
  2. Call a method in a class from another class to print the value of the field.

The value isn't manipulated, only shown through System.out.println();

Any advice would be appreciated :)

EDIT: One class (Person) holds information about people, such as name, age, weight etc. and another class (Directory) has a method used to search through a LinkedList of people to find a object with a matching age. If a person is found, then the method prints out the name of the person.

有帮助吗?

解决方案

Encapsulation is all about maintaining a separation of concerns, the core idea of which is that one class should know as little as possible about how other classes work, partly so that you can make changes to those classes without having to change other classes that interact with them.

Broadly: As a rule of thumb, you want each of your classes to do "it's own little thing" - to have its own little concern, with all the logic that goes into doing that little thing encapsulated in private methods of that class. If other classes, in the course of doing their own little things, need to know things from the first class, then you provide getter methods in that class that expose those things without exposing the details of how they are implemented internally.

With respect to your question specifically, the options you mention are actually the same thing: A getter is a method that gets called by other classes to return the value of a field. The advantage of such a method is that it encapsulates that field in the class that contains it, which can then parse/recalculate/store or otherwise interact with that field however it pleases, as long as it's getter returns the expected data type.

To illustrate, imagine you create a BankAccount class with a double balance field. You do a few tests and it seems to work fine, so you create several other classes that reference this balance field. At some point, you notice that some of your calculations are coming up a few cents off. You do some research and find out that it's a bad practice to use double to store monetary values, and that you should be using a class called BigDecimal instead.

If your other classes accessed your balance field directly, they would all have to change (and all would have to import BigDecimal even though they never use it directly) in order to facilitate this change. On the other hand, if they access an account's balance by way of a getter method, you can change the type of balance to BigDecimal in BankAccount while leaving the return type of getBalance() as double, by calling BigDecimal's toDouble() method to return the double value your other classes expect: None of your other classes will ever know you've changed the data type.

Another way of stating the idea of separation of concerns is to say that each class should have a single reason to change (this is the single responsibility principle referenced in @GregKopff's comment): Needing to change the data type of the balance field is a valid reason for BankAccount to change, but would it be a valid reason or all the other classes that interact with it to change? Should you have to change your BankAccountHolder or BankEmployee class because a technical detail in the Account class changed?

This might not seem to answer your question directly, but I think the only answer to this question in general is to illustrate the question you should ask yourself to answer it each time you come across it... which will happen just about every time you write a class.

If my illustration is unclear, please let me know how I can clarify it: You've asked an important question, and it's important that you grasp the answer to it (as well as what you're asking.)

其他提示

My suggestion would be to use Getters and Setters. Getters are public methods which returns the value of their respective fields. Setters are public methods which sets the value of their respective fields.

public class YourClass {
    private String yourMember;

    public String getYourMember() {
        return this.yourMember;
    }
    public void setYourMember(String member) {
        this.yourMember = member;
    }
}

And use these methods to get or set the values of the variable.

public class AnotherClass {
    public void someMethod() {
        YourClass yc = new YourClass();
        yc.setYourMember( "Value" );
        System.out.println( yc.getYourMember() );
    }
}

But if printing the value is part of the behavior of the class, then it would be better if you add a printYourMember() method also to your class. This really is a context sensitive question. Without knowing the actual context, I can not give more specific answer.

Good Luck!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top