Why can't this be done? - java

class A {
A(int x) { System.out.println("constructor A"); } }
class B extends A {
B() { System.out.println(" constructor B"); } }
public class C {
public static void main(String args[]) { B b = new B(); } }
It says constructor from class A can't be applied for given types.

You have to call the constructor A(int x) explicitly in your constructor B(). I.e., you have to write
class B extends A {
B() {
super(<<< insert some int here>>>);
System.out.println(" constructor B");
}
}
If you do not add such a super call, then java will insert super(); for you which would try to call A(). As there is no constructor A() you receive the error that your constructor cannot be applied for the argument types.

Its always good to have a default constructor in a class if your writing a paramterized one.
class A {
A(){System.out.println("Default A");}
A(int x) { System.out.println("constructor A"); } }
class B extends A {
B() { System.out.println(" constructor B"); } }
public class C {
public static void main(String args[]) { B b = new B(); } }

If we don't specify a constructor to a class A, then a default constructor with no args will be associated to the class, if you specify one/more constructor to the class A, then you have to use one of them each time you want to create an object from this class.when a class B extend a class A, then constructors have to call one constructor of the parent class ( A ) by super() , if you don't specify a constructor to A then it's implecitly called be the constructor of B, if you explecitly defined constructor of A , then You have to call it when you create constructor of B like this :
B() { super(0)/*this call should be if the first line, you have to pass your default args if the constructor have args*/;
System.out.println(" constructor B");
}

what you are seeing is constructor chaining, read
snippet from the link.
If a constructor does not explicitly invoke a superclass constructor, the Java compiler
automatically inserts a call to the no-argument constructor of the superclass. If the super
class does not have a no-argument constructor, you will get a compile-time error. Object
does have such a constructor, so if Object is the only superclass, there is no problem.

Related

I want to call only child class constructor in multilevel inheritance?

class A {
public A() {
System.out.println("Constructor A");
}
}
class B extends A {
public B() {
System.out.println("Constructor B");
}
}
class C extends B {
public C() {
System.out.println("Constructor C");
}
public static void main(String[] args) {
C c = new C();
}
}
When running the code then it calls all constructor but needs to call only child constructor.
output like only print
Constructor C
Like the comments and the other answer already said, this is explicitly impossible.
If a class (class Foo) extends another class (class Bar), then all constructors of Foo must directly or indirectly call one of the constructors of Bar. This is done either through explicit invocation or implicit invocation.
class Foo {
// No constructor is specified, so a default, empty constructor is generated:
// Foo() { }
}
class Bar extends Foo {
Bar() {
// Explicit call to a constructor of the super class is omitted, so a
// default one (to Foo()) is generated:
// super();
}
}
In the Java Language Specification ยง 12.5 it is written how new instances are created. For any class other than Object the super constructor is always executed.
This constructor does not begin with an explicit constructor invocation of another constructor in the same class (using this). If this constructor is for a class other than Object, then this constructor will begin with an explicit or implicit invocation of a superclass constructor (using super). Evaluate the arguments and process that superclass constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, continue with step 4.
So a super constructor is always called. If you want to print only "Constructor C", then you need to do any of the following:
Change the constructor of B so it no longer prints "Constructor B" by either removing the println statement or removing the no-argument constructor alltogether.
Add a second constructor within B which does not print anything and call it from C:
B(boolean b) {
}
C() {
super(true);
}
Make sure C does not extend B anymore:
class C {
public C() {
System.out.println("Constructor C");
}
}
No, you can't do this. Java will call all constructors according the hierarchy.

Java calling Super constructor confusion

class Yfk {
public static void main(String[] args) {
System.out.println(new YfkC().x);
}
}
abstract class YfkA {
int x = 3;
YfkA() { x++; }
}
class YfkB extends YfkA {}
class YfkC extends YfkB {}
The final result is 4. I am not clear about the extend process. In the main function, we create an object YfkC and invoke Yfkc.x. My understanding is since there is no method and filed in class yfkc, so we find in yfkb, and then find in yfkc. At this time, will YfkC be upcasted to YfkA automatically? Equal System.out.println(new YfkA().x); so we will get x = 4; I am confused about the process from YfkC to YfkA.
new YfkC().x
This internally calls the constructor of the sub class. so the value of x is incremented and printed as 4.
YfkC() -> YfkB() -> YfkA() { x++;};
The default constructor of each class is calling the super();. This calls the default constructor of the super class before executing it's own.
If you want to know about the constructor chaining then put as system out and see the calling chain.
public class Yfk {
public static void main(String[] args) {
System.out.println(new YfkC().x);
}
}
abstract class YfkA {
int x = 3;
YfkA() {
System.out.println("YfkA");
x++; }
}
class YfkB extends YfkA {
public YfkB() {
System.out.println("YfkB");
}
}
class YfkC extends YfkB {
public YfkC() {
System.out.println("YfkC");
}
}
output:
YfkA
YfkB
YfkC
4
When you invoke any Child constructor. There is a chain call to the immediate parent class constructor from the current class. And the call continues until the Object class constructor invokes since that the possible most Parent classes super class is.
Here is an example how constructor behaves in inheritance
public class ParentClass {
public ParentClass() {
System.out.println("Parent default constructor invoked");
}
public ParentClass(int a) {
System.out.println("Parent argumented constructor invoked");
}
public static void main(String[] args) {
SubSubClass sub = new SubSubClass();
}
}
class SubClass extends ParentClass {
public SubClass() {// not calling any super
System.out.println("Child default constructor invoked");
}
public SubClass(int b) {
super(b);
System.out.println("Child default constructor invoked");
}
}
class SubSubClass extends SubClass {
public SubSubClass() {// not calling any super
System.out.println("Sub Child default constructor invoked");
}
public SubSubClass(int b) {
super(b);
System.out.println("Sub Child default constructor invoked");
}
}
OUTPUT:
Parent default constructor invoked
Child default constructor invoked
Sub Child default constructor invoked
I wrote an article covering this topic, hope that clears your doubt.
Constructor inheritance(ovveriding) and reasons behind restricting constructor inheritance in Java
Whenever a child class is instantiated, its parent constructors are invoked in sequence, up the chain.
In your hierarchy, you have:
YfkC
YfkB
abstract YfkA
Object
...and in each of their constructors, there is an implicit call to super().
So, new YfkC invokes YfkB's constructor, which invokes the abstract class's YfkAs constructor, which results in the incrementation of x.
If you were to execute new YfkC().x again, you'd get 5, since every time you new up any of YfkA's children, you would be invoking that constructor.

When should the constructor of the superclass be called from the subclass?

The statement that calls the constructor of the superclass should be the last statement in the constructor of a subclass.
Is it a valid statement?
No, It should be the first statement of the sub class.
Invocation of a superclass constructor must be the first line in the
subclass constructor.
Check here for more details
No,that is not a valid statement.It MUST be the first statement of the child class's constructor.
If you don't add that line,the compiler will automatically add it.
Example:
class A {
public A() {
System.out.println("Inside A's constructor.");
}
}
class B extends A {
public B() {
// super(); // THIS LINE WILL BE AUTOMATICALLY ADDED BY THE COMPILER.
System.out.println("Inside B's constructor.");
// super(); // THIS LINE WON'T COMPILE.
}
}
public class Main {
public static void main(String[] args) {
B b = new B();
}
}
No it should be first statement...
Even though if the default constructor is absent in the first line of sub class constructor, the compiler implicitly calls the default constructor of its super class

Using the extended class constructor

I was wondering if it was possible to do the following with a Class, that extends another class in Java, if so. How?:
public class HelloWorld {
public HelloWorld() {
A aClass = new A(22);
}
}
public class A extends B {
public A() {
System.out.println(number);
}
}
public class B {
public int number;
public B(int number) {
this.number = number;
}
}
Your A constructor needs to chain to a B constructor using super. At the moment the only constructor in B takes an int parameters, so you need to specify one, e.g.
public A(int x) {
super(x); // Calls the B(number) constructor
System.out.println(number);
}
Note that I've added the x parameter into A, because of the way you're calling it in HelloWorld. You don't have to have the same parameters though. For example:
public A() {
super(10);
System.out.println(number); // Will print 10
}
Then call it with:
A a = new A();
Every subclass constructor either chains to another constructor within the same class (using this) or to a constructor in the superclass (using super or implicitly) as the first statement in the constructor body. If the chaining is implicit, it's always equivalent to specifying super();, i.e. invoking a parameterless superclass constructor.
See section 8.8.7 of the JLS for more details.

how does the call to overriden methods take place in case of dynamic dispatch

class a extends b {
void h() {
System.out.println("class a");
}
public static void main(String[]args) {
b x = new a();
c y = new b();
c z = new a();
x.h(); //output class a
y.h(); //output class b
z.h(); //output class a
}
}
class b extends c {
void h() {
System.out.println("class b");
}
}
class c {
void h() {
System.out.println("class c");
}
}
Whats is the precedence in which it checks which method to call. I am confused as to how the JVM decides which method to call when I use dynamic dispatch. The output in this case is
class a
class b
class a
and when I remove the overridden method from class a the output is
class b
class b
class b
The class used depends on the instantiated type. So if you have an instance of class a (via new a()), then whether the declared variable is of type a, b, or c does not matter for the purpose of which definition of h() is invoked (it will always invoke a.h()).
However, where the declared type does matter is in when choosing an overloaded method. If you have a subclass that overloads an overridden method, then when invoking from a variable declared as the parent class, you will never use the overloaded method. If using a variable declared as being of the subclass, then it will use the overloaded method as appropriate.

Categories