inheritance in java (compile error) - java

this is my program:
class A{
A(int a){
}
class B extends A{
B(){
}
}
}
when I compile I have an error:
C:\Users\Public\Documents\AB.java:6: error: constructor A in class A cannot be applied to given types;
B(){
^
required: int
found: no arguments
reason: actual and formal argument lists differ in length
and it fixed by this change in my code:
class A{
A(int a){
}
A(){
}
class B extends A{
B(){
}
}
}
but I don't understand why?
thanks for any help.

Since your A class declares a constructor
A(int a){
}
then any code that wants to instantiate A needs to do so with that constructor. Something like
A a = new A(42);
You also declare a child class, B. Since B is an A, in addition to its constructor, it must call the parent class' constructor. This is done implicitly by the compiler. Say you had
class A{
A(){
}
class B extends A{
B(){
// super(); injected by compiler
}
}
If you don't have a no-arg constructor, then the compiler doesn't know which constructor call to inject. You need to explicitly declare the super(...) call.
class A{
A(int a){
}
class B extends A{
B(){
super(42);
}
}
Think of it this way: you can't construct an A without the constructor call. When you construct a B, you are, through inheritance, also constructing an A, so you need that same constructor call.

You need to have a default constructor (no-argument) in A. The first implicit call of a constructor of any class is super(). But there is not super() method in the superclass. You can either explicitly call super(5) or some value, or create a default constructor in A:
A() {}

When instance of class B is created a default call to super() constructor with no parameters is made. Each class has a default constructor with no parameters, unless a different constructor is provided explicitly.
As you have explicitly provided class A with a constructor that takes one parameter, it no longer has default constructor with no params, so you need to define it.

Whenever we extend a class, by default it calls super() (it has no params). In your case , it dint get the matching A() , hence it resulted in compiler error.
Whenever u write this, what happens internally is :
class A
{
A(int a)
{
}
class B extends A
{
B()
{
//Internally compiler calls super()
super();//In your case, it dint get the matching constructor
}
}
}

Related

Constructor in Child Class

Why is the constructor in B required?
IntelliJ suggests to remove =null as it is redundant presumably because it is initialized through the given constructor in A.
However, this removal (which is presumably also performed by the compiler) then (presumably) requires the constructor in B.
Any other explanation?
public abstract class A {
private Object foo = null;
public A(Object foo){this.foo=foo;}
}
public class B extends A {
public B(Object foo){super(foo);}
}
Java does not have "constructor inheritance". The only way to initialize A is to pass the foo parameter to its constructor, and the only way to do this is to create a constructor for B that does so.
Note, however, that they don't have to have the same signature (like you have in the question) - B's constructor only needs to pass some parameter to A. E.g.:
public class B extends A {
public B() {
super("Arbitrary default passed to A");
}
public B(Object passedToA, Obejct notPassedToA) {
super(passedToA);
System.out.println("This argument was not passed to A():" + notPassedToA);
}
}
Why is the constructor in B required?
If the class B extends A, the class B must be instantiated in all possible ways as the class A can be and the class B can have additional ways to be instantiated. It means that class B is forced to have a constructor.
The only exemption can be in case of a no-arg constructor because the compiler makes it up with a default constructor i.e. if you put a no-arg constructor in the class A the child classes are not forced to have this.

How can I call parameterized constructor of default type from a parameterized constructor of type public which is in another class?

Class B is inherited from Class A.
Class A have parameterized constructor of access type default which is not accessible (default:it can be accessible from different class but from same package.)
How can i access my constructor of default visibility from another class?
Here I want to access A(int id1,String s) from public B(int id1,int h1) ,by calling super(999,"super"); it bombards error that create a new constructor
Edit:Class A and B are in same project
public class A {
A(int id1,String s)
{
System.out.println("in parameterized constructor of class A");
}
public class B extends A{
public B(int id1,int h1)
{
super(999,"super");//The constructor A(int, String) is undefined
System.out.println("in parameterized constructor of class B");
}
If B extends A, A only has a default visibility constructor, and B is not in the same package as A, then there is absolutely 100% no way to make B compile at all. None of A's constructors will be visible to B and that is absolutely necessary.
(You can use this deliberately when you need to have a class that needs subclasses but you don't want it to be subclassable outside the package.)

What's wrong with the following java code?

I am getting some argument errors while compilation. don't know what wrong this.
I was expecting the output would be bj. since Class a doesn't have default constructor so at compilation time default constructor would be created by JVM. and the remaining output would be bj. Am I missing something?
class a
{
a(String b)
{
System.out.println("this is a");
}
}
class b extends a
{
b()
{
System.out.println("b");
}
}
class c extends b
{
c(String j)
{
System.out.println(j);
}
public static void main(String...k)
{
new c("J");
}
}
The error is shown below:
javac construct.java
construct.java:12: error: constructor a in class a cannot be applied to given ty
pes;
{
^
required: String
found: no arguments
reason: actual and formal argument lists differ in length
1 error
since Class a doesn't have default constructor so at compilation time default constructor would be created by JVM
The default constructor is created only if you don't define a custom constructor.
Your IDE should have shown you the following message on b() declaration:
There is no default constructor available in 'package.a'
When you tried to instantiate b, it did an implicit call to super() but found only a(String b) instead of a(). As the error message says, a(String b) expected a String but got no arguments.
The solution is either to create the parameterless a() constructor or call the a(String b) constructor in class b constructor.
class b extends a
{
b()
{
super(""); // call to class a constructor passing some string as argument
System.out.println("b");
}
}
By convention you should name Java Classes in upper case letters
When new C("J"); is executed, it calls the constructor of class C. But as class C is extending class B, JVM will add
C(String j)
{
super(); //added by JVM - calls the constructor of super class
System.out.println("j");
}
So the constructor of class b is invoked and as it is also extending class A.
B()
{
super(); //added by JVM
System.out.println("b");
}
Now problem arises. As JVM will add default constructor in its implicit call. But there is no constructor defined with no-arguments. That's why you are getting an error. You can add super(""); in constructor B to resolve the error or create a constructor with no parameters.

Confused with Constructors and Subclasses

I'm having trouble understanding the concept of using constructors with subclasses.
Here is the parent class:
public class A
{
public A()
{
System.out.println("The default constructor of A is invoked");
}
}
The child class:
public class B extends A
{
public B(String s)
{
System.out.println(s);
}
}
And my main method:
public class C
{
public static void main (String[] args)
{
B b = new B("The constructor of B is invoked");
}
}
When I run C, the output I get is
The default constructor of A is invoked
The constructor of B is invoked
What I don't understand is why the message from class A is getting output. Because you pass in a string argument to the constructor of the B class, shouldn't it just print out s? In other words, shouldn't the output simply be:
The constructor of B is invoked
Thanks in advance, I really appreciate any help you guys can give.
From the docs
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.
So even though you've not explicitly called the super class constructor, the compiler inserts a statement called super() in the constructor of class B.
This is how the class B constructor would look post compilation.
public B(String s){
super(); // this is inserted by the compiler, if you hadn't done it yourself.
System.out.println(s);
}
After compilation class B -
public class B extends A{
public B(String s){
super();
System.out.println(s);
}
}
And why! logical answer is child can not be existed without parent, so parent is initialized fast then child.
Technically - if you do not explicitly invoke super class constructor compiler will do it for you. what exactly happened in your case.
A good experiment would be if you invoke the super class contructor explicitly which help you understand this more closely-
public class B extends A{
public B(String s){
System.out.println(s);
super(); // invoking super later
}
}
you get an compilation error -
error: call to super must be first statement in constructor
So In case you are explicitly invoking the super class constructor, then you have to invoke at the start of constructor which should be first statement.
The reason it does this is that B needs to have all the fields in A if B is indeed a subclass of A. Therefore, when you call the constructor
B b = new B("The constructor of B is invoked");
It calls the default constructor of A to initialize A's fields, thus B is actually logically doing
public class B extends A
{
public B(String s)
{
super();
System.out.println(s);
}
}
where super just calls A's default constructor. If the compiler did not do this, you would have uninitialized fields in B since it inherits from A!

Default constructor not getting called

Why default constructor(same class) is not getting called while calling the default constructor but the default constructor of parent class is getting called - Why?
class A{
A(){
System.out.println("A()");
}
}
class B extends A{
B(){
System.out.println("B()");
}
}
class C extends B{
C(){
System.out.println("C()");
}
C(int i){
System.out.println("<------>"+i);
}
}
public class sample {
public static void main(String[] args) {
C c = new C(8);
}
}
Output:
A()
B()
<------>8
This is how the language works: only one constructor is called per class, unless you specifically invoke one constructor from another (like so: How do I call one constructor from another in Java?).
It's Java's rule. If you want your behaviour you must use this() as first instruction in C(int).
as said before it's standard behavior of java if you want some code to be always called on construction of an object you can use an initializer
class A{
{
System.out.println("A()");
}
A(){
}
}
Based on your class declaration for class 'C', you are overloading the constructors and thus when you create a new 'C' object and pass in an integer with the following code:
C c = new C(8);
You are calling the constructor
C(int i){
System.out.println("<------>"+i);
}
instead of the constructor
C(){
System.out.println("C()");
}
therefore it doesn't print out "C()". Overloading constructors/functions depends on the type and number of parameters being passed in. On top of that, only 1 constructor gets called for each object being created.

Categories