Java calling Super constructor confusion - java

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.

Related

could parent object be created using super to call parent method

Would the parent object be created , if we use the super keyword to call the method of the parent class in child object?
Outcomes show that both Mybase and MySub have the same reference address. Not sure whether it is a good demo.
class Mybase {
public void address() {
System.out.println("super:" + this);
System.out.println( this.getClass().getName());
}
}
class MySub extends Mybase {
public void address() {
System.out.println("this:" + this);
System.out.println( this.getClass().getName());
}
public void info() {
System.out.println("this:" + this);
super.address();
}
}
public class SuperTest {
public static void main(String[] args) {
new MySub().info();
}
}
Well, let's find out!
Your test isn't quite going to answer your question. If you want to see if an object is created, why not create a constructor that prints to the console when called?
public class Test {
static class Parent {
Parent() {
System.out.println("Parent constructor called");
}
void method() {
System.out.println("Parent method called");
}
}
static class Child extends Parent {
Child() {
System.out.println("Child constructor called");
}
#Override
void method() {
System.out.println("Child method called");
super.method();
}
}
public static void main(final String[] args) {
new Child().method();
}
}
If you run this, you get this output:
Parent constructor called
Child constructor called
Child method called
Parent method called
So as you can see, when method() was called, no Parent object was created when the super keyword was used. So the answer to your question is "no".
The reason is because super and super() are different. super (no parentheses) is used to access members of the parent class. super() (with parentheses) is a call to the parent constructor, and is only valid inside a constructor as the first call in the constructor. So using super (no parentheses) will not create a new object.
Also, super() doesn't actually create a new, independent Parent object. It just does the initialization work for the fields of Parent that is needed before the child constructor continues.

Is it possible to call both default and parameterized constructors of SubClass and SuperClass for a particular instance(parameterized) in Java?

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.

calling a super method from a static method

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.

Why do I get StackOverflowError here?

Why does this java code produce StackOverflowError? I understand that this somehow connected with recursive generic type parameter. But I don't understand clear the whole mechanism.
public class SomeClass<T extends SomeClass> {
SomeClass() {
new SomeClassKiller();
}
private class SomeClassKiller extends SomeClass<T> {
}
public static void main(String[] args) {
new SomeClass();
}
}
The generic part doesn't matter - nor does it really matter that the class is nested. Look at this mostly-equivalent pair of classes and it should be more obvious:
public class SuperClass
{
public SuperClass()
{
new SubClass();
}
}
public class SubClass extends SuperClass
{
public SubClass()
{
super();
}
}
So the subclass constructor calls the superclass constructor - which then creates a new subclass, which calls into the superclass constructor, which creates a new subclass, etc... bang!
Here it is invoking one constructor from another and from it the previous one, cyclic constructor chain, see the comments below
public class SomeClass<T extends SomeClass> {
SomeClass() {//A
new SomeClassKiller();// calls B
}
private class SomeClassKiller extends SomeClass<T> {//B
//calls A
}
public static void main(String[] args) {
new SomeClass(); //calls A
}
}
This is because of the Recursive constructor calls happening between the classes SomeClass and
SomeClassKiller.
public class SomeClass<T extends SomeClass> {
SomeClass() {
new SomeClassKiller();
}
private class SomeClassKiller extends SomeClass<T> {
public SomeClassKiller()
{
super(); //calls the constructor of SomeClass
}
}
public static void main(String[] args) {
new SomeClass();
}
}
The code produced by the compiler is something like this, so when u create an object it recursivly calls the SomeClass and SomeClassKiller for ever.
Constructors are invoked top-to-bottom, that is if a class A derives from B, A's constructors will first invoke the parent constructor (B).
In you case, new SomeClassKiller() recursively calls the constructor of SomeClass which in turn constructs another SomeClassKiller … there it is.
The main() method is creating a new instance of SomeClass which calls the SomeClass constructor that creates a new instance of SomeClassKiller that by default calls the parent constructor and the stackoverflow occurs.
To avoid the stackoverflow. Change the code to look as follows:
public class SomeClass<T extends SomeClass> {
SomeClass() {
new SomeClassKiller();
}
private class SomeClassKiller extends SomeClass<T> {
public SomeClassKiller(){
//super(); does this by default, but is now commented out and won't be called.
}
}
public static void main(String[] args) {
new SomeClass();
}
}

In Java, how do I call a base class's method from the overriding method in a derived class?

I have two Java classes: B, which extends another class A, as follows :
class A {
public void myMethod() { /* ... */ }
}
class B extends A {
public void myMethod() { /* Another code */ }
}
I would like to call the A.myMethod() from B.myMethod(). I am coming from the C++ world, and I don't know how to do this basic thing in Java.
The keyword you're looking for is super. See this guide, for instance.
Just call it using super.
public void myMethod()
{
// B stuff
super.myMethod();
// B stuff
}
Answer is as follows:
super.Mymethod();
super(); // calls base class Superclass constructor.
super(parameter list); // calls base class parameterized constructor.
super.method(); // calls base class method.
super.MyMethod() should be called inside the MyMethod() of the class B. So it should be as follows
class A {
public void myMethod() { /* ... */ }
}
class B extends A {
public void myMethod() {
super.MyMethod();
/* Another code */
}
}
call super.myMethod();
I am pretty sure that you can do it using Java Reflection mechanism. It is not as straightforward as using super but it gives you more power.
class A
{
public void myMethod()
{ /* ... */ }
}
class B extends A
{
public void myMethod()
{
super.myMethod(); // calling parent method
}
}
Use the super keyword.
super.baseMethod(params);
call the base methods with super keyword and pass the respective params.
class test
{
void message()
{
System.out.println("super class");
}
}
class demo extends test
{
int z;
demo(int y)
{
super.message();
z=y;
System.out.println("re:"+z);
}
}
class free{
public static void main(String ar[]){
demo d=new demo(6);
}
}
See, here you are overriding one of the method of the base class hence if you like to call base class method from inherited class then you have to use super keyword in the same method of the inherited class.
// Using super keyword access parent class variable
class test {
int is,xs;
test(int i,int x) {
is=i;
xs=x;
System.out.println("super class:");
}
}
class demo extends test {
int z;
demo(int i,int x,int y) {
super(i,x);
z=y;
System.out.println("re:"+is);
System.out.println("re:"+xs);
System.out.println("re:"+z);
}
}
class free{
public static void main(String ar[]){
demo d=new demo(4,5,6);
}
}
If u r using these methods for initialization then use constructors of class A and pass super keyword inside the constructor of class B.
Or if you want to call a method of super class from the subclass method then you have to use super keyword inside the subclass method like :
super.myMethod();

Categories