I am calling parametrized constructor of super class then also it is throwing compile time error such as no default constructor Why? Because as per the program i m not calling default constructor at all.
class Sup
{
public Sup(String s)
{
System.out.println("super");
}
}
class Sub extends Sup
{
public Sub()
{
System.out.println("sub class");
}
public static void main(String arg[])
{
Sup s2=new Sup("pavan");
}
}
You need to define the super classes default constructor, because unless otherwise specified the base classes constructor will try to call the super class, in your case the super class doesn't have a parameterless constructor so you'll get a compile error.
class Sup
{
public Sup(){}
public Sup(String s)
{
System.out.println("super");
}
}
class Sub extends Sup
{
public Sub()
{
System.out.println("sub class");
}
public static void main(String arg[])
{
Sup s2=new Sup("pavan");
}
}
Or make a explicit call to the super classes constructor(s) using super() and in your case for the parametrized constructor super("some string")
class Sup
{
public Sup(String s)
{
System.out.println("super");
}
}
class Sub extends Sup
{
public Sub()
{
super("some string");
System.out.println("sub class");
}
public static void main(String arg[])
{
Sup s2=new Sup("pavan");
}
}
Your Sub() constructor is calling default constructor (which is done implicitly if you don't call super() explictly or call another constructor in the same class in first line of your constructor) in Sup class which you did not provide. You should add a call to Sup(String s) in Sub() constructor or add default no-param constructor in your Sup class.
Related
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.
Say I've made an abstract class called animal, and then I make a subclass called dogs which extends animal. The animal class has a constructor method written inside. If I decide to instantiate a "dog" object, will the animal classes's constructor automatically be called as well?
If someone could clarify, and further expand on this a bit, it'd be greatly appreciated!
Yes , The constructor of an abstract class can be called. why not? Use super() from subclass to call the super class argument constructor(s). If you dont use super(), then by default the no-arg constructor of super class will be called.
If you call
Dog dog = new Dog();
By default the super class default constructor[no-arg constructor] will be called.
If you call
Dog dog = new Dog("doggie1");
Unless you explicitly call super() inside the one argument constructor of Dog, the default super class constructor will not be called.
Try it..
Edit: If you don't call super() inside the one argument constructor of Dog, then also the default super class constructor will be called.
If you want to explicitly call the argument constructor , say one argument constructor of the super class, you have to explicitly make the call super("value");
Animal() {
System.out.println("Animal superconstructor");
}
Edit 02:
Sample program and output
(1)
public class SubClass extends SuperClass {
SubClass(String str) {
super(str);
}
SubClass() {
}
public static void main(String[] args) {
new SubClass("hello");
}
}
abstract class SuperClass {
SuperClass() {
System.out.println("I am SuperClass()");
}
SuperClass(String str) {
System.out.println("I am SuperClass(String str)");
}
}
//output: I am SuperClass(String str)
(2)
public class SubClass extends SuperClass {
SubClass(String str) {
}
SubClass() {
}
public static void main(String[] args) {
new SubClass("hello");
}
}
abstract class SuperClass {
SuperClass() {
System.out.println("I am SuperClass()");
}
SuperClass(String str) {
System.out.println("I am SuperClass(String str)");
}
}
//output: I am SuperClass()
(3)
public class SubClass extends SuperClass {
SubClass(String str) {
}
SubClass() {
}
public static void main(String[] args) {
new SubClass();
}
}
abstract class SuperClass {
SuperClass() {
System.out.println("I am SuperClass()");
}
SuperClass(String str) {
System.out.println("I am SuperClass(String str)");
}
}
// output: I am SuperClass()
If Animal has a no-arg constructor, then Animal's subclasses will call it automatically. Otherwise, the compiler will complain. In such a case, you have to call super() explicitly with the appropriate parameters for the Animal constructor you wish to use.
If I remember correctly, the abstract class's constructor (only the default constructor) is called by default only in the instance of the default constructor. To call the other constructors of the inherited class, a super() call needs to be made inside the constructors of the subclass.
I'm trying for the below scenario:
public class SuperClass {
public SuperClass(){
System.out.println("Super Constructor");
}
public SuperClass(int i){
this();
System.out.println("Parameterized Super Constructor");
}
}
public class SubClass extends SuperClass{
public SubClass(){
System.out.println("Sub Constructor");
}
public SubClass(int i){
super(i); /* Need to call **this()** here .. Is this possible? */
System.out.println("Parameterized Sub Constructor");
}
}
public class Inheritance {
public static void main(String[] args) {
SubClass sub=new SubClass(5);
}
}
How to call both default and parameterized constructors for this case ?
If you have functionality in the non-parameterized constructor that you need to call for both, then I'd recommend that you just move it out of there into a, for example, private void init() function that both constructors can call.
Simple answer, no you cannot call both this and super(i). Java only allow you to chain one other constructor in the beginning of a constructor.
You can do what DFreeman suggested or there is another trick in Java;
public class SuperClass {
public SuperClass(){
System.out.println("Super Constructor");
}
public SuperClass(int i){
this();
System.out.println("Parameterized Super Constructor");
}
}
public class SubClass extends SuperClass{
{
/*
* Default initialization block.
* During compile time, this block will get copy to each of the constructor.
*/
System.out.println("Sub Constructor");
}
public SubClass(int i){
super(i);
System.out.println("Parameterized Sub Constructor");
}
}
public class Inheritance {
public static void main(String[] args) {
SubClass sub=new SubClass(5);
}
}
So if you have some common initialization (like assigning default values), you can take advantage of the default initialization block.
However, if need to call different parameterized constructors in a constructor you are out of luck. You will either have to restructure your constructors or call some common private initialization method.
Please check the code
why constructor of abstract class calling first
abstract class car
{
car() //creating a constructor for abstact class
{
System.out.println("four");
}
abstract String getText();
}
adding subclass
public class abc extends car
{
String getText() //override the getText Method
{
return "Hello from JSP!";
}
static block
static
{
System.out.println("Hello");
}
//blank blok
{
System.out.println("two");
}
constructor for abc
abc()
{
super();
System.out.println("three");
}
//main method
public static void main(String []args)
{
abc a = new abc();
System.out.println("one");
}
}
thanks
Superclass constructor is always called first before the subclass constructor. There is no problem in that and it is the standard behavior. Also note that it is perfectly valid for an abstract class to have constructor.
Is it possible to call a super static method from child static method?
I mean, in a generic way, so far now I have the following:
public class BaseController extends Controller {
static void init() {
//init stuff
}
}
public class ChildController extends BaseController {
static void init() {
BaseController.loadState();
// more init stuff
}
}
and it works, but I'd like to do it in a generic way, something like calling super.loadState(), which doesn't seem to work...
In Java, static methods cannot be overidden. The reason is neatly explained here
So, it doesn't depend on the object that it is being referenced. But instead, it depends on the type of reference. Hence, static method is said to hide another static method and not override it.
For example (Cat is a subclass of Animal):
public class Animal {
public static void hide() {
System.out.format("The hide method in Animal.%n");
}
public void override() {
System.out.format("The override method in Animal.%n");
}
}
public class Cat extends Animal {
public static void hide() {
System.out.format("The hide method in Cat.%n");
}
public void override() {
System.out.format("The override method in Cat.%n");
}
}
Main class:
public static void main(String[] args) {
Cat myCat = new Cat();
System.out.println("Create a Cat instance ...");
myCat.hide();
Cat.hide();
myCat.override();
Animal myAnimal = myCat;
System.out.println("\nCast the Cat instance to Animal...");
Animal.hide();
myAnimal.override();
Animal myAnimal1 = new Animal();
System.out.println("\nCreate an Animal instance....");
Animal.hide();
myAnimal.override();
}
Now, the output would be as given below
Create a Cat instance ...
The hide method in Cat.
The hide method in Cat.
The override method in Cat.
Cast the Cat instance to Animal...
The hide method in Animal.
The override method in Cat.
Create an Animal instance....
The hide method in Animal.
The override method in Animal.
For class methods, the runtime system invokes the method defined in the compile-time type of the reference on which the method is called.
In other words, call to static methods are mapped at the compile time and depends on the declared type of the reference (Parent in this case) and not the instance the reference points at runtime. In the example, the compile-time type of myAnimal is Animal. Thus, the runtime system invokes the hide method defined in Animal.
There is static inheritance in Java. Adapting the example from Nikita:
class A {
static void test() {
System.out.print("A");
}
}
class B extends A {
}
class C extends B {
static void test() {
System.out.print("C");
B.test();
}
public static void main(String[] ignored) {
C.test();
}
}
This now compiles, and invoking C prints "CA", of course. Now we change class B to this:
class B extends A {
static void test() {
System.out.print("B");
}
}
and recompile only B (not C). Now invoking C again, it would print "CB".
There is no super like keyword for static methods, though - a (bad) justification may be that "The name of the super class is written in the declaration of this class, so you had to recompile your class nevertheless for changing it, so you could change the static calls here, too."
The whole inheritance concept isn't applied to static elements in Java. E.g., static method can't override another static method.
So, no, you'll have to call it by name or make them instance methods of some object. (You might want to check out one of factory patterns in particular).
A practical example
class A {
static void test() {
System.out.println("A");
}
}
class B extends A {
static void test() {
System.out.println("B");
}
}
A a = new B();
B b = new B();
a.test();
b.test();
This prints A and then B. I.e., invoked method depends on how variable is declared and nothing else.
You can actually call the static method of a superclass in a generic way, given that you know the method name and its parameters.
public class StaticTest {
public static void main(String[] args) {
NewClass.helloWorld();
}
}
public class NewClass extends BaseClass {
public static void helloWorld() {
try {
NewClass.class.getSuperclass().getMethod("helloWorld", new Class[] {}).invoke( NewClass.class ,new Object[]{} );
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("myVar = " + myVar);
}
}
public class BaseClass extends BaseBaseClass {
protected static String myVar;
public static void helloWorld() {
System.out.println("Hello from Base");
myVar = "Good";
}
}
This should work and in the subclass you have everything set in the base class available.
The output should be:
Hello from Base
myVar = Good
The official name of your implementation is called method hiding. I would suggest introducing a static init(Controller controller) method, and calling an instance method to take advantage of overriding.
public class Controller {
static void init(Controller controller) {
controller.init();
}
void init() {
//init stuff
}
}
public class BaseController extends Controller {
#override
void init() {
super.init();
//base controller init stuff
}
}
public class ChildController extends BaseController {
#override
void init() {
super.init();
//child controller init stuff
}
}
You can then call Controller.init(controllerInstance).
For static methods there is no instance of a class needed, so there is no super.