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!
Related
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;
}
I'm learning Java and I'm doing this exercise and I have to say what the main method prints. Its goal is to better understand Java inheritance.
interface X extends Remote{
A m(B bb) throws RemoteException;
}
class A implements Serializable{
int a;
A m(A aa){
aa.a = 3;
System.out.println("A.m");
return aa;
}
}
class B extends A{
int b;
A m(B bb){
bb.b = 7;
System.out.println("B.m");
return bb;
}
}
class C extends A implements X{
public B m(B bb){
if(bb.b == 7) bb.b = 9; else bb.b = 1;
System.out.println("C.m");
return bb;
}
}
Now I have a main method in which I call:
X x = new C();
B b = new B();
(x.m(b)).m(b); // prints C.m() A.m()
The third line of my main method, prints "C.m() A.m()" but I don't understand why it prints A.m(). The x.m(b) returns an object that has both static and dynamic type == B; on this object it is invoked m(b) method; so why it is not called the m() method of B class?
I've seen that the m() mehtod in B class is not an overriding of the m() method in A class because they have different explicit parameter.
thanks in advance
b in an instance of B, which extends A. As such, B has 2 m methods.
To know which is called, what is important is the type of the object on which the method is called.
(x.m(b))
is the result of the call to the m method from the X interface, because the declaring type of x is X.
Therefore (x.m(b)) is an object of type A (even though the actual implementation is a B).
This being a type A, the m method from the A class is called.
If you change the names of the methods, it will become clearer that the m methods from A and B are really different objects.
Your mistake is assuming that
The x.m(b) returns an object that has both static and dynamic type == B;
Which is wrong, because x is declared of type X, making the result of x.m a type A.
In the following code, I don't understand why when a1.k() is called, this.x in class C returns 100 instead of 1. My understanding is that this refers to the current object, but the static type of the current variable a1 is A. So shouldn't this.x returns 1, which is the variable for A type?
I mean a1.x should return 1, right? Many thanks!
class A {
public int x = 1;
public String k() { return "A" + this.x; }
}
class B extends A {
public int x = 10;
...
}
class C extends B {
public int x = 100;
public String k() { return "C" + this.x; }
}
class TestABC {
public static void main(String[] args) {
A a1 = new C();
C c1 = new C();
System.out.println(a1.k());
}
}
When you call a1.k() you dynamically dispatch to the k method that is defined by the actual object whose reference is in a1. In this case, it is a C not an A or a B, and hence the k method is the override defined in C.
The static type (of a1 for example) is used for static resolution; e.g. resolving static methods, overload signatures, and fields. But for instance method invocation, the ultimate selection of the method to be invoked is dynamic.
I know the k() in class C should be called, instead of the k() in class A. But why this.x returns 100? I thought the instance variable is bounded to the static type.
Well it is. But it is the static type that determines which x is used by this.x in the k() call is the static type of this in the C.k method body!
This feature is called Dynamic Polymorphism. The methods being called is not dependent of type of its declaration but by the type being assigned to it (definition).
For this the classes must inherit and also override the methods in the parent class.
Here C,B extends A and overrides the method k;
if you try to call some C specific methods or variable it will throw error. (Since A doesn't know about that)
A is holding reference to C (pointing to C)
a1.k is actually C constructed Object and its new C().k() where x is 100 in C.
class Base{
int x=10;
public int getx(){return x;}
}
class Sub extends Base{
int x=100;
public int getx(){return x;}
}
class Test
{
public static void main (String[] args)
{
Base b = new Base();
Sub s = new Sub();
System.out.println("sub: getx:"+s.getx()+" .x:"+s.x+" Class: "+s.getClass().getName());
System.out.println("base: getx:"+b.getx()+" .x:"+b.x+" Class: "+b.getClass().getName());
Base btoS = new Sub();
System.out.println("btos: getx"+btoS.getx()+" .x:"+btoS.x+" Class: "+btoS.getClass().getName());
}
}
Results in
sub: getx:100 .x:100 Class: Sub
base: getx:10 .x:10 Class: Base
btos: getx100 .x:10 Class: Sub
Since you declare a1 as new C(), a1 will be seen as an object instance of class C, which overrides the fields of its parent class B and A. So why you would do things like A a1 = new C(); (or you might see a lot of such implementation), there is a recommendation saying "programming to interface rather than the actual implementation.", and I think this explains better.
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.
I have an abstract class A with 1 method called public int get(int x, int y).
Classes B,C,D have 1 method which are all same and they extends to the abstract class A.
In a class Car, the Car constructor receives String argument type that should be used to decide which one of B, C, D have to be used in the class.
Apparently, I am using if...else conditional statements based on the type to do it.
So the codes look like
if(type.equals("B")){
A = new B();
} else if(type.equals("C")){
A = new C();
} //and so on..
Is there any elegant way that I can use string argument just as it is to decide which one of 3 classes to use?
You could use the interface / abstract class as an argument in the constructor instead of using a String.
public Car(A a) { this.a = a; }
And then elsewhere:
B b = new B();
new Car(b);
This is called dependency injection.
You can use Class.forName(String) to get a Class object and then instantiate it using newInstance()