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.
Related
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.
I have the following:
public class BogusSuper {
public BogusSuper(Collection<String>... a) {}
public BogusSuper(String... a) {}
}
And in another class, I do:
public class BogusSub extends BogusSuper {
public BogusSub() {/*Prevent calling super's constructor*/}
}
When I try to compile, I get the error: "reference to BogusSuper is ambiguous, both constructor BogusSuper(java.util.Collection...) in BogusSuper and constructor BogusSuper(java.lang.String...) in BogusSuper match.
BogusSuper compiles just fine. Why does BogusSub have issues when I'm not actually calling any of BogusSuper's constructors? I've tried explicitly setting multiple constructors as well, none of which refer to the superclass.
You have varargs parameters (SomeType... arg), which is syntactic sugar for an array of SomeType. When you call such a method, the type is inferred from the parameter, but when you don't provide parameters the type can't be inferred, so both methods are equally a match.
The reason you are "calling" the constructor is because when you don't define a constructor, one is implicitly defined for you with no arguments, - the "default constructor" ie:
public BogusSub() {
}
And if you don't call a super() constructor explicitly, an implicit call is made to the default constructor, ie, it really looks like:
public BogusSub() {
super(); // oops, can't tell which one you want
}
To resolve it, provide typed versions of your own constructor:
public class BogusSub extends BogusSuper {
public BogusSuper(Collection<String>... a) {
super(a); // typed to Collection<String>...
}
public BogusSuper(String... a) {
super(a); // typed to String...
}
}
You have no explicit constructors in BogusSub, and the compiler can't work out which of the two varargs constructors in the superclass it should call for the default no-arg constructor it's trying to automatically add for you.
You can make the desired super constructor explicit by adding in a no-arg constructor like so (assuming this is something like what you want):
public class BogusSub extends BogusSuper {
public BogusSub() {
super(Collections.emptyList());
}
}
Alternatively, you could add a no-arg constructor into BogusSuper if this is more appropriate.
We all Know that the JVM provides us a default constructor in the every java program.
But if we declare any other type of constructor then it does not provide the any type of default constructor.
So, my question is that is it compulsory to declare default constructor when we declare any other type of constructor in our program.
If YES then explain Why?
If NO then also explain Why?
Give the Solution with proper suitable example.
No, it's not compulsory at all. There are loads of classes with no default constructor, and there's nothing stopping you from writing your own. One that springs to mind is java.awt.Color.
Declaring the default constructor depends on the business requirement and technically its not compulsory.
If you want a class to be initialized only with a set of parameters, then you can skip the default constructor, which indeed forces you -- to give the required values to create the object
For instance,
public class ClassA {
String name;
ClassA(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
For the above class, if you want to do,
ClassA obj = new ClassA();
This is not possible as there is not default constructor.
ClassA obj = new ClassA("name");
The above is the only way to create object, as name is the parameter should be given.
If you want both to be created, add default constructor as
ClassA() {}
Which provides way to create the object with out name.
No, it's not cumpolsory.
class Dog {
Dog(String name)
{
system.out.println("Dog :" + name);
}
public static void main(String[] args)
{
Dog d = new Dog("dollar"); // works fine
Dog d2 = new Dog() // error , no default constructor defined for Dog
}
}
So, my question is that is it compulsory to declare default
constructor when we declare any other type of constructor in our
program.
No, It's not necessary to have a default constructor.
If NO then also explain Why ?
Default Constructor will be provided by Compiler, only if you don't defined any no argument Constructor. But, Keep in mind the following, Check mode from JLS
8.8.9. Default Constructor
If a class contains no constructor declarations, then a default
constructor with no formal parameters and no throws clause is
implicitly declared.
If the class being declared is the primordial class Object, then the
default constructor has an empty body. Otherwise, the default
constructor simply invokes the superclass constructor with no
arguments.
It is a compile-time error if a default constructor is implicitly
declared but the superclass does not have an accessible constructor
(ยง6.6) that takes no arguments and has no throws clause.
It is not necessary to create the default constructor, but it is good practice to create the default constructor.
If your class is to be reused then not creating the default constructor will limit the re-usability of your class.
Like if a class is extending that class, then the derived class must have an explicit super call.
consider the following example:-
class Base
{
public Base(int x){
//some statements
}
/*
some methods
*/
}
class Derived
{
// only one of the following will be used
public Derived(){ // This will cause a compile-time error
//some statements
}
public Derived(){ // This will work fine
//some statements
super(x);
}
/*
some methods
*/
}
The reason behind this is, if the base class do not have default constructor than derived class must call the appropriate super() in all its constructor declarations. But if we have a default constructor in base class then the call to super() is not mandatory.
No, it's not compulsory!
But then if you dont have a default constructor(No-argument constructor) and if you want the to create the object of your class in this form
A ref = new A();
then you might not be able to do it.
No this is not necessary.
let me explain why this is not necessary
The question which you've asked is seems like constructor overloading.
If you create an or many parameterized constructor in java then you do need need to be worried for the default constructor.
Basically constructor is used to initialize the instance variables or class members or for performing the preliminary tasks and if you have already done with this by using the another constructor then there is no need for another but you can do if you want.
public class base {
int a;
public base(int x)
{
this.a=x;
System.out.println(x);
}
public base()
{
System.out.println("abc");
}
public static void main(String []a)
{
base b=new base();
b=new base(4);
}
}
The output is :-
abc
4
i was developing the below code....
class P {
//public P(){}
public P(int i) {
}
}
class D extends P {
public D(){ // default constructor must be defined in super class
}
}
public class agf {
public static void main(String[] args) {
}
}
Now in class p explicit parametrized constructor is defined and in class D default constructor is defined but it is still showing the compile time error ,please explain
Your parent Class P explicitly defines a constructor, due to which no-arg constructor will not be added automatically. When you write a no-arg constructor for class D without having a specific constructor call for the class P using super keyword as mentioned below,
Class D extends P {
public D() {
super(10);
}
}
you are instructing it to call the no-arg constructor of P. Since P only has constructor that you defined, it cannot call the no-arg constructor of P.
In simple terms every object of D will have part of P. But it has no idea how to initialize / construct that P part, since it has no no-arg constructor.
In the subclass, if you don't invoke a superclass constructor explicitly, there must be a default superclass constructor that the VM can invoke for you.
In the superclass, if you explicitly define a constructor, the default no-argument constructor is NOT generated by the compiler.
Therefore, in the situation you show, you defined a non-default constructor in the superclass, which prevented the compiler from generating the default no-arg constructor. Then in the subclass, you didn't explicitly invoke a constructor in the superclass. The compiler tried to generate a no-arg superclass constructor call and didn't find a suitable constructor to call.
Inside this constructor:
public D()
{
// no call to super?? implicit call to super()
}
There is an implicit call to the empty constructor of the super class (which doesn't exist in your case)
Either implement an empty constructor in the super class, or call the parameterized constructor explicitly, e.g.:
public D()
{
super(1);
}
I would suggest you read this tutorial as well.
When creating an instance of class D, the constructor of P is first called (since D is also P). The problem is that P's constructor cannot be called since a value has to be provided to it, and that's something you're not currently doing.
To fix that, the first line in D's constructor have to be super(value), while value can be a parameter sent to D's constructor, or..anything else you want (in case you want to leave D's constructor a default one).
You can go through it step-by-step in debug, it can help to clear things out.
In Java, I can't create instances of abstract classes. So why doesn't eclipse scream about the following code?
public abstract class FooType {
private final int myvar;
public FooType() {
myvar = 1;
}
}
The code is fine, the final variable is initialized in the constructor of FooType.
You cannot instantiate FooType because of it being abstract. But if you create a non abstract subclass of FooType, the constructor will be called.
If you do not have an explicit call to super(...) in a constructor, the Java Compiler will add it automatically. Therefore it is ensured that a constructor of every class in the inheritance chain is called.
You can have constructors, methods, properties, everything in abstract classes that you can have in non-abstract classes as well. You just can't instantiate the class. So there is nothing wrong with this code.
In a deriving class you can call the constructor and set the final property:
public class Foo extends FooType
{
public Foo()
{
super(); // <-- Call constructor of FooType
}
}
if you don't specify a call to super(), it will be inserted anyway by the compiler.
You can create concrete sub-classes of FooType and they will all have a final field called myvar.
BTW: A public constructor in an abstract class is the same as a protected one as it can only be called from a sub-class.
What is your doubt?
Ok. See, an abstract class can have a constructor. It's always there-implicit or explicit. In fact when you create an object of a subclass of an abstract class, the first thing that the constructor of the subclass does is call the constructor of its abstract superclass by using super(). It is just understood, that's why you don't have to write super() explicitly unless you use parameterized constructors. Every class even if it is abstract, has an implicit constructor which you cannot see. It is called unless you create some constructor of your own. so long you created abstract classes without creating any custom constructor in it, so you didn't know about the existence of the implicit constructor.
You definitely can declare final variable in abstract class as long as you assign value to it either in the constructor or in declaration. The example that guy gave makes no sense.
No you can't declare final variables inside an Abstract class.
Check Below example.
public abstract class AbstractEx {
final int x=10;
public abstract void AbstractEx();
}
public class newClass extends AbstractEx{
public void AbstractEx(){
System.out.println("abc");
}
}
public class declareClass{
public static void main(String[] args) {
AbstractEx obj = new newClass ();
obj.AbstractEx();
// System.out.println(x);
}
}
This code runs correct and produce output as
abc
But if we remove comment symbol of
System.out.println(x);
it will produce error.