2

I am currently learning Java, and I often get stuck in my programming because of this problem. Maybe since my Java vocabulary isn't sufficient yet to find the right answer. If it is already posted or there is a good webpage where I can find an answer, please let me know!

public class Car {

    private int numberOfDoors;
    private int maxSpeed;

public Car(int doors, int speed) {
    numberOfDoors = doors;
    maxSpeed = speed;
}

Why do we need to create a new int doors and int speed, if int numberOfDoors and int maxSpeed are already created?

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
Marco
  • 33
  • 7
  • 1
    You need those to refer to the values that are passed in at construction time. – Ousmane D. Jul 19 '18 at 16:47
  • 5
    numberOfDoors and maxSpeed are part of a Car object's *state.* doors and speed are just the arguments passed to that particular constructor; the Car instance will forget about them when the constructor exits, unless you copy them into the instance's state. – VGR Jul 19 '18 at 16:48
  • above explanation is also valid for methods, not only constructors. – user85421 Jul 19 '18 at 16:50
  • Possible duplicate of [How to avoid constructor code redundancy in Java?](https://stackoverflow.com/questions/17171012/how-to-avoid-constructor-code-redundancy-in-java) – Sox - Jul 19 '18 at 17:01
  • @Sox I read the page, but I feel that it is for a more advanced person. For a starter that answer is way too complicated to understand and build upon. Thanks anyway! – Marco Jul 19 '18 at 17:08
  • Did you take a look at Jon Skeet answer ? I think it explains it quite well. – Sox - Jul 19 '18 at 17:11
  • @VGR If I would copy them into the Car's state, than how would I be able to not rename them in the constructor again? Wouldn't it just replace the 'numberOfDoors' and 'maxSpeed'? – Marco Jul 19 '18 at 17:11
  • Unrelated, but renaming them to these names is actually removing information that can be used by an ide or in the documentation. While names are arbitrary, they do carry meaning, and here you're losing information about what the parameters represent. – Dave Newton Jul 19 '18 at 17:16
  • I don’t understand what you’re asking. The names are not being copied. doors and speed are variables which hold int values. You are copying those int values, not the names, into your numberOfDoors and maxSpeed instance fields. – VGR Jul 19 '18 at 17:31
  • @Marco see my answer below. – user3437460 Jul 19 '18 at 17:33

5 Answers5

1

Why do we need to create a new int doors and int speed, if int numberOfDoors and int maxSpeed are already created?

numberOfDoors & maxSpeed are the current state of your object. int doors & int speed defines what values you want to assign to your object.


Just imagine your class as a Cake Making Machine:

enter image description here

  • Your machine (your class) requires 2 ingredients (parameter arguments) to make a Cake (make an object).

  • The sugar and flour slots are like the constructor parameters list. (the ingedients needed to create an object)

  • The actual amount of sugar and flour added to the machine are your attribtes of the class.

In codes, this will look like:

public class CakeMachine{

    private Sugar sugarInMachine;  //attribute
    private Flour flourInMachine;  //attribute

    //constructor
    public CakeMachine(Sugar sugarToBeAdded, Flour flourToBeAdded){
        sugarInMachine = sugarToBeAdded;  //assign argument to your attribute
        flourInMachine = flourToBeAdded;  //assign argument to your attribute
    }
}

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
user3437460
  • 17,253
  • 15
  • 58
  • 106
  • Thanks for the example. I understand that I must write it like this, but rationally and emotionally I still find it unnatural and unnecesarry that I must use a 'sugar slot' to say how much sugar will go into the machine. Seeing my example f.e., it states int numberOfDoors first, and then int doors. While if I would follow this example, I would state int doors in the class, and in the connector int numberOfDoors. Is there a conventional way of writing this? Like methods always need verbs. – Marco Jul 19 '18 at 17:44
  • @Marco You feel like we are repeating ourselves because you need to write `numOfDoors` twice. However, that is needed because when you create an object via the constructor, you may not always be required to provide all the attributes stated in the class. For e.g, you may make a car object without knowing the maxSpeed. Then your constructor will only have `numOfDoors`. – user3437460 Jul 19 '18 at 17:58
  • @Marco I'm not sure I understand the issue. `Car` instances have properties, and you need to give those properties their values; in this case, two properties require values. How else would they get their values? – Dave Newton Jul 19 '18 at 20:32
0

Constructor ia recieving arguments of two integer types. Whenever an instance of class will be created, it will require two arguments eg.

Car carinstance = new Car(4, 50);

These parameters which are passed here will be recieved in constructor. The constructor variable's scope is local. These variables can only be used within the constructor.

Now these local variables will be assigned to global variables which are declared in the body of class. These variables are private(within a class), hence can be used within the class in any of its methods and constructors.

Please refer any of the java tutorials to get idea of class, constructors, scope of variables, access modifiers and methods in java. You can start with tutorialspoint to get basic idea.

Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
Abhishek Tiwari
  • 332
  • 2
  • 16
  • I am reading the entire Oracle documentation, but without examples it is not really getting in my head.. That's why I am trying some other pages now, so let's see whether I will get a hang of it. Thank for the help! – Marco Jul 19 '18 at 17:26
  • Do not go with oracle docs initially. Refer some tutorial site first. Once you are familiar with java, then you can go to oracle java docs for detailed help. – Abhishek Tiwari Jul 21 '18 at 09:48
0

Why do we need to create a new int doors and int speed, if int numberOfDoors and int maxSpeed are already created?

Firstly to say, you really don't need. you can stick with the same names under one condition: You have to use the keyword this in order to differentiate the scope of these variables.

Having this:

public class Car {

    private int numberOfDoors;
    private int maxSpeed;

    public Car(int doors, int speed){
       numberOfDoors = doors;
       maxSpeed = speed;
    }
}

This constructor is exactly the same:

public Car(int numberOfDoors, int maxSpeed) {
   this.numberOfDoors = numberOfDoors;
   this.maxSpeed = maxSpeed;
}

The keyword this always refers to the class variable. If not present and the constructor's parameters don't contain any other same-named variable, it works according to the first snippet in my answer - the class variable is found. If both class and constructor's parameters have the same-named variables, the conflict happens and the scope of the constructor is recognised only - therefore it's needed to distinguish them with this.

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
  • Thanks for the answer. Your suggestion will not complicate anything if I add more objects? Or can I use this.numberOfDoors for any object I create after this one? And what is the conventional way of writing it down? – Marco Jul 19 '18 at 17:20
  • The standard convention is the second snippet of my answer. It's always a good practice to refer to the class variables using the keyword `this` for brevity. – Nikolas Charalambidis Jul 19 '18 at 17:32
0

In Java, you have three basic "kinds" of fields, class, instance, and local (this is a simplification.)

Class fields have a static modifier. All instances and all methods share these fields.

Instance fields are defined outside of any method. All instance (non-static) methods of the instance share these fields.

Local fields are defined inside a block; a method is a kind of block. These are shared only inside the block.

Parameters are a special form of local fields where the method is the containing block.

In your code, you have two sets of fields with the same names, one set are instance, one set are local (parameter.) This leads to the local fields "hiding" the instance fields.

You have a couple means of dealing with hiding. One is to rename one set of fields or the other. This is the approach I use. The other is to "qualify" the instance fields using "this." This tells the compiler that you want to always look at the instance to find the fields.

The reason you passed values to your constructor as parameters was to initialize the the instance fields. That way, the instance will be able to use those values once the constructor completes and other methods are called.

Steve11235
  • 2,849
  • 1
  • 17
  • 18
0

You want to build a Car, so you have planned your car, is going to have some doors and want to give max speed for that. But You just planned for the car i.e., you created blueprint for your car(which is class) You have come out of the dreams and start constructing your dream car so that you have to made a real object by using "new" keyword. Car car = new Car(); Now you have made a car but it doesn't have doors and max speed as you have planned.

you can add those doors and max speed by using Car reference 

like this
car.numberOfDoors = 4; car.maxSpeed = 200;

but it seems tedious and not space efficient right? so java designers add a tool that is Constructor.

which is 
   public Car(int doors, int speed){
   numberOfDoors = doors;
   maxSpeed = speed;
 }

 the benefit of this is you can directly add numberOfDoors and maxSpeed when you are creating the object.

Here comes your question you have to explicitly tell the JVM to which parameter initialising which variable otherwise JVM would confuse and ended up build a car having 200 doors with max speed 4. I am sure you can not handle it. Computers are really dumb, and Don't forgot that everything you watching on the screen is processed by things which are made of sand. what do you expect form them is what you told them.

LuFFy
  • 8,799
  • 10
  • 41
  • 59
kishoref22
  • 56
  • 1
  • 12