1

I am new to Java and I would like too know how to properly assign values inside a constructor with parameters. The issue is how to properly encapsulate the values, i.e. do we use set methods or is just using the this keyword enough? Please note I am asking about encapsulation and OOP.

public class cars{
    private String make;
    private String model;
    public String getMake(){
        return make;
    }
    public String getModel(){
        return model;
    }
    public void setMake(String ParamMake){
        this.make = ParamMake;
    }
    public void setModel(String ParamModel){
        this.model = ParamModel;
    }

    // Should it use the setter
    public cars(String make,String model){
        setModel(model);
        setMake();
    }
    // Or
    public cars(String make,String model){
        this.model = mode;
        this.make = make;
    }
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
Musa
  • 35
  • 7
  • 3
    Please stick to **naming conventions**. `cars` should be `Cars`, `ParamModel` should be `paramModel`. – Zabuzard Apr 12 '19 at 09:01
  • In addition to what Zabuza said, classes often model a certain object. That means the class name is often a singular noun. So `cars` should be `Car`. – MC Emperor Apr 12 '19 at 09:36

4 Answers4

2

There are two schools of thought on this:

  1. Never call overridable¹ methods from the constructor, except setters; if you have a setter, always use it, so assignment to the member only ever happens in one central place.

  2. Never call overridable methods from the constructor, not even setters; just assign directly, via this.make = make; for instance.

I believe #2 is the more well-accepted school of thought. The problem with #1 is that if a subclass overrides the setter, you can end up with hard-to-understand crosstalk between the classes during construction.


Side note: Java has well-observed naming conventions. Class names should start with an upper case character; variable, parameter, and method names should not. So Cars, not cars, and paramModel, not ParamModel.


¹ "overridable" - e.g., non-private, non-final methods.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • So wait, the 2nd declaration of an argument constructor is more correct when it comes too the concept of encapsulation but it has its flaws when it comes to things like inheritance? – Musa Apr 12 '19 at 09:22
  • Then the 1st declaration of the argument constructor will have less issues when it comes to inheritance but will also be not enforce encapsulation? – Musa Apr 12 '19 at 09:23
  • 1
    @Musa - Unfortunately, the "first" and "second" in your code are the opposite of the "first" and "second" in my answer (my bad, I've fixed it). I wouldn't say directly assigning in the constructor is worse for encapsulation, no. It *does* create two places where you assign to that member, but I don't think that weakens its encapsulation. – T.J. Crowder Apr 12 '19 at 09:24
  • Please bare with me, so If one where too mark the setters final then would that fix that override flaw of the 2nd argument constructor? – Musa Apr 12 '19 at 09:30
  • @Musa - Yes. That doesn't mean I'm suggesting you do that. – T.J. Crowder Apr 12 '19 at 09:32
  • @T.J.Crowder Strictly speaking, it's perfectly fine to call a non-`final` but private method. In my humble opinion, it should be "overridable". – MC Emperor Apr 12 '19 at 09:38
  • @MCEmperor - That's a much better way to put it. Although in some sense, `private` methods are implicitly `final`. – T.J. Crowder Apr 12 '19 at 09:42
0

Using this. is what you want, getters/setters are for external classes which can't read the fields due to them being private

AleksW
  • 703
  • 3
  • 12
0

This post provide you what you are looking for,

Encapsulation vs Data Hiding - Java

More generally encapsulation refers simply to bundling the data (e.g. of an object) with the operations on that data. So you have a class encapsulating data - fields - along with the methods for manipulating that data.

Note: This is to clear your concepts about Encapsulation.

For your specific answers, its an standard to use this.variableName = variableName, where variableName is your variable.

darshgohel
  • 382
  • 2
  • 13
0

The second approach is good,

public cars(String make,String model){
          this.model = mode;
          this.make = make;
         }

Also note that since you are new to java, in future you may be passing other class es objects to your class constructor, using the above way will help you doing dependency injection as well.

Rohail Usman
  • 119
  • 3
  • 12