From the java tutorial I see that a class can have two different constructors with the distinction being the number of arguments provided in each constructor, they also give an example of the no constructor parameter. Based on that information and their example. I have written the class to get a better understanding. I also notice that the fields inside the no param constructor can be changed using getter and setter methods, so I do not see differences with a constructor that has parameters. I have read some question here but they don't address this.
My question: Are there specific cases where such constructor SHOULD be used, if yes what is the reasoning behind it and are there benefits?
public class Course {
int numberOfStudents;
String courseName;
String courseLecturer;
public Course() {
this.courseName = "Human Science";
this.courseLecturer = "Jane Doe";
this.numberOfStudents = 22;
}
public Course(String courseName, String courseLecturer, int numberOfStudents) {
this.courseName = courseName;
this.courseLecturer = courseLecturer;
this.numberOfStudents = numberOfStudents;
}
public String getCourseName() {
return this.courseName;
}
public void setCourseName(String courseName) {
courseName = this.courseName;
}
public static void main(String[] args) {
Course courseType2 = new Course("CIV4046F", "Obi", 45);
System.out.println(courseType2.getCourseName());
}
}
No, defining default constructors with "realistically looking" too-specialized magic values is not a good idea, it will only cause trouble later on during debugging ("What's wrong with out database, where did this Jane Doe come from?").
Overriding default constructor might make more sense when there are some "canonical default values". For example, if you were modeling fractions, then setting the numerator to 0 and denominator to 1 would give a nice default representation of a zero as a fraction.
the default parameter constructor is used when the user doesn't affect any value at the instantiation so there is default values that can be used instead of emptiness , and if there is parameters the class use the parameters affected by the user.
There is definitely a use case for a default constructor (the one with no arguments) when you want to provide default values for non-final attributes. However, your example is not the recommended approach to provide such defaults. Your attributes should be initialized in the constructor, otherwise you have go around the class to know where the values come from. This would be better
public class Course {
//You should also keep these private to avoid them being set outside of the class
int numberOfStudents;
String courseName;
String courseLecturer;
public Course() {
this.courseName = "Human Science";
this.courseLecturer = "Jane Doe";
this.numberOfStudents = 22;
}
}
Constructor execution results in creation of an object. Once an object is created the user code is not forced to set any parameter before using the object even though there may be setter methods available.
Parametrized constructor and setter methods.
Suppose there is a class Duck with a parameter height of type int. You may have a setter method to set the height. Now if an object of Duck is created user code may use this invalid object of Duck (of 0 height). Even though setter method is present but still user code is not enforced to set it before using the created object. To enforce creation of object with necessary life giving parameters Parameterized constructors are needed. The setter methods enables you to modify the states during run time of the application. Based on the modified states the behavior of object can also be modified so they have a different use case but parameterized constructor solves different purpose as I mentioned above.
Default constructor on the other hand provide the user to create the object with states set to default values (these defaults may be defined inside the class while fields declaration itself or in super class or in other constructors or methods invoked by no parameter constructor).
you're getting confused because your parameters have the same name as your fields.
your no-arg constructor is setting the fields to the values that they have already have been given, which isn't very useful - there's no point in doing this. your constructor with three args sets the fields to the values that you are passing in. so if you want to set the fields to values other than your defaults, you need to use the constructor with three args. otherwise a no-arg constructor will do (although it doesn't need to do anything).
note also in Java, if you don't provide a constructor, you get a no-arg constructor for free. but as soon as you write a constructor with arguments, you will have to write a no-arg constructor (if you want one).
Your default constructor have no effect on class variables.
Instead of initializing class variable where it is declared you should initialize in the default constructor.
One of the many reasons to override default constructor in java is you want to initialize some class level parameters which you are going to processes in different method and those parameter are must to initialize that class.. There are many example in java for these kind of non default constructors for example
BufferedReader br=new BufferedReader(fr)
Where fr is file reader object. If file stream is not passed to buffer reader you cannot use buffer reader class.
Related
A constructor is used to initialize a value and assign it to the class variable in the time of creating the class instance, right?
public class Joke{
private String jokeSetup;
private String jokePunchLine;
public Joke(String jokeSetup , String jokePunchLine){
this.jokeSetup=jokeSetup;
this.jokePunchLine=jokePunchLine;
}
}
Consider the following:
public Joke(String jokeSetup , String jokePunchLine)
Is another variable with same name created?
If so, why are they assigned to the former jokeSetup and jokePunchLine values?
PS:This code is not created by me.It was shown in the videos from which I am learning Java.
The purpose of a constructor is to initialize the object that was just created, for instance by filling in its instance fields (also called instance variables). this is used in your constructor to refer to the instance the constructor is initializing.
In your example constructor, you have parameters and instance fields. The constructor is taking the values of the parameters and assigning those values to the instance fields:
public Joke(String jokeSetup , String jokePunchLine)
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---- Declares parameters this
// constructor accepts when
// called
{
// vvvvvvvvv------------ parameter
this.jokeSetup=jokeSetup;
// ^^^^^^^^^^^^^^---------------------- instance field
// vvvvvvvvvvvvv---- parameter
this.jokePunchLine=jokePunchLine;
// ^^^^^^^^^^^^^^^^^^------------------ instance field
}
The constructor could initialize instance fields with constant values instead, or by using a parameter value indirectly (for instance, looking something up), etc. It's not always a direct one-to-one assignment as it is in your example.
In your example, the parameters have the same names as the instance fields, but that's not a requirement. For instance, this constructor does exactly the same thing as yours:
public Joke(String theJokeSetup , String theJokePunchLine)
// ^---------------------^---------- Note the name changes
{
// vvvvvvvvvvvv------------ parameter
this.jokeSetup = theJokeSetup;
// ^^^^^^^^^^^^^^--------------------------- instance field
// vvvvvvvvvvvvvvvv---- parameter
this.jokePunchLine = theJokePunchLine;
// ^^^^^^^^^^^^^^^^^^----------------------- instance field
}
Java lets you leave off the this. part when referring to an instance field and just use the field name on its own (e.g. jokeSetup instead of this.jokeSetup). You can't do that in your constructor unless you rename the parameters, though, because they have the same names as the instance fields, so jokeSetup in your constructor is the parameter, not the field. When there's a conflict like that, the most local identifier takes precedence (in your constructor, the parameter is the most local).
When there's no conflict, it's a matter of style whether you use the this. part or not. (I always use this., I find it clearer.) So for instance, here's another version of that constructor which does exactly the same thing as your original:
public Joke(String theJokeSetup , String theJokePunchLine)
// ^---------------------^---------- Note the name changes
{
// vvvvvvvvvvvv------------ parameter
jokeSetup = theJokeSetup;
// ^^^^^^^^^--------------------------- instance field
// vvvvvvvvvvvvvvvv---- parameter
jokePunchLine = theJokePunchLine;
// ^^^^^^^^^^^^^----------------------- instance field
}
I mention this because, again, when there's no conflict, it's a matter of style, and you'll see this style used sometimes.
The class has a field named jokeSetup.
The method has a parameter of the same name that shadows that field.
So in essence there are two variables with the same name.
Using this makes it possible to again differentiate the two different usages of the same name, as this.whatever always denotes the corresponding field.
And you nailed it: shadowing is actually not a good idea. But this "pattern" is actually very common in Java. You could avoid it by giving the parameter a different name, such as _jokeSetup, but deviating from common practices is also bad practice.
A parametrized constructor can be used to initialize value to the variables in the time of creating it. When the parameters and variable names are same then in this case to differentiate between both, we use this keyword. This keyworord always refer to local variable of the method or class.
Java has an implied context for symbol names; the class instance (ie this) for non-static contexts and the class (eg Joke) for static.
This lets you omit the context when there is no conflict for the symbol name. For example
public String getJokeSetup() {
return jokeSetup; // no "this." required, it's implied
}
When there is a conflict for the name such as the case with a method argument named the same as a field, you need to explicitly define the context, eg
public void setJokeSetup(final String jokeSetup) {
// you must prefix the field with "this." to differentiate it from the argument
this.jokeSetup = jokeSetup;
}
Finally, here's an example that avoids a symbol name conflict
public void setJokeSetup(final String js) {
jokeSetup = js;
}
It is fairly typical to name arguments the same as the fields they correspond to but you're certainly not constricted to such a convention.
As we all know, Java reflection provides Class.getConstructors method, but how is the order of the Constructor<?>[] array?
For example, I create Person class and there are 3 construct method:
public Person()
{
}
public Person(int age)
{
this.age = age;
}
public Person(int age, String name)
{
this.age = age;
this.name = name;
}
And by debug, I find the order of constructor array like this:
0 = public xxx.Person(int)
1 = public xxx.Person(int, java.lang.String)
2 = public xxx.Person()
When I look at the Class#getDeclaredConstructors()-method I noticed the following line:
"The elements in the array returned are not sorted and are not in any particular order."
At the Class#getConstructors()-method this isn't mentioned though..
Even though it isn't mentioned, my assumption is that the same applies to that method, which your code kind of proves.
I'm not sure what you want to accomplish (perhaps you could add you goal to your question so we might be able to help your further), but I don't think it's possible to get the Constructors in the same order using reflection.
EDIT: With the constructors in your example, you can call either of the three like this:
Class<Person> pClass = Person.class;
pClass.getDeclaredConstructor().newInstance(); // default constructor
pClass.getDeclaredConstructor(int.class).newInstance(50); // constructor with int parameter
pClass.getDeclaredConstructor(int.class, String.class).newInstance(50, "test"); // constructor with int and String parameters
As constructor order does not matter for java classes there is not specification for getConstructors method order. I think testing you can figured out the default order, but I will not use it as can change any time. If you want to get an specific constructor check parameters or if the order does matter for you process the .java file as a simple text file.
Java documentions.
Returns an array containing Constructor objects reflecting all the
public constructors of the class represented by this Class object. An
array of length 0 is returned if the class has no public constructors,
or if the class is an array class, or if the class reflects a
primitive type or void. Note that while this method returns an array
of Constructor objects (that is an array of constructors from this
class), the return type of this method is Constructor[] and not
Constructor[] as might be expected. This less informative return
type is necessary since after being returned from this method, the
array could be modified to hold Constructor objects for different
classes, which would violate the type guarantees of Constructor[].
Returns:
The Class class has several similar methods, such as getInterfaces, getTypeParametrers, getMethods, getFields, etc.
In most cases, when the order is well defined, it is specified in the javadoc. For example, getInterfaces:
The order of the interface objects in the array corresponds to the order of the interface names in the implements clause of the declaration of the class represented by this object
The javadoc of getConstructors does not comment on order and you should therefore not rely on the specific order you observed as it may change across JVMs and possibly even from one run to another.
The order is unspecified. The javadoc for the Class.getConstructors() method makes no mention of the order of the constructors.
That means that even if you can figure out what determines the order, you cannot rely on the order being the same across all JVM versions.
Interestingly, the javadoc for the the Class.getMethods() method states specifically that you should not rely on the order of the methods returned.
So I am looking at these respective classes (and subclasses)...
public class Control{
public Control(){}
public Control(String name, String type, ContainerControl owner){
//do stuff here
}
}
public class ContainerControl extends Control{
public ContainerControl() { super(); }
public ContainerControl(String name, String type, ContainerControl owner)
{
super(name, type, owner);
controls = new Controls(); //exists somewhere else
}
}
public class SSTab extends ContainerControl{
public SSTab(){ super(); }
public SSTab(String name, String value, ContainerControl owner)
{
super(name, value, owner);
}
}
I am confused about the purpose behind the method declarations with no parameters which use super ().
From the research I have done, I would be inclined to believe that they were necessary for either overloading the methods with properties from respective parent classes, or overriding. However, as they are calling super() which to my understanding would find the parameter-less method in the super class (which once again does the same thing), I don't see what could actually be getting changed.
As a result of being part of a huge project with massive amounts of subclasses I can't just remove the first method declarations from each class and run to see what happens (to identify whether there is a purpose), and I can't seem to find a reference to explain what these initial method declarations which use super are actually doing.
Any help or links would be incredibly appreciated!
Follow up question:
Why can't SSTab just be initialized with parameters with CControl which can be initialized with parameters with Control? I don't see how the parameterless constructor variables are necessary to initialize the kinds of objects, when there are constructor variables with parameters which call super anyways.
This is Constructor Overloading; a constructor is not a method.
I'm not sure where controls is defined, but i'm pretty sure that's a typo. In any case, Super is used to call the parent version of a method/constructor. It's always needed in a constructor for subclasses such as the example you provided. Think of it like this:
SSTab IS A ContainerControl object; so in order to make an SSTab you first have to make a ContainerControl. However, CControl IS A Control object. Therefore, you must first make a Control Object. Kind of like, you were born because your parents were born. They were born because THIER parents were born.
Follow up answer:
What I can say (based on my understanding of your question) is that this is kind of like how there are certain laws to follow. For example, in real life, if you don't have a lawyer one will be provided to you. If you call SSTab(param x, y z), and you don't call the super function (with params x y z), then the default one will be provided to you (which will create an empty CControl, and an empty control). Because you did not define inside SSTab to use the other one, it will use the default one and this is not always what you want to do
This is an example of Constructor overloading - since those aren't really methods.
Constructor overloading in this manner allows you to create a Control object that hasn't been initialised, and a Control object that has been provided a name.
I would assume each class also exposes public methods for setting required fields, but this isn't shown in the example code in the question (understandably, IMO).
Additionally, sometimes it is useful to have parameter-less Constructors when loading objects via Reflection (although you can call a Constructor with parameters using Reflection too).
Common design practice is to make instance variables private and have public getters and setters to access them. But many times I have seen code samples on the internet that have constructors that assign values directly to the private instance variable instead of using the setters inside constructors. Am I missing something?
public class Person{
private String name;
public Person(String name){
//is this right, seems like the whole encapsulation purpose is defeated
this.name = name;
//shouldn't this be used
setName(name);
}
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
}
You are not missing anything. What you do depends entirely on your situation. However, consider this:
It is very common to do parameter validation in a setter. For example, let's say I have a class with field that can hold a value 0 through 10 (the "throws" is unnecessary for the exception type below but I include it for clarity):
public class Example {
private int value;
public Example () {
}
public final int getValue () {
return value;
}
public final void setValue (int value) throws IllegalArgumentException {
if (value < 0 || value > 10)
throw new IllegalArgumentException("Value is out of range.");
}
}
Here, setValue() validates 'value' to make sure it sticks to the rules. We have an invariant that states "an Example will not exist with an out of range value". Now let's say we want to make a constructor that takes a value. You might do this:
public class Example {
...
public Example (int value) {
this.value = value;
}
...
}
As you can see, there is a problem. The statement new Example(11) would succeed, and now an Example exists that breaks our rules. However, if we use the setter in the constructor, we can conveniently add all parameter validation to the constructor as well:
public class Example {
...
public Example (int value) throws IllegalArgumentException {
setValue(value); // throws if out of range
}
...
}
So there are many benefits to this.
Now, there are still cases when you might want to assign values directly. For one, maybe you don't have setters available (although I would argue that creating private or package private setters is still desirable, for the reasons mentioned above, for reflection/bean support if necessary, and for ease of validation in more complex code).
Another reason might be that perhaps you have a constructor that knows, somehow, ahead of time that valid values will be assigned, and therefore doesn't need validation and can assign variables directly. This is usually not a compelling reason to skip using setters though.
However, all-in-all, it's generally a good idea to use the setters everywhere when possible, it will usually lead to cleaner and clearer code that is easier to maintain as complexity increases.
Most of the examples you see where people set variables directly are just people being "lazy" - which is perfectly acceptable if the situation warrants it (perhaps you're writing a quick test program or application and don't want to implement a bunch of setters, for example). There's nothing wrong with that as long as you keep the big picture in mind and only be "lazy" when it's appropriate.
Something I'd like to add based on some of the other answers here: If you override a setter in a subclass, and the data you are setting breaks invariants that the base class assumes, then either the relevant setters should be made final or the base class should not make those assumptions. If overriding setters breaks base class invariants then there is a bigger issue at hand.
You'll notice the getter/setter is final in the above example. This is because our rule is that "any Example must have a value from 0 to 10". This rule therefore extends to subclasses. If we did not have that rule and if an Example could take on any value, then we would not need a final setter and could allow subclasses to override.
Hope that helps.
Sometimes when you would want make the class immutable, it is just one of the things you need to do. And don't have setter methods at all in that case.
Depending on the context, the use of getters and setters is actually a bigger violation of encapsulation than using member variables in constructors. If you want to set the member variable 'name' of this class, either of these approaches would work since the construction is hidden from the caller and thus not violating encapsulation. One warning is that the use of setName within the constructor might call an overrided method in a subclass which may not be what you want (since it may leave name undefined in the superclass).
Here's a similar question to yours that may provide additional insight:
calling setters from a constructor
the private variables are accessible directly anywhere in the class
settng variabels private is to encapsulate them from other classes
Setting variables to private is to encourage encapsulation from other classes.
Unless setName(String) was meant to do something extra (which the method name doesn't imply), it's unnecessary to use the setter while you're in the class where the private variable is.
This does not defeat encapsulation since the private member is still hidden from the other classes
If the modifier method does not contain any logic and just sets the member then there is no difference between directly setting the member of calling its setter method although for better practice the setter should be called.
The setter indicates that this person's name might change in the future and allows it easily without creating an entire person object again.
Initializing variables inside constructor is a very common practice. It can be used to assign values to variables based on which constructor user has called. You cannot write code based on assumption that the client code will invoke setter method to assign value to instance variables. It is always safe to assign default value to a variable when its object is created (i.e inside constructor).
There is a difference between initializing variables within constructor and setting it to different value as per requirement of the calling code(using setter method). Both have different purposes and different objectives.
This is perfectly normal. Some variables might need to be initialized as soon as the object is created, hence it makes sense to pass them in the constructor and many times we may not want to provide setters for those variables to avoid changing the values after object is created.
Its ok to directly assign values with in class provided setter doesn't do any other processing.
Basically setters/getters are used to provide restrictive access to private data such as returning copy of the data instead of reference of private object, validating data in getter etc..
Since the constructor is part of the object itself, and we are sure what we are doing is right, then its ok.
My preferred approach (as described by Joshua Bloch in "Effective Java") is to make the constructor private, make the fields final (i.e., eliminate the setters entirely), and require clients to obtain instances either using the Builder Pattern or Factory Method Pattern, which would take care of any necessary validation to protect invariants. Then the (private) constructor would simply directly assign the given parameters (which have already been validated by the Builder or Factory Method) to the appropriate fields, which are private and final.
I'm trying to get a better understanding than I've been able to so far...it's to help me with class, but not with any specific homework assignment; I'm looking for more conceptual information that I've not found in my textbook or in the tutorials. On a purely theoretical level, I get why encapsulation is powerful for OO programming, but need a better understanding of what, specifically is going on. I keep confusing myself about the path through which data flows, and wonder where we're getting and setting data FROM. Hopefully this is not the exception to the "there are no stupid questions" rule.
Consider:
public class Employee
{
private int empNum;
public int getEmpNum()
{ return empNum; }
public void setEmpNum(int Emp)
{ empNum = emp; }
}
My interpretation of this: Using int Emp passed from somewhere, we set the declared empNum variable in the set... method. We then get... that variable and return it to the calling method. Is that a good understanding?
Further Consider:
import.javax.*
public class CreateEmp
{
public static void main(String[] args)
{
int ssn;
ssn = JOptionPane.showInputDialog(null,"enter ssn");
Employee newEmp = new Employee(123456789);
JOptionPane.showMessageDialog(null,"Employee ID " + newEmp.getEmpNum);
}
}
With this class, I don't need to explicitly set a variable because declaring new Employee(123456789) automagically sends that value to the set... method. The return in the Employee method returns the resulting value to the calling method and makes that variable available, in this case to my dialog box output. Do I have a handle on that?
Here's where I get confused. With my understanding as noted above--which may be off--I can never decide the best place to put logic. For instance: I would place the "enter employee number" dialog box in the Employee class, with a condition to run ONLY if the parameter passed to the method was null. In my mind, as I understand the data flow, the purpose of the class is to get an employee number. If one is not supplied as a default, one needs to be created. I'm not sure if this thinking is best practices, or if I'm setting myself up for trouble later.
I'd love to hear some thoughts about whether or not I'm properly understanding what's happening.
First, this site is to be used more for questions that can be concretely answered; not so much for theoretical questions.
Anyways, the first part with the 'get' and 'set' you understand fine. Now when you said that you do not need to explicitly set the employee number because you do 'new Employee ...' is not quite true. That would work if you had explicitly defined a constructor that takes an integer for an argument and then sets 'empNum' equal to the argued integer value.
Getters and setters are usually used in conjunction with the 'private' modifier. Setters can be used to control the input. For example, you can check if the provided value is greater than zero, where as you cannot if you give direct access. Getters just allow values to be retrieved, but to make changes you force the use of the corresponding setter (if any).
You are right about how if a value is not supplied you should set one by default. Consider that the value that you retrieve (if any) is to be used in a different class. What if the user never set a value? What if it's not something you expected? The different class, whatever it may be, still requires a value and you still need to pass something. By setting a default value, the different class can recognize that, "oh, this is a default value - this means that the user probably did not supply the correct input." By doing so, you create a relatively fail-safe application; you can keep on working even if the input is not what it is expected to be.
The point of using public accessors for private variables is to control how those variables are accessed and to insure that all of the internal state is kept consistent. For example, a class might have both an age and a birthdate variable. Setting the birthdate also implicitly sets the age. If direct access was given to these variables, then it would be possible to set them to inconsistent values (i.e. birthday says they are 30, but age set to 35). By using setters, we can insure that setting the birthdate will reset the age to be correct.
In this example, using setters would also allow us to convert the age variable into a generated property. Since age can be directly determined using the birthdate, you can create a getter for age and have it directly calculate and return the age without needing to store it anywhere.
If we use getters and setters to expose these object properties, we are free to switch out the implementations (such as removing the age variable and calculating it on the fly) without the users of our object needing to worry about it.
It depends how you are using the Employee object. If, upon construction, you always provide the employee number or one is automatically provided and the employee number is never set anywhere else, then you won't need the set method.
However, if at some point you are going to set the employee number to something else (perhaps an error was made and the number needs to be updated), then you will need to have a "set" method. In this case, it would probably be easiest to also call the "set" method from the constructor.
It really depends on how the Employee class will be used/instantiated.
You say
With this class, I don't need to explicitly set a variable because declaring new Employee(123456789) automagically sends that value to the set... method.
I'm pretty sure that's not true. Consider this: Java creates an Employee object and the constructor receives the value 123456789. How does it know to which variable it needs to assign that value? It doesn't know. There can be multiple variables that belong to that object so it doesn't know what 123456789 really means.
When you don't define a constructor in Java, it automatically creates one for you. But that one does not take any arguments, it's just a default constructor. Your code has several compile errors (for example, the import line for javax is wrong) so I'm guessing you're running a previously compiled version of your code. Remove all .class files in your project, fix compile errors and run again. It should give you an error. It'll also make the flow of data a lot easier to understand. The constructor should look something like this:
public Employee(int empNum) {
this.empNum = empNum;
}
It now makes a lot more sense that getEmpNum() knows which value to return.
With this class, I don't need to explicitly set a variable because declaring new Employee(123456789) automagically sends that value to the set... method. The return in the Employee method returns the resulting value to the calling method and makes that variable available, in this case to my dialog box output. Do I have a handle on that?
Your understanding is slightly wrong here. The statement
new Employee(123456789)
is creating a new Employee object by using a constructor method. Constructors usually take parameters which are used to set the internal member variables of the class.
So the complete Employee class would be -
public class Employee
{
private int empNum;
public Employee(int employeeNum) {
empNum = employeeNum;
}
public int getEmpNum() {
return empNum;
}
public void setEmpNum(int Emp) {
empNum = emp;
}
}