Why is calculate() in the constructor executed? - java

in summary
WeatherCalculator calculator = WeatherCalculatorFactory.getInstance(Mode.valueOf(mode));
if(mode==Mode.DEW_POINT)
{
return new DewPointCalculator();
}
public class DewPointCalculator extends WeatherCalculator{
//default constructor
public DewPointCalculator()
{
this(null);
}
public WeatherCalculator(WeatherData weatherData) {
this.weatherData = weatherData;
calculate(); //calculate overriding
}
public WeatherCalculator()
{
this(null);
}
The line breaks are all different classes.
I wonder why calculate() in the constructor is executed when no object has been passed here.

You do call the first constructor with this(null). To call the second, no-argument constructor you can use this().
However, the second constructor still calls this(null) so the first constructor will be called either way.
The thing about null is that null can be anything, and anything can be null.
So by calling this(null) you are passing a WeatherData, it is just null (and using it would result in an error).

You are overloading constructors in class WeatherCalculator this is known as Explicit Constructor Invocation
You have two constructors in the class WeatherCalculator
WeatherCalculator() //Non parameterized constructor
WeatherCalculator(WeatherData weatherData) //parameterized constructor
what happens when you create an object of the WeatherCalculator class the WeatherCalculator() constructor is called which calls this(null) the parameterized constructor(WeatherCalculator(WeatherData weatherData)) and the calculate method is executed.

Related

Sometime it creates an error because there is no constructor and sometimes it's OK [duplicate]

so I have a java class called User that contains a constructor like this:
public class User extends Visitor {
public User(String UName, String Ufname){
setName(UName);
setFname(Ufname);
}
}
And then the he problems occur in my other class called Admin:
public class Admin extends User { //error "Implicit super constructor User() is undefined for default constructor. Must define an explicit constructor"
//public Admin() { } //tried to add empty constructor but error stays there
//}
public void manage_items() {
throw new UnsupportedOperationException();
}
public void manage_users() {
throw new UnsupportedOperationException();
}
}
I am getting the error Implicit super constructor User() is undefined for default constructor. Must define an explicit constructor at the place marked in the code. I don't know how to fix that, and I'm really new to java.
If you don't add a constructor to a class, one is automatically added for you. For the Admin class, it will look like this:
public Admin() {
super();
}
The call super() is calling the following constructor in the parent User class:
public User() {
super();
}
As this constructor does not exist, you are receiving the error message.
See here for more info on default constructors:
http://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html
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.*
You must call the Visitor's constructor on the first like of the constructor that extends the Visitor's class, using super():
public User(String UName,String Ufname){
super();
setName(UName);
setFname(Ufname);
}
and if you want Admin to have a custom constructor too, you must call:
super(uname, ufname) // String, String - pass the params of the superclass cunstructor
So:
public Admin() {
super(someString, someString);
}
Your Admin class extends User, and User doesn't have a default construtor. You need to use the constructor that takes two String(s) with super. Something like,
public Admin() {
super("a", "b"); // <-- first line.
}
Alternatively, you could add a no-args constructor to User
public User() {
}
And then your current Admin would compile.
You need to know two things:
At start of each constructor there is call to constructor of superclass. It is represented by
super() - invoke no-argument constructor of superclass
super(your,arguments) - invoke constructor handling arguments with same types as passed to super(..).
If we want to use no-argument constructor we don't actually need to write super() because compiler will add code representing call to super() in binaries, but compiler can't do this nice thing for us if we want to call super with arguments because
it can't decide which constructor with arguments of superclass you want to use,
and what values (arguments) should be passed there,
so in that case you need to explicitly write super(your,arguments) at start of your constructor yourself.
If you will not add any constructor to your class compiler will add default constructor, which will have no arguments and its only instruction will be calling no-argument constructor of superclass super(). In other words code of classes like
class Base{}
class Derived extends Base{}
is same as this code
class Base extends Object{
Base(){
super();//will try to call Object() constructor
}
}
class Derived extends Base{
Derived(){
super();//will try to call Base() constructor
}
}
Now since in User class there is only one constructor User(String UName,String Ufname) when you try to compile
public class Admin extends User {
public void manage_items() {
//...
}
public void manage_users() {
//...
}
}
compiler see it as
public class Admin extends User {
public Admin(){
super();
}
public void manage_items() {
//...
}
public void manage_users() {
//...
}
}
Now as you see problem lies in
public Admin(){
super();
}
because super() will try to invoke no-argument User() constructor, but there is no such constructor because only existing constructor in User class is User(String,String).
So to make this work you need to add Admin constructor and at its start call super(someString, someString).
So consider adding to your Admin class constructor like this one:
public Admin(String aName,String Afname){
super(aName, Afname);
//here you can place rest of your constructors code
}

Do i need super when creating a subclass or not?

In this program there is no need for a super to reach the superclass's constructor:
class Base{
Base(){
System.out.println("Base");
}
}
public class test2 extends Base{
test2() {
//super();
System.out.print("test2");
}
public static void main(String argv[]){
test2 c = new test2();
}
}
But this program needs super and gives an error at quest1 constructor saying
constructor quest can't be applied to given types: required int, found no arguments
class Quest {
Quest(int y){
System.out.print("A:"+y);
}
}
class Quest1 extends Quest {
Quest1(int x){
//super(x+1);
System.out.print("B:"+x);
}
}
class Test {
public static void main(String argv[]){
Quest1 q = new Quest1(5);
}
}
JLS 8.8.7. Constructor Body
If a constructor body does not begin with an explicit constructor invocation and the constructor being declared is not part of the primordial class Object, then the constructor body implicitly begins with a superclass constructor invocation "super();", an invocation of the constructor of its direct superclass that takes no arguments.
In
class Base {
Base() {
}
}
public class test2 extends Base {
test2() {
//super();
System.out.print("test2");
}
}
The commented out line is added automatically and since the superclass's no-argument constructor is defined, there is no error.
In the case of
class Quest {
Quest(int y) {
System.out.print("A:"+y);
}
}
class Quest1 extends Quest {
Quest1(int x) {
//super(x+1);
System.out.print("B:"+x);
}
}
The implicit call super() is trying to invoke an undefined constructor in the superclass, which causes the error
Implicit super constructor Quest() is undefined. Must explicitly invoke another constructor.
Uncommenting your explicit constructor call replaces the implicit call and thus the problem is resolved. Alternatively, define a no-argument constructor in the superclass.
You need a call to super() if and only if there's no default constructor (accepting no arguments) for your parent class.
In all other cases (where a constructor with zero arguments exists) you don#t have to code it. It's implicitly called anyway.
These Rules apply:
if your parent class has no constructor at all, it has the default constructor, which takes no arguments -> no need for super();
you parent class declares a constructor with no arguments -> no need for super()
your class has a constructor with arguments but no constructor without arguments -> you need to call one of the defined constructors with mathching arguments via super()
If you create a constructor in super class the you should call the super class constructor (Ex : super()) before the sub class constructor gets call.

super() with no arguments in java

I'm checking out this tutorial:
http://www.developerfeed.com/building-todo-list-app-android-using-sqlite
What I do not understand is this piece of code:
public Task()
{
this.taskName=null;
this.status=0;
}
public Task(String taskName, int status) {
super();
this.taskName = taskName;
this.status = status;
}
Why the need to call super() on this point?
Edit: The reason why I'm asking is because I personaly see no need to put it there.
Why the need to call super() on this point?
There is no such need. The compiler will put it in by default.
There is not a need to call super() with no arguments. When you call a constructor of a sub class the 0 parameter superclass constructor gets called automatically. It does not matter if you call it or not.
super() specifically calls the constructor of the class that the current class is inheriting.
In this case, the call for the super() method is calling the constructor for the Object class, which all classes primitively inherit.
And you are right; in this particular case, the call for super() is not required or needed at all.
An example of using super() can be easily made with the reference of the JFrame class.
public class MyFrame extends JFrame {
public static final String TITLE = "My JFrame";
public MyFrame() {
//call constructor of super class (JFrame)
//the String parameter is the title of the frame
super(TITLE);
//other code here
}
//assume other methods are here
}
super(), is for calling the father constructor , i think that your class is not extending from some class, so in JAVA the pure class, extend from Object. When you call super(), you are calling the father constructor in this case Object().
I your constructor public Task(String taskName, int status) You are not calling to public Task() your class is calling the Object constructor Object().
Check this.
http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html
Super is used to call the parent class. When you extend a class you can call a function or variable from the parent class in the child class.
For example Look at this pseudo code which child uses an int defined in the father class
Public class Child extends Father{
Int age = 21;
Int ageDiff = Super.age - age;
}
Super in your code is not needed.

Error - The constructor Level2Class(double) is undefined

My code -
public abstract class Level1Class
{
protected double num = 0.0D;
protected Level1Class(){}
protected Level1Class(double num){this.num = num;}
protected abstract methods A, B, C...etc //pseudocode !
}
public class Level2Class extends Level1Class
{
//NO CONSTRUCTORS HERE
//BUT, only implementation of methods A,B, C
}
public class Tester
{
Level2Class l2c = new Level2Class(10.0D); //This causes the compiler error !
}
Can someone tell me why I get this error. I know it will go if I create the necessary constructor in Level2Class. But, I want to know the reason.
The main reason for the behaviour you describe is that in Java constructors are not inherited. When you create a class, you have two choices:
Do not specify any constructors at all (as in your example). In this case the compiler will automatically add a default constructor (with no parameters).
Create specific constructors (with parameters or without). In this case only the constructors you define will exist in the class, the compiler will not add a default one.
In your example, you are not defining any constructors in class Level2Class, therefore the compiler adds the default constructor with no parameters. Constructor with parameters double doesn't exist in the compiled class and hence your error Constructor undefined.
Level2Class have a only default constructor which would be implemented by compiler. Level2Class does not have constructor which takes double as parameter.
Level2Class l2c = new Level2Class(10.0D);
This will try to figure out double constructor in Level2Class class which is not available because constructor are not inherited.
Create a constructor with a double parameter in Level2Class class
public class Level2Class extends Level1Class
{
Level2Class (double val)
{
// body of the constructor
}
}
constructor in java not polymorphic, when you call new Level2Class(10.0D) program can't find Level2Class(double) it sees Level2Class() which is default constructor in this case.
simply saying after compiling you code would be like:
Level2Class {
Level2Class() { super(); }
}
so you have to declare constructor Level2Class(double) { super(double) } in order this to work
In Java,whenever a class is extended,only the public and protected methods are inherited,but not the constructors.

what is this() ? can it have multiple parameters?

I encountered a code where this() method in java takes three parameters two being integers and the third one is boolean value.
what exactly does that mean ? Are there any other variants of this() method ?
Hera is the actual code.
public SegmentConstructor(int seqNum_, int length_) {
this(seqNum_, length_, false);
}
Thank You..
It means that there is another constructor in the current class that has that signature.
public SegmentConstructor(int seqNum_, int length_) {
this(seqNum_, length_, false); // calls the constructor below.
}
public SegmentConstructor(int seqNum_, int length_, boolean required_) {
seqNum = seqNum_;
length = length_;
required = required_;
}
The this method is just a way to call one of your class's constructors from within another constructor, to help avoid code duplication. It can only be called on the first line of a constructor--never from within any other method.
this simply invokes another constructor to run. So, look for other constructors with that signature.
As said before this invokes another constructor, mostly as a convenience method.
Trivial example:
class A {
private int value;
public A(int val) {
value = val;
}
public A() {
this(0); //0 as default
}
}
Normally you do use calls to this() when the most specific constructor (that one with the most parameters) is not just assignment but contains more logic that you don't want to repeat/copy etc.
Just because it fits in here: super() can have parameters, too, i.e. this calls a super class' constructor with parameters from the sub class' constructor.
It is a constructor call. If your class implements different constructors with a differing number of arguments, you can chain your constructors like this:
class A {
public A(boolean arg) {
...
}
public A() {
this(false); // invokes the constructor with the boolean argument
}
}
Sometimes it makes sense to create a private constructor taking different arguments and provide public and/or protected constructors with other/fewer arguments and delegate object construction to that private constructor.
It is important to know that no other code may be placed before the call to this(...). However, after calling this(...), you can do everything you could in any other constructor.
Edit: Since this(...) calls a constructor, it can only be called from within other constructors (belonging to the same class).
class MyClass
{
private int var1;
private int var2;
private boolean flag;
public MyClass(int var1_,int var2_)
{
this(var1_,var2_,false);
}
public MyClass(int var1_,int var2_,boolean flag_)
{
var1 = var1_;
var2 = var2_;
flag = flag_;
}
public String toString()
{
return (new Boolean(flag).toString());
}
public static void main(String[] args)
{
MyClass my = new MyClass(5,6);
System.out.println(my);
}
}
So it works.
this() is not a method but is a reserved keyword pointing to a overloaded constructor of the same class.
The number of parameters you pass should point to an existing corresponding constructor defined in the class.
The super() also has the semantics however the constructor is defined in one of its parent hierarchy.

Categories

Resources