This question already has answers here:
this() and this
(4 answers)
Closed 2 years ago.
package test;
public class Employee {
String name;
int age;
Employee() {}
Employee(String newName, int newAge) {
this();
name = newName;
age = newAge;
}
public static void main(String args[]) {
Employee e = new Employee("N", 43);
System.out.println();
}
}
In the above code, what is the actual point of "this()" in the overloaded constructor from a usefulness perspective besides being an example of calling the no-argument constructor from the overloaded constructor?
This looks like it's the wrong way round to me.
A typical use of this() would be to provide a default value for the constructor when not supplied in the argument as you cannot call the constructor directly. Adapting your code for example:
package test;
public class Employee {
String name;
int age;
Employee() {
this("Default", 42);
}
Employee(String newName, int newAge) {
name = newName;
age = newAge;
}
public static void main(String args[]) {
Employee e = new Employee();
System.out.println();
}
}
In that exact snippet?
Literally nothing.
Any constructor MUST neccessarily have, at the top of it, either a this() call, or a super() call. You can't not. If you fail to write it, javac will inject: super(); for you, and if that isn't valid (for example, your superclass does not have a protected+ no-args constructor), then your code won't compile.
So that's the difference between the snippet as pasted and a hypothetical one where the this(); is removed. Desugaring, you get either:
Desugared, WITHOUT the this():
package test;
public class Employee {
String name;
int age;
Employee() {
super(); // invokes java.lang.Object's no-args, which does nothing.
}
Employee(String newName, int newAge) {
super(); // invokes java.lang.Object's no-args, which does nothing.
name = newName;
age = newAge;
}
}
Desugared, WITH the this():
package test;
public class Employee {
String name;
int age;
Employee() {
super(); // invokes java.lang.Object's no-args, which does nothing.
}
Employee(String newName, int newAge) {
this();
name = newName;
age = newAge;
}
}
Now, inject, say, a System.out.println("Hello!"); in the no-args constructor and now there is a small difference: With the this(), you'd see Hello! printed, and without it, you won't. Either way, though, you end up calling your superclass's constructor, as that is something that has to happen, one way or another. (Only java.lang.Object doesn't have to, hardcoded in the VM; Object has no superclass).
To call the default constructor, this() is used.
Related
I have 2 subclasses: Staff, Student
they belong to superclass Person.
Here is the code(tasks) which is given by my teacher:
public class Person
{
private String name;
private int yearOfBirth;
/**
* Create a person with given name and age.
*/
Person(String name, int yearOfBirth)
{
this.name = name;
this.yearOfBirth = yearOfBirth;
}
}
class Student extends Person
{
private String SID; // student ID number
/**
* Create a student with no parameters.
*/
Student()
{
//task.
}
}
public class Staff extends Person
{
private String roomNumber;
/**
* Construct a staff member with field values and no pamaeters.
*/
public Staff()
{
//task
}
}
I don't know what can I type in order to create an object without parameter.
It always appears an error like: constructor Person in class Person cannot be applied to given types; required: java.lang.String,int;
I have checked online that there are 2 ways to solve the problem:
add a default value in the superclass: Person()//without parameter.
In the subclass Student:
Student()
{
Person astudent = new Student() //I guess.
}
add a super() in the subclass:
Student()
{
super("xxx")//I guess.
}
I don't know what to do. I an a starter in learning BlueJ.
Hope anyone can help me. Thank you very much.
Since your superclass Person doesn't have a default constructor, in your subclasses (Student and Staff), you must call the superclass constructor as the first statement.
You should define your sub-class constructors like this:
Student() {
super("a_string_value", an_int_value);// You have to pass String and int values to superclass
}
Staff() {
super("a_string_value", an_int_value); // You have to pass String and int values to super class
}
the first thing a constructor will do, is call the constructor (with same arguments) of the super class.
Person does not have a no-argument constructor, so, you must change your code in one of next two ways:
Student(String name, int yearOfBirth)
{
//task.
}
or
Student()
{
super("", 0);
//task.
}
and the same goes for Staff
Add super(NAME_IN_STRING_TYPE,YEAR_OF_BIRTH_IN_INT_TYPE); as a first statement in your subclasse's constructor like
Student constructor
Student()
{
super("name", 1970); // String,int arguments passed
//task.
}
Staff constructor
Staff()
{
super("name", 1970); // String,int arguments passed
//task.
}
This is needed since there is no default no-arg constructor in the base class. You have to explicitly define a no-arg constructor in base class or you need to instruct the compiler to call the custom constructor of the base class.
Note : Compiler will not add default no-arg constructor in a class if it has a user defined constructor. It will add the default no-arg constructor only when there is no constructor defined in the class.
Try this:
Student(String name, int yearOfBirth) {
super(name, yearOfBirth);
// task...
}
Reason: you dont have a default constructor at your superclass. So you have to call super() at the first position in your subclass constructor.
To construct instance of Student you need to do actions neccesary to construct Person first. There is only one way to construct Person - two-arg constructor. That means you have to change Student like:
public Student() {
super("someName", 1950); //first values came to my mind
}
Although you should be aware that Student should behave exactly like Person if treated as Person, i.e. have age and name. So actually I'd recommend to change Student constructor to include name and age there.
If you want to create an object of child class (ie Staff and Student) without passing parameters then you can create an additional constructor without parameters in the parent class (ie Person class) as below.
public class Person
{
private String name;
private int yearOfBirth;
/**
* Create a person with given name and age.
*/
Person(String name, int yearOfBirth)
{
this.name = name;
this.yearOfBirth = yearOfBirth;
}
// additional constructor without parameter
Person(){
// add your code here
}
}
now below code will work without any error.
Staff stf = new Staff();
Student std = new Student();
for constructor no param you should have two constructors like
public class Student {
Student(String name , int dateOfBirth)
{
super(name,dateOfBirth)
}
Student()
{
//task.
}
}
also same for other class
student should not extend person.
bcoz, if we create obj for student, person’s constructor will be called automatically.
I created a new class "Lecturer" which extends another class "Person", i wanted to make 2 constructors for Lecturer and one would accept a name and a stipend (just a constant to say how much pay is), the other just accepts the name and uses the default stipend set in the code. i included appropriate getters and setters. I then wrote a writeOutput method to print an output similar to this
Name: (name) which gets the name and prints it
Stipend: (stipend) same process ^
heres what i have so far
Lecturer.java
public class Lecturer extends Person{
private static String name;
static double stipend;
public Lecturer(String name) {
super(name);
}
public Lecturer(String name, double stipend) {
super(name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getStipend() {
return stipend;
}
public void setStipend(double stipend) {
this.stipend = stipend;
}
public static void writeOutput() {
System.out.println("Name: " + name);
System.out.println("Stipend: " + stipend);
}
}
Person.java
public class Person {
/** Every Person has a name */
private String name;
/** Person requires a name */
public Person(String n) {
this.name = n;
}
/** return this Person's name */
public String getName() {
return this.name;
}
/** Change this Person's name */
public void setName(String nn) {
this.name = nn;
}
Main file (Inheritance.java)
Lines 41-53
Lecturer l1 = new Lecturer("Zachary");
Lecturer l2 = new Lecturer("Wilhelmina", 11017.00);
l1.writeOutput();
l2.writeOutput();
pause();
l1.setName("Zack");
l1.setStipend(10800.00);
l1.writeOutput();
pause();
System.out.printf("%s's stipend is $%,4.2f.\n",
l1.getName(), l1.getStipend());
System.out.printf("%s's stipend is $%,4.2f.\n",
l2.getName(), l2.getStipend());
This is the output
Name: null
Stipend: 0.0
Name: null
Stipend: 0.0
press enter...
Name: Zack
Stipend: 10800.0
The 2nd part works as it should but the first one isnt and i tried to change the code but nothing is working properly.
In Lecturer you are declaring another name variable. This variable is separate from the name variable declared in Person. The call to the superclass constructor is setting the name variable in Person, not in Lecturer. But you don't need the second variable; remove it. You can access the name in Person via the getName method you've already declared. This means that you also don't need to re-declare getName and setName in Lecturer, so the Lecturer class can inherit them.
Also, in Lecturer, the two variables you've declared shouldn't be static. Per the above reasoning, name shouldn't even be there, but even if it should be there, it shouldn't be static. The variable stipend should be there, but it shouldn't be static. When you declare a member variable static, then there is only one variable for the entire class, no matter how many instances you create, which doesn't sound like what you want.
Your constructors should initialize stipend.
You have a static variable inside Lecturer which has the same name as the inherited one from Person and your getter is referring to that static one - are you sure you want these static variables? For completeness if you really want to keep the static one and the inherited one with the same name then change your getter to read return this.name; which will return the inherited name instance variable.... But that method can be inherited from Person class...
There are two name fields in your program , one is private static String name; in Lecturer.java and another is private String name; in person.java .
The thing is that you are just calling Lecturer javs's name field but not setting it.
Fixed the project based on rgettman answer.
Lecturer class should look like this:
public class Lecturer extends Person {
double stipend = 9144;
public Lecturer(String n) {
super(n);
}
public Lecturer(String n, double stipend) {
super(n);
this.stipend = stipend;
}
public double getStipend() {
return stipend;
}
public void setStipend(double stipend) {
this.stipend = stipend;
}
public void writeOutput() {
System.out.println("Name: " + this.getName());
System.out.println("Stipend: " + getStipend());
}
}
I have 2 subclasses: Staff, Student
they belong to superclass Person.
Here is the code(tasks) which is given by my teacher:
public class Person
{
private String name;
private int yearOfBirth;
/**
* Create a person with given name and age.
*/
Person(String name, int yearOfBirth)
{
this.name = name;
this.yearOfBirth = yearOfBirth;
}
}
class Student extends Person
{
private String SID; // student ID number
/**
* Create a student with no parameters.
*/
Student()
{
//task.
}
}
public class Staff extends Person
{
private String roomNumber;
/**
* Construct a staff member with field values and no pamaeters.
*/
public Staff()
{
//task
}
}
I don't know what can I type in order to create an object without parameter.
It always appears an error like: constructor Person in class Person cannot be applied to given types; required: java.lang.String,int;
I have checked online that there are 2 ways to solve the problem:
add a default value in the superclass: Person()//without parameter.
In the subclass Student:
Student()
{
Person astudent = new Student() //I guess.
}
add a super() in the subclass:
Student()
{
super("xxx")//I guess.
}
I don't know what to do. I an a starter in learning BlueJ.
Hope anyone can help me. Thank you very much.
Since your superclass Person doesn't have a default constructor, in your subclasses (Student and Staff), you must call the superclass constructor as the first statement.
You should define your sub-class constructors like this:
Student() {
super("a_string_value", an_int_value);// You have to pass String and int values to superclass
}
Staff() {
super("a_string_value", an_int_value); // You have to pass String and int values to super class
}
the first thing a constructor will do, is call the constructor (with same arguments) of the super class.
Person does not have a no-argument constructor, so, you must change your code in one of next two ways:
Student(String name, int yearOfBirth)
{
//task.
}
or
Student()
{
super("", 0);
//task.
}
and the same goes for Staff
Add super(NAME_IN_STRING_TYPE,YEAR_OF_BIRTH_IN_INT_TYPE); as a first statement in your subclasse's constructor like
Student constructor
Student()
{
super("name", 1970); // String,int arguments passed
//task.
}
Staff constructor
Staff()
{
super("name", 1970); // String,int arguments passed
//task.
}
This is needed since there is no default no-arg constructor in the base class. You have to explicitly define a no-arg constructor in base class or you need to instruct the compiler to call the custom constructor of the base class.
Note : Compiler will not add default no-arg constructor in a class if it has a user defined constructor. It will add the default no-arg constructor only when there is no constructor defined in the class.
Try this:
Student(String name, int yearOfBirth) {
super(name, yearOfBirth);
// task...
}
Reason: you dont have a default constructor at your superclass. So you have to call super() at the first position in your subclass constructor.
To construct instance of Student you need to do actions neccesary to construct Person first. There is only one way to construct Person - two-arg constructor. That means you have to change Student like:
public Student() {
super("someName", 1950); //first values came to my mind
}
Although you should be aware that Student should behave exactly like Person if treated as Person, i.e. have age and name. So actually I'd recommend to change Student constructor to include name and age there.
If you want to create an object of child class (ie Staff and Student) without passing parameters then you can create an additional constructor without parameters in the parent class (ie Person class) as below.
public class Person
{
private String name;
private int yearOfBirth;
/**
* Create a person with given name and age.
*/
Person(String name, int yearOfBirth)
{
this.name = name;
this.yearOfBirth = yearOfBirth;
}
// additional constructor without parameter
Person(){
// add your code here
}
}
now below code will work without any error.
Staff stf = new Staff();
Student std = new Student();
for constructor no param you should have two constructors like
public class Student {
Student(String name , int dateOfBirth)
{
super(name,dateOfBirth)
}
Student()
{
//task.
}
}
also same for other class
student should not extend person.
bcoz, if we create obj for student, person’s constructor will be called automatically.
Java is not my strong suite, so please go easy! :)
I am trying to do construtor-chaining between below super and sub class
//SuperClass
class Furniture{
String name;
int cost;
boolean IsAvlbl;
void Furniture(String name,int cost,boolean IsAvlbl){
this.name = name;
this.cost = cost;
this.IsAvlbl = IsAvlbl;
}
}
//Sub-class
public class Table extends Furniture{
public Table(String name,int cost,boolean IsAvlbl)
{
super(name,cost,IsAvlbl);
}
public static void main(String args[])
{
Table t = new Table("dinning",2600,false);
t.runner();
}
void runner()
{
System.out.println("Name : "+this.name);
System.out.println("Cost : "+this.cost);
System.out.println("Is Avaiable : "+this.IsAvlbl);
}
}
Error popping up is :
Table.java:20: error: constructor Furniture in class Furniture cannot be applied to given types;
super(name,cost,IsAvlbl);
^ required: no arguments found: String,int,boolean
reason: actual and formal argument lists differ in length 1 error
I understand that constructor call has to be the first line and parameters have to be same....I tried doing it but error is persistent.
I would appreciate if some one can tell me why this error is popping up as i want to understand the cause of it..... try it this way kind of solution is not preferred!
Constructor will not have any return type
it should be like
Furniture(String name,int cost,boolean IsAvlbl){
this.name = name;
this.cost = cost;
this.IsAvlbl = IsAvlbl;
}
you have void keyword before constructor, which makes it a method. Since you had return type, java found only "no argument" (default) constructor in Furniture class, hence giving that compilation error.
In Java, constructor should not have return type. Remove void from Furniture constructor
Furniture(String name,int cost,boolean IsAvlbl){
this.name = name;
this.cost = cost;
this.IsAvlbl = IsAvlbl;
}
void Furniture(String name,int cost,boolean IsAvlbl){ // Method
is a method and not a constructor.
Replace it with :
Furniture(String name,int cost,boolean IsAvlbl){ // Constructor
Remember, constructors do not have return-types. Interestingly, you can define a method with the Class-Name (similar to constructors) but the only difference is that, methods will have return-types.
void Furniture() is not the constructor. It is treated as a method in your Furniture class.
public Furniture() is the proper syntax as constructors do not have any return type.
public Furniture(String name, int cost, boolean IsAvlbl) {
this.name = name;
this.cost = cost;
this.IsAvlbl = IsAvlbl;
}
This question already has answers here:
What is the meaning of "this" in Java?
(22 answers)
Closed 7 years ago.
I was studying method overriding in Java when ai came across the this keyword. After searching much about this on the Internet and other sources, I concluded that thethis keyword is used when the name of an instance variables is same to the constructor function
parameters. Am I right or wrong?
this is an alias or a name for the current instance inside the instance. It is useful for disambiguating instance variables from locals (including parameters), but it can be used by itself to simply refer to member variables and methods, invoke other constructor overloads, or simply to refer to the instance. Some examples of applicable uses (not exhaustive):
class Foo
{
private int bar;
public Foo() {
this(42); // invoke parameterized constructor
}
public Foo(int bar) {
this.bar = bar; // disambiguate
}
public void frob() {
this.baz(); // used "just because"
}
private void baz() {
System.out.println("whatever");
}
}
this keyword can be used for (It cannot be used with static methods):
To get reference of an object through which that method is called within it(instance method).
To avoid field shadowed by a method or constructor parameter.
To invoke constructor of same class.
In case of method overridden, this is used to invoke method of current class.
To make reference to an inner class. e.g ClassName.this
To create an object of inner class e.g enclosingObjectReference.new EnclosedClass
You are right, but this is only a usage scenario, not a definition. The this keyword refers to the "current object". It is mostly used so that an object can pass itself as a parameter to a method of another object.
So, for example, if there is an object called Person, and an object called PersonSaver, and you invoke Person.SaveYourself(), then Person might just do the following: PersonSaver.Save( this );
Now, it just so happens that this can also be used to disambiguate between instance data and parameters to the constructor or to methods, if they happen to be identical.
this keyword have following uses
1.used to refer current class instance variable
class Student{
int id;
String name;
student(int id,String name){
this.id = id;
this.name = name;
}
void display(){System.out.println(id+" "+name);}
public static void main(String args[]){
Student s1 = new Student(111,"Karan");
Student s2 = new Student(222,"Aryan");
s1.display();
s2.display();
}
}
here parameter and instance variable are same that is why we are using this
2.used to invoke current class constructor
class Student{
int id;
String name;
Student (){System.out.println("default constructor is invoked");}
Student(int id,String name){
this ();//it is used to invoked current class constructor.
this.id = id;
this.name = name;
}
void display(){System.out.println(id+" "+name);}
public static void main(String args[]){
Student e1 = new Student(111,"karan");
Student e2 = new Student(222,"Aryan");
e1.display();
e2.display();
}
}
3.this keyword can be used to invoke current class method (implicitly)
4.this can be passed argument in the method call
5.this can be passed argument in the constructor call
6.this can also be used to return the current class instance
This refers current object. If you have class with variables int A and a method xyz part of the class has int A, just to differentiate which 'A' you are referring, you will use this.A. This is one example case only.
public class Test
{
int a;
public void testMethod(int a)
{
this.a = a;
//Here this.a is variable 'a' of this instance. parameter 'a' is parameter.
}
}
Generally the usage of 'this' is reserved for instance variables and methods, not class methods ...
"class methods cannot use the this keyword as there is no instance for
this to refer to..."
http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
Here's a trivial example ...
public class Person {
private String name;
private int age;
private double weight;
private String height;
private String gender;
private String race;
public void setName( String name ) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setAge( int age) {
this.age = age;
}
public int getAge(){
return this.age;
}
public void setWeight( double weight) {
this.weight = weight;
}
public double getWeight() {
return this.weight;
}
public void setHeight( String height ) {
this.height = height;
}
public String getHeight() {
return this.height;
}
public void setGender( String gender) {
this.gender = gender;
}
public String getGender() {
return this.gender;
}
public void setRace( String race) {
this.race = race;
}
public String getRace() {
return this.race;
}
public void displayPerson() {
System.out.println( "This persons name is :" + this.getName() );
System.out.println( "This persons age is :" + this.getAge() );
System.out.println( "This persons weight is :" + this.getWeight() );
System.out.println( "This persons height is :" + this.getHeight() );
System.out.println( "This persons Gender is :" + this.getGender() );
System.out.println( "This persons race is :" + this.getRace() );
}
}
And for an instance of a person ....
public class PersonTest {
public static void main( String... args ) {
Person me = new Person();
me.setName( "My Name" );
me.setAge( 42 );
me.setWeight( 185.00 );
me.setHeight( "6'0" );
me.setGender( "Male" );
me.setRace( "Caucasian" );
me.displayPerson();
}
}
In case of member variable and local variable name conflict, this key word can be used to refer member variable like,
public Loan(String type, double interest){
this.type = type;
this.interest = interest;
}
if you have knowladge about c,c++ or pointers, in that language this is a pointer that points object itself. In java everything is reference. So it is reference to itself in java. One of the needs of this keyword is that:
Think that this is your class
public class MyClass
{
public int myVar;
public int myMethod(int myVar)
{
this.myVar = myVar; // fields is set by parameter
}
}
If there is not this keyword you it is confused that this is paramter or class field.When you use this.myVar it refers field of this object.
I would like to modify your language. The this keyword is used when you need to use class global variable in the constructors.
public class demo{
String name;
public void setName(String name){
this.name = name; //This should be first statement of method.
}
}
this is a reference to the current object — the object whose method or constructor is being called. You can refer to any member of the current object from within an instance method or a constructor by using this.
One more thing that should be in mind is that this keyword might be the first statement of your method.
This is used in java. We can use in inheritance & also use in method overloading & method overriding. Because the actual parameter or instance variable name has same name then we can used this keyword complsary . But some times this is not same as when we can not use this keyword complsary.....
Eg:- class super
{
int x;
super(int x)
{
this.x=x
}
}