Confusion over method parameter and instance variable having same name - java

class Employee {
public String name = "John";
public void modifyName(String name)
{
name = name; // I know using 'this' would be helpful, but I dont want to
}
System.out.println(name);
}
class Someclass {
public static void main(String[] args)
{
Employee e1 = new Employee();
System.out.println(e1.modifyName("Dave"));
System.out.println(e1.name); // Does this outputs John or Dave?
}
}
Does the method modifyName behave like a setter and change the instance variable name to be "Dave"?
Do methods only behave like a setter when they follow the naming convention setProperty?
modifyName is not working, will it work if it is named setName?

To directly answer your question, no the naming convention of the method does not cause it to act as a setter.
If that were the case, there would be no need for a method body.
public void setName(String name) {
}
would behave the same as
public void setName(String name) {
this.name = "I don't care what name you gave";
}
Which is not the case at all.
The reason your particular method is not working, is because of the statement:
// I know using 'this' would be helpful, but I dont want to
The reason that you use this.name is to distinguish between the method parameter and the instance member. The instance member is shadowed by the parameter, so without this.name you are simply overwriting the method parameter with itself.
If you absolutely refuse to use this.name for whatever (silly) reason then you should change the name of the parameter:
public void modifyName(String iHateUsingThis) {
name = iHateUsingThis;
}

Within a method, a method parameter takes precedence over an instance variable. The method modifyName refers to method parameter name, not the instance variable name.

If you don't use this for instance variable. Then you are just playing with the method variable in the following statement:
name = name; // I know using 'this' would be helpful, but I dont want to
asa result, nothing will be changed

In modifyName, the name parameter would hide the isntance member, and therefore the instance member won't be set (e1.modifyName("Dave") would change nothing). You should either write this.name = name; or use a different name for the instance member.
Does the method modifyName cannot be a setter only because of the naming convetion? modifyName() treats name as method parameter just because of not using JavaBean naming conventions?
The behavior has nothing to do with the naming convention of the method. It would behave the same if you change it to setName. The only thing that would make a difference is changing the parameter name or instance member name, to make them different.

Within a method block local variable will be used (if the name is same as that of the global variable). Hence there will be no change in the global variable. That's why it is mandatory over here to use this operator to access global variable.

It prints "John"
Saying you don't want to use "this." is just ridiculous. It takes almost no effort to type and vastly improves code quality.
If you don't want to follow Java standards for code style, use inName and then name = inName; or somesuch.

Related

can you use default and parameter constructor at the same time?

I have been assigned to make a class using both default and parameter constructor but the thing is, is that even possible? I don't get how it can even work..both are supposed to assign values to variables
Borrowed from this answer from #bohemian
public class Person
...
public Person() {
this("unknown", 0); // you can call another constructor
}
public Person(String nm, int ag) {
name = nm;
age = ag;
}
...
}
In this example if the no-args constructor is called then unknown and 0 will be passed to the other constructor
When you define another constructor in your class, you do not get the "usual" default constructor (public and without arguments) anymore.
However, you can add it back in:
class MyClass{
MyClass(String param){} // custom constructor
MyClass(){} // bring back the non-arg one
}
Of course, when creating an object instance using new you have to choose which one to call (you cannot have both):
MyClass instanceA = new MyClass("a string");
MyClass instanceB = new MyClass();
The constructors can call each-other (using this(parameters)) or shared methods if there is common functionality in them that you want to keep in one place.
Actually you can't do that in Java, by definition.JLS ยง8.8.9, http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.8.9 says, "If a class contains no constructor declarations, then a default constructor is implicitly declared." So as soon as you add any constructor declaration, even a no-arg constructor, you don't get a default constructor.

what is the use of a parameterized constructor in java?

Im a beginner in java and i wanted to know in a simple way why you should use a parameterized constructor instead of a default one provided by the compiler.
Thanks
You'd need to use parameterized objects anytime you want to pass any sort of configuration into your object. You could use setters to pass in that information later, but not only is it shorter and cleaner to pass that information in at construction time, it lines up with the good practice of creating immutable objects, which cannot be modified after construction and have no setters. For example,
class Student {
private final String name;
private final Date birthday;
public Student(String name, Date birthday) {
this.name = name;
this.birthday = birthday;
}
}
In Java, a constructor is a method which is called by Java runtime during the object creation using the new operator. A reason for creating a constructor could be:
To initialize your object with default or initial state since default values may not be what you are looking for. For example, if you have a person class, containing a name and date of birth, you want these fields to be filled, not empty. So you would pass the values of the name and date of birth into the constructor of that class to assign the object with a value to use in that class.
By the default constructor any attributes your object might have are set to 0, false et cetera. If you want to set the attributes right away you can use a parameterized constructor. Also using you own constructor of course gives you the option of executing code before the object (technically while) is created.
By the way: The answer that "the default won't set any value to the properties" is wrong. For example this code:
public class Test {
private int test;
private boolean test2;
public static void main(String[] args) {
Test test = new Test();
System.out.println(test.test);
System.out.println(test.test2);
}
}
Will print out "0" and "false".
As in any object oriented language, a constructor method is used to allocate and initialize the memory for an object. With this in mind, a parameterized constructor method is used for setting properties of the object to certain value, while the default won't set any value to any of the properties.
In addition to what Louis Wasserman said, there are many situations where paramaterizing constructors makes sense from a logical point of view. Say you want to make an Employee object. There are certain attributes an employee MUST have to even be considered an employee, like a name, social security number, company and ofcourse a salary (slavery is illegal). Therefore, it would be logical to make a parameterized constructor requiring the 4 aforementioned variables.
Constructor helps class to initialize and set values to there some properties that are passed to it.That may be for current object of class.
For Ex.
class Education{
String typeOfEducation; //values are not set
String courseName;
Education(String type,String name){
typeOfEducation=type;
courseName=name; //values are set
}
}
Hope this helps.
I'm surprised no one has brought up overloading in this thread. Parameterized constructors also give the user the ability to set up an object to varying degrees based on information you have at creation time. You can do this with method overloading.
For example:
public Car(long vin){
this.vin = vin;
}
would set up a car object with only a vin number whereas this:
public Car(long vin, String make){
this.vin = vin;
this.make = make;
}
would create a similar Car object with additional information. In addition to overloading, you ought to look into copy constructors as well to get an idea of 'shallow' vs. 'deep' object copies. The following link has a decent example: http://www.geeksforgeeks.org/copy-constructor-in-java/

What is the difference between instance variables in a class or using them as parameters in a constructor in Java?

How is using studentName and studentAverage different in the class or in the constructor?
public class StackOverFlowQ {
String studentName;
int studentAverage;
public void StackOverFlowQ (String stedentName, int studentAverage){
}
}
It's called shadowing, and there's a specific case that applies to this situation.
A declaration d of a field or formal parameter named n shadows, throughout the scope of d, the declarations of any other variables named n that are in scope at the point where d occurs.
To distill that a bit for you:
You have declared fields studentName and studentAverage as formal parameters in your constructor. In the scope of that constructor, any references to the above two names will be treated as using the parameters, and no other higher level field.
If you need to refer to the field, then use the this keyword as if you were dereferencing the field.
this.studentName = studentName;
this.studentAverage = studentAverage;
There's a huge difference in usage not just in variable shadowing, but access as well. On your constructor, you will only ever have the variables studentName and studentAverage available within the scope of it. Someone that instantiates this class can't access the values in those parameters unless they're captured into fields.
Hence, the fields which are similarly named come into play. Those fields, depending on their visibility or exposure through other methods, can actually be used by other classes.
In the constructor, if you wish to reference the instance variables you must preface with this; otherwise you will be referencing the parameters.
For example:
public class StackOverFlowQ {
String studentName;
int studentAverage;
public StackOverFlowQ (String studentName, int studentAverage){
this.studentName = "Paul" // will point to the instance variable.
studentName = "Paul"; // will point to the parameter in the constructor
}
}

In Java, can you call a setter for one class inside a constructor for another class?

If you have two classes Boo and Foo, and each Instance of Foo contains in it an instance of Boo, can you have a Setter for a private attribute in Boo contained inside in the constructor of Foo?
Yes, absolutely. Why would you not be able to?
class Boo {
private String name;
public void setName(String name) {
this.name = name;
}
}
class Foo {
private final Boo boo;
public Foo() {
boo = new Boo();
boo.setName("boo");
}
}
The fact that you ask the question suggests there's something you think might go wrong - what in particular did you have in mind?
A better answer is to try it out yourself.
It is not hard to test and see the results in this case.
How else can your learn how to program if not by doing it?
Yes, you can. I can't see any problem about it.
EDIT:
Uncomment your code. Your getter/setters are just fine.
The problem I see in your new code is here:
this.name = new Name();
Name.setFirstName(firstName);
Name.setLastName(lastName);
Name is a class name. In order for Name.setFirstName() to be a valid call, setFirstName() would have to be a static method in Name. Presumably it is an instance method instead. You need to invoke it for a specific instance of the class, in this case the one referred to by this.name. So the correct code would be:
this.name = new Name();
this.name.setFirstName(firstName);
this.name.setLastName(lastName);
Back to your original question -- my guess is that the advice you were given not to call setters from your constructor was based on an idea along the lines of "constructors should not have side effects". In this case, you are constructing a brand new Name object to be a part of your new Student, so it is perfectly appropriate to make any calls you need to initialize the object.
However, I don't see why you would prefer this to calling Name's constructor. Fewer lines, and the whole thing either succeeds or doesn't.

Setting a Variable in another class results in an error

What I am trying to do is set a value in a variable contained within another class.
this is how I am currently trying to achieve it.
BookingUI Class
private void setCarRegNo()
{
aBooking.setCarRegNo();
}
Booking class
public void setCarRegNo(String regNo)
{
carRegNo = regNo;
}
Yet I keep getting an error saying 'setCarRegNo (java.lang.String) in booking cannot be applied to ()
What is it I am doing wrong? Many thanks
You need to pass a String into the setCarRegNo(String ) of Booking class. The method signature declares that it requires a String argument, and your compiler will complain if you dont supply one.
You have to pass a string into the setCarRegNo() function.
Like this: setCarRegNo("Some string");
In your Booking Class, setCarRegNo takes a single parameter of type String.
When you call it from BookingUI, you are not passing in any parameters.
You need to change BookingUI to something like:
private void setCarRegNo()
{
aBooking.setCarRegNo("CarRegNo");
}
you need to pass a string to your setter. change
aBooking.setCarRegNo();
to
aBooking.setCarRegNo("the registration number');
as a note, you should fully spell out the words of the variables.

Categories

Resources