I am learning java. The book I'm reading has a question which asks what is wrong with the following code? I have typed the code in NetBeans and I can see the error but why is this error caused and how is it resolved?
The error is highlighted over the code public A(int t) and it says
Constructor B in class B cannot be applied to given types, require int, found no arguments, reason actual and formal arguments lists differ in length.
Here is the code:
public class Test {
public static void main(String[] args) {
B b = new B(5);
}
}
class A extends B {
public A(int t) {
System.out.println("A's constructor is invoked");
}
}
class B {
public B(int k) {
System.out.println("B's constructor is invoked");
}
}
when your super class has an args constructor and doesn't have a no-args constructor you have to explicitly invoke it using a super(args) call from sub-class constructor
class A extends B {
public A(int t) {
super(t);
System.out.println("A's constructor is invoked");
}
}
Class B has defined constructor, so it does not have public implicit default constructor (with no arguments). All subclass constructors have to explicitly call superclass constructors, via super(t), if zero argument superclass constructor is not available.
The class B has only one constructor which takes an int argument. On the other hand, the constructor you have in class A (implicitly) tries to call a constructor in A's super class (namely B) that takes no arguments. This is the cause of the error. There are at least two ways to fix the problem:
Create a no-arg constructor in class B.
Explicitly call the constructor in class B which takes an int as a parameter. You can do this using the super keyword.
You need to call the constructor of the super class as the first statement in A(int):
public A(int t) {
super(t);
System.out.println("A's constructor is invoked");
}
Related
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.
I was just experimenting with abstract classes and bumped into an error.
I have one class as:
public abstract class C {
String aname;
int aid;
public C(String s, int n) {
aname = s;
aid = n;
}
public static void main(String[] args) {
System.out.println("Hello");
}
}
Now, another class extends it as follows:
public class D extends C {
public static void main(String[] args) {
}
}
However, it gives the following error:
error: constructor C in class C cannot be applied to given types;
public class D extends C {
^
required: String,int
found: no arguments
reason: actual and formal argument lists differ in length
Since class D does not define any constructor, the compiler automatically creates a default no-argument constructor for it. However, this constructor implicitly calls the no-argument constructor of the base class C, which is not defined -- a no-argument constructor exists if you explicitly define one or if you don't define any constructor. To solve it, you can either define a no-arg constructor for C:
public C() {
}
or you can define a constructor in D that has the same parameters as that of the parent class:
public D(String s, int n) {
super(s, n);
}
This has nothing to do with abstract classes and methods, and everything to do with the fact that you don't have a constructor declared in D.
You have only one constructor in C, and it takes 2 arguments. You did not declare a constructor in D, so Java implicitly inserts a no-arg, default constructor. It calls the superclass's default (no-arg) constructor, but that doesn't exist in C.
You must explicitly create a D constructor that calls C's 2-arg constructor or supply a no-arg constructor in C.
You have a parameterized constructor only in the abstract class. Try to have explicit default constructor or override the one in child.
public class A{
public A(String x){
System.out.println("A constructor Called "+x);
}
public static void main(String []args){
System.out.println("Hello World");
A a= new B("b");
}
}
class B extends A{
public B(String x){
System.out.println("B constructor Called "+x);
}
}
What is the problem in this very simple program, I am unable to locate it.
Getting the following error on compile:
A.java:13: error: constructor A in class A cannot be applied to given types;
public B(String x){
^
required: String
found: no arguments
reason: actual and formal argument lists differ in length
Since class A does not have a default constructor, you need to tell class B how to construct its parent:
class B extends A{
public B(String x){
super(x); // this constructs the parent class
System.out.println("B constructor Called "+x);
}
}
The error is telling you that the constructor you must call requires a string:
required: String
... however the one you are calling (which is the the default constructor because you are not calling super ) has no arguments:
found: no arguments
You need to invoke the super constructor:
public B(String x){
super(x);
System.out.println("B constructor Called "+x);
}
Usually, there's an implicit call to a default no-arg constructor, but A doesn't have one of those. Writing super(x); will call the public A(String x) ... constructor, which is the only one available in the A class.
Just to add more.
If you will write no-argumnet constructor in hte parent class it will not show an error. Because by default super() call happens inside constructor. So when it's calling the parent class constructors it's not getting the no-argumnet constructor in the parent class.
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.
I'm trying to understand why does this code compile:
public class A {
}
public class B extends A {
public B() {
}
}
while this code doesn't:
public class A {
public A(int n) {
}
}
public class B extends A {
public B() {
}
}
I mean, doesn't the class A have a blank constructor in both cases ? If so, why isn't it working?
Thanks in advance
When the superclass has only constructors with args, you need to explicitly make an call to your superclass's constructor from your subclass, like below.
public B() {
super(2);// passing an int value to your super class cons
}
doesn't the class A have a blank constructor in both cases?
No. If you declare a constructor then the compiler will not include a default constructor, thus your class A doesn't have a default no-args constructor in case 2, and you have to explicitly make a super call from your sub class constructor.