It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
My brother works as a teacher in secondary school, and is grading an exam. He asked the question: "What is the purpose of a constructor?"
So now there were some answers like "The constrcutor creates an object..."
Of course he wanted to see something like "The constructor is called after the object's instanciation and is used to initialize an object's member variables..." (just an example)
The problem is that there is a lot of literature where the authors write that the constructor in Java creates the object, and in general most authors seem to avoid a detailed explanation of the whole process.
I think it works like this:
The class constructor is called as an operand of the new operator, since "the name of the constructor provides the name of the class to instantiate." (see http://docs.oracle.com/javase/tutorial/java/javaOO/objectcreation.html)
But before executing this constructor the new operator instantiates the class (allocates memory etc.) and sets the member variables to their default values.
Then the constructor is executed and initializes member variables for example.
In the last step the new operator returns a reference to the object.
But I really don't know if this is actually right, and if things happen in the exact order.
Does anyone know about object creation in detail? How does it work if you create a subclass? Is the superclass created first, its constructor called next, then the subclass merged into the existing construct somehow, and its constructor called then? Could someone somehow argue that a constructor "CREATES" an object?
I am really looking forward to reading your answers!
The gory details are covered in the Java Language Spec, here is the basics that you need to know on an every day level (continues in the next section, I pointed you at the class initialization which happens the first time a class has new called on it (there are other ways for it to happen too)).
new allocates the memory for the object and initializes it to 0, null, false (depending on the type). That is why all the instance variables are guaranteed to have initial values.
Assuming new succeeds the constructor is called to allow the programmer to perform other initialization/tasks.
The first thing that a constructor does is call the parent constructor (super(...)). That happens all the way up the hierarchy until it reaches java.lang.Object which has no parent.
Before the constructor is executed any instance initialization blocks are run, followed by any instance variables that have assignment operators.
There is a special case if an instance variable is marked as final and has an assignment operator which seems to happen before the call to super if I remember right (there is some trick to it).
All of this is why you should never refer to this.method() (implicitly or explicitly) or pass this out of the constructor because you will be making use of an unfinished object.
Your explanation is correct, as far as I know.
The main idea behind constructors is that you can enforce valid states for an object.
Consider a class called "Rational" with two properties: numerator (int) and denominator (int)
The code would look like this (I've omitted the getters and setters for brevity)
public class Rational {
private int numerator;
private int denominator;
public Rational(int numerator, int denominator) {
this.numerator = numerator;
this.denominator = denominator;
}
public double getRationalValue() {
return (double) numerator / denominator;
}
public static void main(String[] args) {
Rational oneFourth = new Rational(1, 4);
System.out.println(oneFourth.getRationalValue());
}
}
As you can see, I've written a constructor that "demands" values for the numerator and denominator. If you only had a default constructor, anyone could make instances of Rational without specifying a numerator or denominator, and if you don't specify a value for an int variable, they are initialized at zero. And everyone knows the universe collapses if you divide by zero, so we'd like to avoid that.
Anyway, constructors don't make the object, as you correctly explained. You should see them more as a method that is called "post construction".
When it comes to base classes, the constructor of the base class is always called first. This ensures that you can access protected properties of the base class in your subclass constructor.
Since every class in Java inherits from Object, the Object constructor is always called first.
The following snippet:
public class Base {
protected String baseProperty;
public Base() {
System.out.println("In base constructor");
this.baseProperty = "This gets initialized first";
}
static class Sub extends Base {
private String subProperty;
Sub() {
System.out.println("In sub constructor, baseProperty = " + baseProperty);
}
}
public static void main(String args[]) {
Base base = new Sub();
}
}
prints:
In base constructor
In sub constructor, baseProperty = This gets initialized first
Right from the specification to clear your doubt about the new and constructor role:
Creating Objects
As you know, a class provides the blueprint for objects; you create an object from a class. Each of the following statements taken from the CreateObjectDemo program creates an object and assigns it to a variable:
Point originOne = new Point(23, 94);
Rectangle rectOne = new Rectangle(originOne, 100, 200);
Rectangle rectTwo = new Rectangle(50, 100);
The first line creates an object of the Point class, and the second and third lines each create an object of the Rectangle class.
Each of these statements has three parts (discussed in detail below):
Declaration: The code set in bold are all variable declarations that associate a variable name with an object type.
Instantiation: The new keyword is a Java operator that creates the object.
Initialization: The new operator is followed by a call to a constructor, which initializes the new object.
Related
I am confused as to the purpose of empty constructors, let me ellaborate:
if I have a class..
public class Test {
private int x;
private int a[];
private static int y;
public Test() {
a = new int[3];
}
}
I know that there exists an empty default constructor:
public Test() {
//or at least I think it exists
} //what is its purpose?
if I have a main method and code the following:
Test t1 = new Test();
Which constructor is called? or is the empty constructor overwritten by the one which instantiates a[]?
If I then instantiate 5 instances of Test, how many integer memory locations are allocated?
Sooo confused....
The empty constructor is inherited from the Object class, which is the superclass of all classes in Java. It merely allocates memory of the objects, but does not initialize anything.
So for every object it is possible to call new A(), even if public A() is not defined explicitly.
Sometimes you don't need to do extra job in the constructor, so you can just use the default one without bothering reimplementing it.
When a child class overwrites it, then the one called is the new one. It makes perfect sense, because when you bother overwriting a method, you want to be able to use it instead of the default one.
In your examples, the Test class contains 2 integers, and an array of 3 integers.
Each time you instantiate a new Test, you allocate space for two more integers and the array of three integers. This is why those are called instance variables: it means they belong to an instance. So each instance has its own.
If you do not define any constructor for your class then compiler will automatically add a default parameter-less constructor to your class definition so that objects can be created using new keyword. If you explicitly define a parameter-less constructor (the way you have done) yourself then compiler will not add anything from his side.
So in this line of code
Test t1 = new Test();
the constructor that you have defined explicitly will be called.
To answer your second question - Each instantiation of your class results in allocation of memory required to hold an array containing 3 integers. For 5 instances it will simply become 5 times.
i.e. 5 * 3 * memory occupied by one integer
Which constructor is called? or is the empty constructor overwritten by the one which instantiates a[]?
Since you have provided constructor for Test class, your constructor will be called. If you want to call super class constructor explicitly, change your code as
public Test() {
super();
a = new int[3];
}
From oracle documentation page on constructors
You don't have to provide any constructors for your class, but you must be careful when doing this. The compiler automatically provides a no-argument, default constructor for any class without constructors. This default constructor will call the no-argument constructor of the superclass. In this situation, the compiler will complain if the superclass doesn't have a no-argument constructor so you must verify that it does. If your class has no explicit superclass, then it has an implicit superclass of Object, which does have a no-argument constructor
If I then instantiate 5 instances of Test, how many integer memory locations are allocated?
JVM will allocate space for 1 integer for static variable ( int y, which is class or static variable)
JVM will allocate space for 1 integer for each Test instance for int x, which is instance variable
JVM will allocate space for 3 integers for each Test instance for int a[] array, which is instance variable
Total : Space for 5 + 5 + 15 (=25) integers
In the code below I get a compiler error at b.printname();. As I understand it the error is to do with the fact that the compiler is effectively operating in a non polymorphic way( i.e. the compiler is essentially only choosing to look at the left side of the operand and therefore b is a Question). Since b is of type Question and since Question does not have a no-args printName method you get a compilation error. Is that correct?
Now assuming that is correct, my question is why? Surely the compiler should know that Question b is referring to an object that does in fact support the no-args printName method? E.g. if you look at how the compiler behaves in terms of casting there are examples where the compiler, for lack of a better word, acts polymorphicly or to put it a different way the compiler knows what's going on in terms of the right hand side of the operand and acts upon that knowledge. An example would be if an interface type refers to an object that implements the interface, then the compiler looks at the right hand side of the statement (i.e. the object that implements the interface) and decides no cast is required. So why doesn't the compiler act that way here, why doesn't it look and see that the object in question is actually a Blue and that a Blue does indeed support the no-arg method printName?
public class Polymorf3 {
public static void main(String[] args){
Polymorf3 me = new Polymorf3();
me.doStuff();
}
public void doStuff() {
Bat a = new Bat();
Question b = new Blue();
//a.printName();
a.printName(a.name);
b.printName(); // Compiler Error:Required String Found no args
}
abstract class Question {
String name="Question_name";
public void printName(String name){ System.out.println(name);}
}
class Bat extends Question {
String name = "Bat_Bruce";
//public void printName(){ System.out.println(name);}
}
class Blue extends Question {
String name = "Clark";
public void printName() {System.out.println(name);}
}
}
Though b is of type Blue, since you declared it as Question b = new Blue();, the compiler treats it as type Question, and thus that's the only interface available to it without an explicit cast:
((Blue)b).printName();
Alternatively, you can declare it as Blue b = new Blue(); and b.printName(); will not throw a compile time error.
Essentially what's happening here is that you're declaring your new variable b at a higher level of abstraction, so the only printName method available to b is the one in the higher level of abstraction, the one with the args.
Edit:
OP asked why the compiler treats b as a Question even though it's initialized as Blue. Consider the following:
Question q = new Blue();
// ... some other code...
q = new Bat(); // Valid!!
q.printName("some string");
Now consider that tomorrow, some other developer comes in and changes it to the following:
Blue q = new Blue();
// ... some other code...
q = new Bat(); // Invalid!! Compiler error
q.printName("some string");
Declaring a variable at the highest level of abstraction required for your operation means you can later change the implementation more easily and without affecting all the rest of your code. Thus, it should be clear why the Java compiler is treating b as a Question. It's because b can, at any time, become an instance of Blue or Bat, so treating it as the implementation (Blue or Bat) would violate the contract of the Question interface by allowing some other non-arg getName method.
You seem to have misunderstood what polymorphism means. It means that you can treat an instance of the derived class as if it was an instance of the base class. That includes not calling methods on it that the base class doesn't provide. The variable type informs what methods you can call, and the instantiation type determines what implementations of those methods are run.
By putting your Blue instance in a Question variable, you are asking to treat it like a Question. If you wanted to call methods on your Question variable that are not provided by the Question class, then why have it be a Question variable at all? If you could call derived-class methods on a base class variable, it would not be a base class variable.
I am working on an assignment that I'm trying to debug currently. I have numerous error: (method name) in class (SuperClass Name) cannot be applied to given types;. The project is repurposing a game centered around Procedural programming to the same game, but now around OOP. I'm new to Java and have been tasked with creating numerous Classes, two of which are subclasses to a Superclass (obviously), and I have been given what methods to have and their parameters. The problem I am having is that one method in a subclass is supposed to control a battle between two characters, the player and an enemy. Both of these classes are the subclass to the character class (superclass). Since this is a class assignment, I don't want to post everything that I have, but below is an example of the battle method I'm trying to perform. The problem I'm experiencing, and continue to have with "inheritance" in general, is exactly what is inherited between parent/child classes and how to pass certain values/variables between each of them.
In the example code below, this method is nested within the Player class that extends a Character class. This method needs to use and enemy from the Enemy class and perform the actions within. Depending on the outcome, I pass back a boolean to the main method of my program.
My problem is this; I'm unsure how to call a class that has been made "Player" class in this example, within a method that is already contained under the "Player" class. I was asked to use one argument for the method when called, Enemy. I'm positive that I'm not approaching this particular assignment in the appropriate way and there is a much better way to deal with this. But any help to understand what is possible is much appreciated as it will help me approach this assignment in the correct way.
Sample Method from the Player class is as follows:
public abstract class Character{ //Character Superclass - attack method called
public int attack(Player _player){
Random randomNumbers = new Random();
int enemyRandAtk = randomNumbers.nextInt(Weapon.getMaxDamage - Weapon.getMinDamage) + Weapon.getMinDamage;
int enemyAtk = enemyRandAtk + getStrength();
int charRemainingHP = _player.getHitPoints() - enemyAtk; //can I call _player in the Character class????
System.out.printf("%s attacks with ATK = %d + %d = %d\n", getName(), getStrength(), enemyRandAtk, enemyAtk);
System.out.printf("%s HP is now %d - %d = %d\n\n", _player.getName(), _player.getHitPoints(), enemyAtk, charRemainingHP);
return charRemainingHP;
}
public class Player extends Character{
public int attack(Enemy _enemy){
Random randomNumbers = new Random();
int enemyHP = _enemy.getHitPoints();
int charRandAtk = randomNumbers.nextInt(Weapon.getMaxDamage - Weapon.getMinDamage) + Weapon.getMinDamage;
int charAtk = charRandAtk + getStrength();
int enemyRemainingHP = _enemy.getHitPoints() - charAtk;
System.out.printf("\n\n%s attacks with ATK = %d + %d = %d\n", getName(), getStrength(), charRandAtk, charAtk);
System.out.printf("%s HP is now %d - %d = %d\n\n", _enemy.getName(), enemyHP, charAtk, enemyRemainingHP);
return enemyRemainingHP;
}
public boolean battleWizard(Enemy _enemy){
Random randomNumbers = new Random();
Scanner userInput = new Scanner(System.in);
int spellCast = randomNumbers.nextInt(4) + 1;
System.out.printf("*** %s vs The Evil Wizard ***\n\n", getName()); //getName() is in Player Class
boolean charWinning = false;
int updWizHP = _enemy.getHitPoints(); //****** Question 1. below
do{
System.out.print("Choose your action: \n" +
"1. Attack\n" +
"2. Attempt Spell Cast\n\n" +
"What would you like to do?: ");
int battleDecision = userInput.nextInt();
if (battleDecision == 1){
updWizHP = Player.attack(_enemy); //**** Question #2 Below
if (updWizHP <= 0){
charWinning = true;
break;
}
}else if(battleDecision == 2){
System.out.print("Enter your guess: ");
int playerGuess = userInput.nextInt();
if (playerGuess == spellCast){
System.out.printf("The %s's spell is cast successfully! The Wizard's HP is now 0!\n\n", getName());
charWinning = true;
updWizHP = 0;
break;
}else{
System.out.print("Your spell missed the Wizard. Now he attacks!\n");
}
}
if (getHitPoints() > 0){
enemyDamage = Enemy.attack();
decreaseHitPoints(_enemy.attack(Player)); \\**** Question #3 below
if (getHitPoints() < 0){
charWinning = false;
break;
}
}
}while(getHitPoints() > 0 && _enemy.getHitPoints() > 0);
if (charWinning)
return true;
else
return false;
}
}
Please keep in mind that this is a method within a subclass (Player) that holds roughly the same methods as (Enemy) short of this one and a few others.
In terms of my code above, here are my specific questions:
Line 6 in method battleWizard (#1 Question in notes) - Since this method resides in the Player class, can I reference the Enemy class in this way? If not, what is a better way of doing so?
Line 12 in method battleWizard (#2 Question in notes) - How can I reference a class that has an object created in it's own name when the method (code example) is in the class itself? I'd like to take the end-user's player player and reference that object within itself, if that makes sense? I am trying to visualize how the compiler will perform this task and can't imagine this ever working.
13 Lines from the bottom (#3 Question reference in notes):
a) can you pass a method as a parameter to another method like this in Java?
b) is the proper way to invoke another subclass (same subclass level as the one calling the class) like this or is it even possible?
Thank you for the help. As I mentioned before, since this is a class assignment I'd prefer not to provide more samples of my code. But inevitably, if it helps me to understand then I will. Please let me know what further information you need.
ETA:
I added additional code to portray the relationship between the super and subclasses. For the Enemy subclass, it relies on the Character superclass for the attack method. So in my code example above, I hope that it clarifies 3.b. of my question. Any further information required, please let me know.
You are getting compilation errors because you defined attack(Player _player) which means you are allowing only Player objects to be passed but you are using like Player.attack(_enemy) which means passing Enemy object.
You need to correct this. Read my para, "As an aside...".
Line 6 in method battleWizard (#1 Question in notes) - Since this
method resides in the Player class, can I reference the Enemy class in
this way? If not, what is a better way of doing so?
As per your code sample, int updWizHP = _enemy.getHitPoints(); is a valid and sensible call if you want to get the hit points of the enemy. _enemy is your Enemy object and you can all any method on it as long as that method exists in that class.
Line 12 in method battleWizard (#2 Question in notes) - How can I
reference a class that has an object created in it's own name when the
method (code example) is in the class itself? I'd like to take the
end-user's player player and reference that object within itself, if
that makes sense? I am trying to visualize how the compiler will
perform this task and can't imagine this ever working.
Since Player is extending Character, so you would have attack method inherited in Player class (visualize this is as defining attack method in Character class). So, you really don't need to use updWizHP = Player.attack(_enemy); but you can simply use updWizHP = attack(_enemy);. However, this is a compilation error, read my first and last portion of answer.
Now, since attack method is not using any instance field of Player class (state of the Player class) so you need not to worry but if it was then you had to think and decide that on which Player class object you want to call your attack method.
13 Lines from the bottom (#3 Question reference in notes): a) can you
pass a method as a parameter to another method like this in Java? b)
is the proper way to invoke another subclass (same subclass level as
the one calling the class) like this or is it even possible?
For #3.a: Using decreaseHitPoints(_enemy.attack(Player)); you are not passing method to another method BUT first _enemy.attack(Player) will be evaluated and as your code an int would be returned and that value will be passed to decreaseHitPoints.
For #3.b: You are not invoking any sub-class but you are calling method on a object, it doesn't matter if the class that object represent lies in the inheritance tree or not. Only thing you need to make sure that it is a logical call and that method exists in the class.
I guess _enemy.attack(Player) will give you compilation error because you are not defining Player as an object reference variable. You have to use some variable, cannot use class name like this. Better use _enemy.attack(this)
_enemy.attack(Player) this suggests that in attack method you want to pass an Player object, now either you use _enemy.attack(this) which means pass on current object on which battleWizard is getting called (make sense) or use _enemy.attack(new Player()) which means create a new object of Player class and pass that one.
As an aside, I think you better be defining public int attack(Player _player){ as public int attack(Character _character){ because like this in future you can use attack method to pass an Enemy object or some sub-class of Character
That's the beauty of "Inheritance" and "Program to interface". I would recommend you to search and learn about these 2 concepts.
Few quick notes for you, may be you will be aware (these are general notes trying to expose the topic/concept, there could be more limiting behavior, so please read more on each topic/concept):
An object is a runtime representation of a class.
Methods of super class are inherited by sub-class, and to call them you need not to use an object, if you are calling from same class. Visualize this as defining that method in same class (read more on inheritance in context public v/s protected v/s private methods).
You can override the inherited methods.
A method accepting a super type can be invoked with object of any of its subclass. For example, in your case giveMeAnyCharacter(Character char) can be used as giveMeAnyCharacter(new Person()) or giveMeAnyCharacter(new Enemy()).
In Java this means current object or instance and super means super class. So, either create a new object or if you want to use the same object on which you are presenting working then use this.
Always put your all common code (method or instance fields) in super class and let sub-classes take advantage of it using inheritance.
So, Java has "visibility" for methods and fields (and classes too), that defines what exactly is visible to an other class. Look up f.e. JLS 6.5.7.1-1, Simple Method Names and Visibility.
However, in your case "cannot be applied to given types" implies that you pass to a method different parameter types than what the signature says.
Still, for question 2, you just write this.attack(_enemy), or simply attack(_enemy). (BTW, what's with the underscores? I hope it's an artifact from the conversion and not something in your style guide)
Question 3: just use _enemy.attack(this).
BTW, you have your OO terminology mixed up - one passes instances of classes around.
Your question is quite unclear, but I think the problem is your lack of terminology as well as a lack of understanding. I'll try a few pointers for you:
Line 6 in method battleWizard - Since this method resides in the
Player class, can I reference the Enemy class in this way? If not,
what is a better way of doing so?
int updWizHP = _enemy.getHitPoints(); //****** Question 1. below
If getHitPoints() is in the Player class, you cannot call it with an Enemy instance. Fields and methods must exist in the classes of the instance being used in the call, or in their inheritance tree (super classes).
If getHitPoints() is both common to both Player and Enemy, you should place the method in the nearest class common to both - in your case, it would be the Character class. Putting the method in the Character class (and giving it protected or public visibility) allows it to exist in both Player and Enemy classes (and to be called using associated instances of Player and Enemy)
How can I reference a class that has an object created in it's own
name when the method (code example) is in the class itself?
The only thing I can possibly imagine you describing here is the this keyword (which you don't seem to be using in your code). this represents the current instance of the class you are in.
So using this.attack(_enemy) is how you would get the current Player instance to attack the specified enemy.
a) can you pass a method as a parameter to another method like this in
Java? b) is the proper way to invoke another subclass (same subclass
level as the one calling the class) like this or is it even possible?
a) No. Java does not allow methods to be passed as parameters. If you want to pass a method, you must pass an instance (of a class containing the method) as a variable - say x - and then call the method you want to execute as x.method(). What you are doing is calling a method and using the return value as a parameter which is perfectly allowed.
decreaseHitPoints(_enemy.attack); // passing a method - not allowed
decreaseHitPoints(_enemy.attack(Player)); // passing a return value from calling a method - OK
b) I think what you want is this.decreaseHitPoints(_enemy.attack(this));. Yes, you can (and should) call methods in other classes - but if your calling class is unrelated (i.e not inherited from), you can only call those methods if they have been declared with public visibility.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
If i use so
class Test {
public Test() {
System.out.println("constructor");
}
}
public class MainClass {
public static void main(String[] args) {
Test t1 = new Test();
Test t2 = new Test();
}
}
I get 2 outputs
constructor
constructor
But if I add void to constructor (public void Test()) - output is empty. Why is so strange ?
It's not strange, it's its normal behaviour. Constructor does not have a return type
public Test() {
System.out.println("constructor");
}
is a constructor, but
public void Test() {
System.out.println("constructor");
}
is a simple method that you can call using t1.Test().
This page lists the differences between constructors and methods:
1) First difference between method vs constructor in Java is that name of constructor must be same with name of the Class but there is no such requirement for method in Java. methods can have any arbitrary name in Java.
2) Second difference between method and constructor in Java is that constructor doesn't have any return type but method has return type and return something unless its void.
3) Third difference between constructor and method in Java is that Constructors are chained and they are called in a particular order, there is no such facility for methods.
4) Unlike method, constructor, yet declared in class doesn't considered as member of Class. Constructors are not inherited by child classes but methods are inherited by child classes until they are made private. on which case they are only visible in class on which they are declared. Similarly private constructor means you can not create object of that class from outside, this is one of the technique used to implement Singleton pattern in Java.
5) Another difference between method and constructor in Java is that special keyword this and super is used to call constructor explicitly. no such thing for method, they have there own name which can be used to call them.
Because if you add void to the constructor that is no longer a constructor. It's just a method that happens to have the same name as the class.
Then, you could ask "but how can I call the constructor if one doesn't exists?" Well, every class has implicit, no-args constructor.
Conclusion: constructor must not have a return type.
Constructors don't have a return type .Methods have return type. If you add void() then it turns to a method . To invoke the method you need to call it .
t1.test();
Its java language specification.
Docs saying
A class contains constructors that are invoked to create objects from the class blueprint. Constructor declarations look like method declarations—except that they use the name of the class and have no return type.
When you write:
public Test()
{
System.out.println("constructor");
}
This is definitely a constructor. And, as you create first object of Test class by writing:
Test t1 = new Test();
This would call your constructor for the first time, and the code you have written in print statement, that is, constructor would be printed on console.
Remember, constructors are automatically called when you create an object of the class.
Second time you create object by writing:
Test t2 = new Test();
This would call the same constructor, and print the same "constructor" on screen, but it would be second time.
So you get the answer as-
constructor
constructor
In the second case, when you write:
public void test()
{
System.out.println("constructor");
}
your compiler would treat it as a method rather than a constructor.
Even if void does not return anything, it is a "return-type" and constructors can never have a return type, never.
This does not mean that they do not return you anything, but they just do not have a return type.
So, a method is not called automatically when the object of the class is created. So, you should not expect same result.
Now, you get an empty output because compiler provides a dummy/default constructor to every class, even if you do not define it. And, this default constructor would be called everytime you create a object of the class, no matter if you call it explicitly or not!
a default constructor can be thought of written somewhere as:
test() { }
so now you can imagine what happens when you create two objects, program would compile and run correctly, returning empty output to you!
I hope that helped you.
Because constructors don't have a return type. What you create when you add a void return type is a method named Test() that returns nothing.
The compiler gives you a no-arg constructor, since you didn't write any, and that does nothing because it's not the method you created.
A java constructor has the same name as the name of the class to which it belongs. Constructor’s syntax does not include a return type, since constructors never return a value.
public Test() {
System.out.println("constructor");
}
If you add return type to Constructor then it will not be a constructor no longer. It is something like a method.
So I'm learning java. I'm one month in and I just learned about constructors. But I don't see the whole purpose of creating one. Why and when would I ever want to use one? I get the whole idea that it does not have a main method and you can call a constructor from your main class. Anyone can enlighten me on this topic, it would help me a great deal.
Constructors are what you use to initialize/set up the instances of your classes.
If you have an object that needs some processing before it is usable (initializing members for instance), you should do that in the constructor.
Ideally, you should never have "partially built" objects (i.e. objects that are "live", that you hold a reference to, but that are not yet usable). Without constructors, you'd be permanently creating partially built objects, and that is very error-prone. (Theory and practice don't always match, but keep that idea in mind.)
You use a constructor to create new objects. Yes, you can write Java just using static methods - but then you're really not writing object-oriented code, and you'll have a hard time using much of the standard library, either.
Most of your time you should be working with and thinking in terms of objects - and they need to be constructed before they can be used... and that's where constructors come in. They create an object, often with parameters specifying the initial state or other important information about the object.
To be honest, it's probably not worth worrying about them just yet, if you don't see the point yet. It's likely that as you learn more, you'll naturally start using objects more (maybe collections to start with, for example) and you'll get the hang of it. Rest assured, it is important to have constructors in Java, but I'm sure you'll understand why in the course of time. (Of course, if this answer has helped you to appreciate their value already, I'm glad - but if not, don't worry :)
It might seem as if you're having trouble understanding the basic concepts of objects and object-oriented programming. An explanation by example; This class represents a type of thing, namely a car:
public class Car{
// Licence plate number. This is private, so it can
// not be accessed directly from outside the class.
private String hiddenRegNr = "";
private static String description = "This is a car".
// The constructor, which sets the value of hiddenRegNr
public Car(String regNr){
hiddenRegNr = regNr;
}
// Method for reading hiddenRegNr, the only
// way to access it after instantiation.
public String getRegNr(){
return hiddenRegNr;
}
// A static method. Can be used withouth instantiation.
public static String getDesc(){
return description;
}
}
From some other class, you could call this class, and make instances of it; actual representations of different cars. They represent different cars, but are based on the same "model", i.e., the class Car.
Car myFirstCar = new Car("SR12345");
Car myOtherCar = new Car("XZ54321");
Now you have two different cars, with two different registration numbers. These are independent instances of the type car. They exist in memory, and may contain different values (in this case, different registration numbers).
myFirstCar.getRegNr(); // Will return SR12345
mySecondCar.getRegNr(); // will return xz54321
The first thing to notice here, is that you can only specify the registration number once per car, namely upon creation. That is the point of the constructor: It sets values, and does other stuff that needs to be done when objects (instances) are created.
Now, note the difference between getRegNr() and getDesc(): The keyword "Static" means that the second method is related directly to the class, and not to each instance. This means that:
Calls to getDesc() is made on the class, not an instance:
Car.getDesc();
Calls to getDesc() will return the same value for all instances of the class car
The variable description (which is also static) will be the same for all instances of Car
The static method getDesc() CAN NOT access the variable hiddenRegNr, since that variable is related to a specific instance. Trying to refer to a variable in an instance from a static context (such as getDesc()) will cause an exception to be thrown. You might say that hiddenRegNr will not have been set when you call
Car.getDesc();
because the constructor was never called, so it was never given any value.
Constructors are used to initialize a class and give parameters to a class. What is important is that they let you set the class state on creation. This allows you to use specific instances of a class with different data field values instead of relying on purely static information. Take the following example:
class Obj {
private int state = 0;
public Obj(int state) {
this.state = state;
}
public Obj() {
state = 1;
}
}
Now in main (or wherever) you can have:
Obj obj1 = new Obj();
Obj obj2 = new Obj(2);
The two objects have different states (one is at state 1, the other is at state 2). If you were relying on static methods and members, the objects would share one state and would not be independent of each other.
It is also important to note that constructors (specifically the new keyword) allocate memory for a given object internally so you don't have to worry about using malloc and other memory management. So they are important in that sense as well.
It is used to create objects. Objects are the main concept in OOP, so creating them is an important step. The main class method is just an entry point to your program. If you don't create objects your program will be procedural rather than object-oriented. This is why to use a constructor.
And why to create a constructor - sometimes you need to construct an object with some required parameters. There is also a default no-argument constructor, but if you want to initialize your object with additional arguments - you create a constructor taking those arguments.
Actually constructor is needed IF you need to assign unique initial state to an instance of a class. In Java i only just realized (by a friend) that we can do this:
public class MyClass1 {
private class MyClass2 {}
private MyClass2 myobj2 = new MyClass2();
}
So no need for implicit constructor.
But if something like follows, you need constructor.
public class MyClass1 {
private class MyClass2 {
private int id_ = 0;
public MyClass2(int id) { id_ = id; } // how to reach this?
}
private MyClass2 myobj2 = new MyClass2(1); // (this doesn't work. Not unique)
public MyClass1(int id) { myobj2 = new MyClass2(id); } // by this!
}
MyClass1 obj1 = new MyClass1(100);
MyClass1 obj2 = new MyClass1(200);
I will give you an example, imagine you have a car class.. when you call the constructor of the car class you have an car object. on this car object is possible to use diffent methods. And you could create as many as car objects as you want.