Can you please tell me the problem in following code?
class boxdemo1 {
public static void main(String args[]) {
boxweight weightbox = new boxweight(2, 3, 5, 4);
System.out.println(weightbox.volume());
}
}
class boxinfo {
int l, b, h;
/*
* boxinfo() { l=b=h=-1; }
*/
boxinfo(int a, int b, int c) {
l = a;
this.b = b;
h = c;
}
int volume() {
return l * b * h;
}
}
class boxweight extends boxinfo {
int w;
boxweight(int a, int b, int c, int w) {
l = a;
this.b = b;
h = c;
this.w = w;
}
}
When I compile it,it shows following error:
"constructor boxinfo in class boxinfo cannot be applied to given types;
required:int,int,int; found:no arguments; actual and formal argument lists differ in length."
But when I compile it including the code which is commented(i.e. boxinfo() constructor), it gets compiled. Why is it necessary to include default constructor?
As this is necessary to build the super class part of the instance to get something working, the call of a super constructor is necessary.
If there is no statement calling super() in first statement of a constructor (or this() that would end up with a super()), the compiler will add a call to the default constructor (super();).
Since you don't have a constructor with no parameter, this can't compile as there is no constructor that match this statement.
In the same way, if a class don't define any constructor, a default constructor is implemented like
public MyClass(){ super(); }
Giving the same kind of problem if the superclass of MyClass only provide a constructor with parameters like said in the JLS
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.
To correct your problem, simply call the correct super constructor or define a constructor with no parameter (not called a default constructor anymore, only the one defined by the compiler is the default one ;) )
Reason for the error-
Child class constructor calls the constructor of the parent which
takes four parameters.
There is no constructor in the boxinfo class which takes four
parameters.
Furthermore,
Java compiler automatically insert super() constructor to the child class. Meaning of this super constructor is Go and execdute a constructor in the parent class which takes no parameters.
According to your program:
boxinfo(int a, int b, int c) {
l = a;
this.b = b;
h = c;
}
When you run your program compiler remove the default constructor because constructor in parent class takes three parameters.
If you do not add constructor for your boxweight class Java compiler automatically insert default constructor. Since you have added four parameters compiler will check for four parameter constructor . As I said before when you extends another class(boxinfo) in the constructor also Java compiler automatically insert the super() in the first line of constructor.
It's look like this:
class boxweight extends boxinfo{
boxweight (int a, int b, int c, int w){
super();
//.....
}
}
We can add super() to child class's constructor in a way that it matches an existing constructor in the parent class.
Solution for your qustion,
Add super() in constructor(first line) of child class and add values to match the parent class constructor.
Like this:
boxweight(int a, int b, int c, int w) {
super(a, b, c);
this.w = w;
}
Now you dont need these assign l = a;, this.b = b;, and h = c; because through the constructor you send it to the parent class.
Note: when you add super() must be the first line in child class constructor.
By setting your boxinfo(int a, int b, int c) constructor, the default no-parameters constructor set by java for boxinfo gets deleted. Then, when you call the boxweight(int a,int b,int c,int w) constructor, since the boxweight class inherits from boxinfo, you're implicitly calling the default constructor from boxinfo which just got overrided.
To avoid this, either create yourself a no-argument constructor in boxinfo or call explicitly super(a, b, c) in boxweight
It's necessary this when you overload the default constructor, the default one doesn't exist anymore.
eg:
class boxweight extends boxinfo {
boxweight(int a, int b, int c, int w) {
...
}
}
is actually the same as :
class boxweight extends boxinfo {
boxweight(int a, int b, int c, int w) {
super();
...
}
}
but in boxinfo such constructor doesn't exist anymore this you create a custom constructor. You need to keep it in code to make it callable.
A subclass constructor must initialize it's super class members by calling at least one of the constructors of its super class.
This becomes mandatory if the superclass does not have a default constructor such as the one in your example.
In this case, Your boxweight constructor must initliaze the other members that boxinfo declares. So you must invoke super(...) to initialize boxinfo.
so, your boxweight constructor would become:
boxweight(int a, int b, int c, int w) {
super(a,b,c); // put this call here and remove other lines.
this.w = w; // this is sufficient
}
PS: I recommend that you follow naming conventions to name your classes, methods and other Java artifacts.
http://www.oracle.com/technetwork/java/codeconventions-135099.html
When you extend a class using inheritance and create object of subclass the constructor of subclass will call its parent class constructor.In your case you are using below constructor it will call default constructor.In your class you have not specify the default constructor.In that case you can use super to call the declared constructor in parent class.
boxweight(int a, int b, int c, int w) {
super(a, b, c); //or declared default constructor
l = a;
this.b = b;
h = c;
this.w = w;
}
Related
Question:
I have the following:
interface A
{
int MethodA(int x, int y);
}
and
interface B extends A
{
//This is meant to overload MethodA
int MethodA(int x, int y, int z);
}
The problem comes when I try to implement interface B, and run the method in main.
class Foo implements B
{
//For interface B
public int MethodA(int x, int y, int z)
{
//Actual implementation
}
//For interface A
public int MethodA(int x, int y)
{
//Actual implementation
}
}
public static void main(String[] s)
{
Foo foo = new Foo();
//Problem occurs here
foo.MethodA(1, 2, 3);
}
Eclipse will complain and say that "The method MethodA(int, int, int) in the type A is not applicable for the arguments (int, int)."
But why? I've already implemented interface B. Shouldn't MethodA(int, int, int) have overload MethodA(int, int), making MethodA able to accept three integers as well?
The above looks a little confused.
You need to specify your return types, specify names for each argument (even in the interface) and declare the implemented methods as public eg.
public int MethodA(int a, int b, int c)
{
//Actual implementation e.g.
return 0;
}
Your static main() method has to reside within a class (e.g. the Foo class above), and finally call the method with real arguments.
Once you've done that, then all should be good. You can certainly provide overloading as in the above. You just need to resolve the more basic issues first. I would get a very basic single method going, and then enhance from there in order to get something working.
I am getting two errors in this code
Constructor call must be the first statement in a constructor.
Implicit super constructor Parent() is undefined. Must explicitly invoke another constructor.
So please help me to resolve these issues.
class Parent
{
public Parent(int x, int y,int z)
{
System.out.println("Created Parent");
}
}
public class Child extends Parent
{
Child(int x)// error 2
{
}
Child(int x, int y)// error 2
{
}
Child(int x, int y, int z)
{
this(x);
super(x,y,z);// error 2
System.out.println("Creating child");
this(x,y);// error 1
}
public static void main(String [] args)
{
Child c=new Child(1,2,3);
}
}
There are four things you need to understand:
If you don't specify any explicit constructor call, the compiler inserts a call to super() for you.
There must be exactly one constructor call for any constructor- either explicit or the implicit super() call. (You've got three in your Child(int, int, int) constructor.
An explicit constructor call must be the very first statement in the constructor body.
You can only call a constructor which actually exists - so a call to super() from Child is looking for a parameterless constructor in Parent, which doesn't exist.
One frequent pattern is to have a "master" constructor which other constructors in the same class chain to, and then that one chains to the superclass. For example:
Child(int x)
{
this(x, 0); // Chains to the Child(int, int) constructor, defaulting y to 0
}
Child(int x, int y)
{
// Chains to the Child(int, int, int) constructor, defaulting z to 0
this(x, y, 0);
}
Child(int x, int y, int z)
{
super(x, y, z);
System.out.println("Creating child");
}
The first thing a constructor has to do is to invoke the parent class constructor.
The implicit default is super() (without any arguments), but that does not work in your case, because the parent class Parent does not have a no-arguments constructor, it only has one with three int arguments, so you need to invoke that one.
And you need to do that in the first line of the constructor.
Instead of calling the super constructor, you can also call another constructor (another this()) on the same class. The super constructor is assumed to be called by that other constructor (otherwise it would not compile).
But you have to call this() also in the first line of the constructor.
And after you have called this() or super(), you cannot call it a second time.
Child(int x)// error 2
{
}
Does not compile, because there is no super() to match the implicit call.
Child(int x, int y)// error 2
{
}
Same problem.
Child(int x, int y, int z)
{
this(x);
super(x,y,z);// error 2
System.out.println("Creating child");
this(x,y);// error 1
}
You cannot call super() or this() except on the very first line.
Answer is in the question. You have to call parent class constructor before any other statement in child class constructor.
public class Child extends Parent
{
Child(int x)// error 2
{
super(0,0,0);
}
Child(int x, int y)// error 2
{
super(x,y,0);
}
Child(int x, int y, int z)
{
super(x,y,z);
System.out.println("Creating child");
}
call to base constructor is not mandatory if base has a default constructor, this is not the case in your code.
The theory behind this is, in any inheritance hierarchy, when you instantiate any derived object, first the top most base will be initialized, then next of it and so on upto the actual derivation point.
When you create a new instance of Child class first thing to do is to call super(x,y,z), otherwise it cannot works. In fact a Child "is a" Parent, so to have an instance of Child you must be able to instantiate superclass. So Child(int x){ super(x,0,0);} is a possible constructor for Child class, but Child(int x){} isn't because Parent class does not have the default constructor. Remember that when you explicitly add a constructor to your class the default one is no more available. Finally, the constructor you wrote: Child(int x, int y, int z){this(x); super(x,y,z); this(x,y);} cannot works, because in a constructor you call three different constructors, but how many instances would you like to have? You can create just one instance per contructor.
When you instantiate a child object, the order of calling constructor is
Parent ---> followed by Child.
So The first line in your constructor has to be a call to the parent constructor. ( If you don't provide yourself, the compiler will insert one for you.) OR a call to own overloaded constructor (which will call super as explained above).
Your error 1 is caused because you have called the constructor only after certain executable statement are executed.
For error 2...
First thing you must know is that , a compiler will provide a default no-arg constructor for every class IF YOU DON'T PROVIDE ANY TYPE OF CONSTRUCTOR AT ALL.
But the moment , you provide a constructor , compiler no longer gives you a default constructor. you need to write one by yourself.
Second thing, by default , if you don't have a super() in your child class, the compiler will put by default a no-arg call to super().
This is where your problem lies.
You have given a parametrized constructor for your parent , and so compiler didn't provide with a no-arg default constructor. And now when in your child class you dont put your own super(xy,z) call, it will put a default no-arg super() call. BUT THE PARENT DOENST HAVE A NO AGR CONSTRUCTOR....hence the error.
You can do 2 things to solve this, either write a
Parent() {}
constructor
or put an explicit call to super -->
super (0,0,0)
in each child constructor
class A
class A {
int a;
int c;
A (int a, int c) {
this.a = a;
this.c = c;
}
}
class B
class B extends A{
public static void main (String [] args) {
A obj = new A (5, 6);
}
}
When I compile the code It shows me this error
B.java:1: error: constructor A in class A cannot be applied to given types;
class B extends A{
^
required: int,int
found: no arguments
reason: actual and formal argument lists differ in length
1 error
When this error appears exactly? And when inheritance the class Is the constructor must be the same type of super class?
A specifies a constructor taking two arguments, B only specifies a parameterless (the default one).
If you really want to let B inherit from A, you'll need to create a constructor as well, either one with two arguments as well, or one just calling the constructor of A with default values:
// variant A
class B extends A {
B (int a, int c) {
super(a, c);
}
}
// variant B
class B extends A {
B () {
super(0, 0); // replace 0 with an appropiate default value for each parameter
}
}
However, from your code, B wouldn't need to inherit from A, if you only want to instantiate A in the main. Just remove the inheritance in that case.
Add a constructor to class B.
The compiler realizes that you cannot instantiate class B!
This is my simple java code. When I compile/run the program, Eclipse IDE shows a syntax error. The syntax error does not make any sense to me
class A {
int x;
int z;
int s;
A(int a,int b) {
x=a;
z=b;
}
void display() {
System.out.println("x+y :"+(x+z));
}
}
class B extends A
{
B(int a, int b, int c) {
x=a;
z=b;
s=c;
}
void display() {
System.out.print("In B class...");
System.out.println("x+y+s :"+(x+z+s));
}
}
public class Simple {
public static void main(String[] args) {
A ob=new A(10, 20);
B ob2=new B(20, 30, 40);
ob.display();
ob2.display();
}
}
In your class A, you've provided a constructor that accepts two parameters and you've not defined a parameter-less constructor for A. As such, when you try to instantiate B, which extends A, it fails since it cannot call A()
There're two ways to resolve this:
Provide a parameter-less constructor for A
Something like:
class A{
int x;
int z;
int s;
public A(){
}
public A(int a,int b){
x=a;
z=b;
}
void display(){
System.out.println("x+y :"+(x+z));
}
}
Call super(a, b) as the first statement in the constructor of B.
For example:
class B extends A
{
B(int a, int b, int c){
super(a,b);
x=a;
z=b;
s=c;
}
void display(){
System.out.print("In B class...");
System.out.println("x+y+s :"+(x+z+s));
}
}
If you're new to Java, you might want to read about Inheritance and Creating Objects in Java
There are a few things that needs to be considered here: -
When you declare a class without any constructor, the compiler does that for you by inserting a default constructor, that is an empty zero-arg constructor..
If you have explicitly declared your one-arg constructor(or any other constructor), compiler doesn't add any default constructor.
Every time you make an instance of a class, constructors are invoked from top-down in inheritance hierarchy. So, if you are not using inheritance, then instantiating a class first invokes the Object class's constructor (which is the top-level class of any inheritance or non-inheritance hierarchy)
We invoke super class constructor, using super(), but if we haven't done it explicitly, compiler will add this for us.. If you are adding it by yourself, make sure it should be the first statement of a constructor.. You can pass argument to super, to call super class's non-zero arg constructor, but compiler adds only zero-arg super().
Now, Having said all that, lets move to your code..
In your class A, you have declared a three-arg constructor, so compiler won't add any.. So, precisely you don't have any zero-arg constructor there.
Now, your class B extends A and hence instantiating that class will invoke super-class constructor which is A here.
Now, since you have not added any super() call in your B class, compiler will add there automatically.
But, what compiler adds is: super(), which will call A's zero-arg constructor, which we saw that you don't have.
So, how you can solve that??
Either add a default constructor to your class A: -
class A {
public A() {
}
}
Or add an explicit super() call as your first statement in B's constructor to invoke your 3-arg A's constructor : -
class B extends A {
public B(int a, int b) {
super(a, b, 19);
/* More Code */
}
}
Similar, to super(), you can also use this() in your constructor, to invoke the same class's constructor. Same rule applies to this().. It should be the first statement in your constructor..
So, we can see that we can either have super() or this() in our constructor.
I hope this much information will solve at least your current problem.
The (lack of) formatting makes it hard to read. The start of the definition of class A is outside the code block.
It looks like you didn't define the int field s in class B. Should be:
class B extends A
{
int s;
...
}
EDIT: looks like you reformatted and changed it while I was posting my answer...
Where is the class a definition " class A"? Where are the data fields definitions (x, z, s for class B and x,z for class A)? Please edit your post
After the post was edited, I've tried to compile it and the error should be as follows:
Simple.java:17: cannot find symbol
symbol : constructor A()
location: class A
B(int a, int b, int c){
^
1 error
This means that you should call some constructor of class A when you create a class B because B extends A. You don't have default constructors because you created your own.
Rewrite the constructor of B like this and you'll be fine:
B(int a, int b, int c){
super(a,b);
s=c;
}
Good luck!
You have explictly declare constructor of Class A, so the class B should explict call his parent's - class A - constructor.
Add below code into the class B's constructor:
super(a, b);
Then your constructor of class B will be looks like:
B(int a, int b, int c) {
super(a, b);
x = a;
z = b;
s = c;
}
PS, pls take care of the formatting of the code that your pasted. It's hard to read.
your super class has an two args constructor, when you extend class A in class B's constructor you have call your superclasses's two args constructor.
change your sub class constructor code to this.
B(int a, int b, intc) {
super(a,b); //this has to be in the first line inside the constructor.
//do your things
}
this link explains it
If you want to set the values to the properties that are defined in the super class, call super() method in the sub class constructor.
So, Your sub class constructor should look like as follows
public B(int a, int b, int c){
// The following statement will automatically sets the values to the base class properties (which are already derived into derived class).
super(a, b);
// No Need of setting the values to the super class properties... The above statement will automatically sets the values...
s=c;
}
First off, posting the error given by eclipse would be helpful.
But in any case, your syntax errors are stemming from the fact that you aren't defining the datatype of your variables, such as x, z, s, etc.
For example,
int x = a;
int z = b;
etc.
say i have a parent class and a child class and call the constructor of the child class. Would I have to have both the child constructors arguments plus the parent constructors arguments and use super( ) to initialize the parent. And does this mean if i overloaded the parents constructor I would need to have constructors matching each of the child's constructors... So if I had two parent constructors
parent(int a);
parent(int a,int b);
and two child constructors
child(int c);
child(int c,int d);
I would have to have child(int a) actually be in the form of two constructors
child(int a, int c)
{
super(a)
c = this.c;
}
and
child ( int a, int b, int c)
{
super(a,b)
c = this.c;
}
and have child(int c, int d) actually have two constructors
child(int a, int c, int d)
{
super(a);
c = this.c;
d = this.d;
}
or could i pass
child(int a,int b, int c, int d)
{
super(a,b);
c = this.c;
d = this.d;
}
}
The parent constructor is always invoked. If not explicit it will be implicit. Its up to you to define the parameters to invoke the parent constructor.
If parent doesn't present a default constructor (one that doesn't requires any parameter) you need to invoke it explicitly from you sub classes.
Nothing forbids you to have a general constructor as you commented in case of child(int a, int b, int c, int d) and invoke the parent class's constructor lie super(a,b).
If you have some constructors on the parent class doesn't mean necessarily that you need to "propagate" them on the sub classes.
There is a good text regarding the constructor chaining here.
Its up to you that how many overloaded version of construtor you want to write but keep in mind that every construtor of child class calls its super() with no arg implicitly if in parent no arg construtor is not there it will give you compile time error .but if yor are making in call explicitly you can call any supar construtor .