///Example code here
Superclass{
method1(){
print(do1);
}
method2(){}
}
Subclass extends Superclass{
///override method1
method1(){
print(do2);
}
method3(){}
}
I have a question for the polymorphism in java, which is when Superclass s =new Subclass(). the "s" object always invoke the method in the Superclass, but when the override method happened, the "s" will point back to the override methods.
Update:
So, the question is who will create a heap address for the reference "s", if it can be compiled and running in the end. If the Superclass created it, why new Subclass() rather than new Superclass(). If the Subclass created it, why cannot use s.method3().
s can call method3. You just have to cast it first. If they allowed s to call method3 as Superclass, it wouldn't make sense because not ALL Superclass can call method3.
Dynamic binding of method will decide at run times , so first when you call method with s as its reference of super class compiler will always first check if superclass has that method or not. there are 2 case
1. If super class has the method JVM will go ahead and check in child class, If child class has overriding method then that method will be called , if child class doesn't have that method than normally parent class method will call.
2. If super class does not have that method , then compilation fails as compiler could not identified any method in class of reference variable
So in your case if super class doesn't have method3 then it will defiantly gives compilation error
Related
As stated in the title, pertaining specifically to Java. In pseudocode an example of this might be:
class SubClass extends SuperClass {
protected void update() {
super.update()
// do other functionality
}
}
class SuperClass {
protected void update() {
if (something) return;
}
}
If the update method is called and the superclass then returns, does the other functionality in the subclass then execute or does it return fully to where the original subclass method is called?
As a follow up question, if this is not the case, is there a way to effectively prevent any further code from running in the superclass or subclass methods?
There's nothing special about the method call from the subclass to the superclass (other than which method gets called, which the super keyword influences, obviously). The answers to your questions flow from that fact:
Does the return keyword in a superclass method return to the subclass that called the superclass method?
Yes, just like any other method call. Sometimes, the subclass needs to do work after the superclass work is done, and/or with the return value from the superclass before returning to the caller.
...is there a way to effectively prevent any further code from running in the superclass or subclass methods?
Not from the superclass method, no. You can throw an exception, but (of course) the subclass method could catch it. Which is, again, just like any other method call.
Because the type of the method is protected, access from subclasses is
possible. Also void methods do not return.
This question already has answers here:
Overriding member variables in Java ( Variable Hiding)
(13 answers)
Java cast to superclass and call overload method
(1 answer)
Closed 5 years ago.
Super keyword related doubt.
class Parent{
int x=40;
void show()
{
System.out.println("Parent");
}
}
class Child extends Parent
{ int x=20;
void show() //method overriding has been done
{
System.out.println(super.x); // prints parent data member
System.out.println(((Parent)this).x); /*same output as previous statement which means super is similar to (Parent)this*/
System.out.println("child");
super.show(); // invokes parent show() method
((Parent)this).show(); //Doesnt invoke parent show() method.Why?
}
public static void main(String s[])
{
Child c1=new Child(); //Child class object
c1.show();
}}
So, System.out.println(super.x) and System.out.println(((Parent)this).x) prints the same value.So if super.show() calls parent class show() method then why is ((Parent)this).show(); unable to call parent show()? Please tell appropriate explaination for this.
Constructor Chaining
in Java keyword this represent current object and when one class extends another then its super class reference variable may hold child class reference variable that's is in your code is ((Parent)this).x ,
while super keyword is used to call directly super class constructor and its variables.
at the same time when super class variables holds child class object and when we use super it refers same object .
How to call one constructor from another constructor in Java or What
is Constructor Chaining in Java is one of the tricky questions in Java
interviews. Well, you can use this keyword to call one constructor
from another constructor of the same class if you want to call a
constructor from based class or super class then you can use super
keyword. Calling one constructor from other is called Constructor
chaining in Java. Constructors can call each other automatically or
explicitly using this() and super() keywords. this() denotes a
no-argument constructor of the same class and super() denotes a no
argument or default constructor of parent class. Also having multiple
constructors in the same class is known as constructor overloading in
Java.
Read more: http://www.java67.com/2012/12/how-constructor-chaining-works-in-java.html#ixzz4bJ5C069o
Calling ((Parent) this).show(); on what is really a Child object causes Child.show() to be called. Whether you are doing it as myObject.show() or through this makes no difference for which version of the method gets called — it’s always the method determined by the object’s runtime type, in this case Child.
So you have a recursive call, leading to infinite recursion.
super.show() on the other hand calls the method in the super class, in this case Parent.
I'm new to Java Programming and learning polymorphism.
__EDIT__
As per the answers I received from everyone,I have code:
Here I'm typecasting my Derived object (obj) to Base type and then calling method().
public class Tester {
public static void main(String[] args) {
Base obj=(Base)new Derived();
obj.method();
}
}
class Base{
public void method(){
System.out.println("In Base");
}
}
class Derived extends Base{
public void method(){
System.out.println("In Derived");
}
}
Output I'm getting is: "In Derived".
So after typecasting my object should become of type Base referenced by Base type.
But it's not happening? Why?
Does typecast work on child->parent conversion or it has no effect here?
Base obj=new Derived();
In the above statement, the reference part points to type Base. This is how the compiler identifies which class to consider. But your code will create an error. Let me explain the structure of the above statement before explaining why will it show an error.
Structure of the above statement:
Declaration-The reference part is Base obj.
Instantiation: The new keyword is a Java operator that creates the object/allocates space in the memory.
Initialization: The new operator is followed by a call to a constructor, which initializes the new object.
Since, Derived is a sub-class of Base, you are allowed to call the constructor in the Derived class. This is how inheritance and polymorphism works.
Okay, Now let us go back to the error part.
The obj.method() in your code is looking for a function method() in Base class but the method(int a) function in Base class requires an argument of type integer to be passed. So for the code to work, the calling statement has to be something like obj.method(5).This statement works because the calling statement is actually passing 5 to the function.
There is an easy fix for your code:
Derived obj=new Derived();
Have you noticed?
I have relaced the reference to type Derived.
Why does that work?
Because there is method() function in your Derived class which doesn't require an integer argument.
There is one more amazing fact about inheritance in Java:
Everything possessed by a super-class is also possessed by the sub-class but the reverse is not true. And yes, the sub-class has the right to redefine any method/function it has inherited from super-class.
The above statement means the following code will work:
Derived obj=new Derived();
obj.method(5);
You must be wondering-How come this code works even though method() in Derived requires no argument. In fact, Derived has no method(int a).
Well, the answer to this is the amazing fact I have mentioned above.
Yes, method(int a) also belongs to Derived since it's a sub-class of Base.
But How does the code mentioned below work?
Derived obj=new Derived();
obj.method(5);
Simple, the JVM looks for the method(int a) in class Derived and it finds the function since Derived has inherited the function from Base class.
Remember this too, the sub-class also has a privilege to over-ride a method in super class. This means that you can add method(int a) function in class Derived which over-rides the original method inherited from Base.
How inheritance works?
When you call obj.method(5) in the above code, the JVM first looks for any over-ridden method of the same type in Derived. If it does not find any over-ridden method, it moves up in the inheritance hierarchy chain to the super class and looks for the same method. But the reverse is not the true.
how does compiler comes to know which method is to be called & too from which class?
The compiler searches for the method in the class (in this case Base) of the object (in this case obj). If the method is not found in that class, then it looks for the method in the super class (in this case Object). If still not found, it flags an error.
Is it that compiler checks the reference type class & if method to be invoked is not present in reference type class it gives error??
Yes. But, as said before, If the method is not found in that class, then it looks for the method in the super class (in this case Object). If still not found, it flags an error.
Your obj.method() will fail, because Base does not have a method with the signature method() (it has method(int))
If your obj was of type Derived, then both these case will work:
obj.method(); // will call this method from the Derived class
obj.method(1); // will call this method from the Base class
when there are same method names in different classes , the compiler comes to know by:
1-if you are passing any argument , then the type of argument which you are passing will tell the compiler which method to be called
2-if there are two classes , then make the object of that class for which you want to call the method
I have an abstract class and its concrete subclass, when I create an object of subclass it automatically calls the super constructor. Is the JVM internally creating an object of the abstract class?
public abstract class MyAbstractClass {
public MyAbstractClass() {
System.out.println("abstract default constructor");
}
}
public class ConcreteClass extends MyAbstractClass{
public static void main(String[] args) {
new ConcreteClass();
}
}
then how constructor exists without an object in JVM ?? (In case of abstract class)
Also constructor gets executed after object is being created then without creating the object of abstract class how the default constructor get executed ?? (This is mentioned in Java Doc)
Is it true that you can't instantiate abstract class?
Yes.
Is JVM internally create object of abstract class ?
No, but it's a common misunderstanding (and that wouldn't be an unreasonable way for it to be done; prototypical languages like JavaScript do it that way).
The JVM creates one object, which is of the class you created (in your case, ConcreteClass). There are aspects of that one object that it gets from its superclass (MyAbstractClass) and from its subclass (ConcreteClass), but there is only one object.
The object is an aggregate of all of its parts, including parts that seem to have the same name, such as a method of the superclass that is overridden by the subclass. In fact, those methods have different fully-qualified names and don't conflict with one another, which is why it's possible to call the superclass's version of an overridden method.
So if it's just one object, why do you see the call to MyAbstractClass's constructor? Before we answer that, I need to mention a couple of things the Java compiler is doing that you don't see in the source code:
It's creating a default constructor for ConcreteClass.
In that constructor, it's calling the MyAbstractClass constructor.
Just to be thorough: In the MyAbstractClass constructor, it's adding a call to the superclass's (Object) constructor, because there's no super(...) call written within the MyAbstractClass constructor.
Here's what the code looks like with the bits the Java compiler adds for you filled in:
public abstract class MyAbstractClass {
public MyAbstractClass() {
super(); // <== The Java compiler adds this call to Object's constructor (#3 in the list above)
System.out.println("abstract default constructor");
}
}
public class ConcreteClass extends MyAbstractClass{
ConcreteClass() { // <== The Java compiler adds this default constuctor (#1 in the list above)
super(); // <== Which calls the superclass's (MyAbstractClass's) constructor (#2 in the list above)
}
public static void main(String[] args) {
new ConcreteClass();
}
}
Okay, with that out of the way, lets touch on a point TheLostMind very usefully mentioned in a comment: Constructors don't create objects, they initialize them. The JVM creates the object, and then runs as many constructors (they really should be called initializers) against that one object as necessary to give each superclass a chance to initialize its part of the object.
So in that code, what happens (and you can step through this in a debugger to fully understand it) is:
The JVM creates an object
The ConcreteClass constructor is called
The first thing that constructor does is call its superclass's constructor, in this case MyAbstractClass's constructor. (Note that this is an absolute requirement: The Java compiler will not allow you to have any logic in the constructor itself prior to the superclass constructor call.)
The first thing that constructor does is call its superclass's constructor (Object's)
When the Object constructor returns, the remainder of the MyAbstractClass constructor runs
When the MyAbtractClass constructor returns, the remainder of the ConcreteClass constructor runs
The object is returned as the result of the new ConcreteClass() expression.
Note that the above would get more complicated if there were instance fields with initializers. See the JLS and JVM specs for the full details.
JVM doesn't create object of abstract class. it is calling its super constructor
JVM will create one object, an instance of the concrete class which inherits fields and methods of abstract class
I have derived a class in java.
I noticed that the superclass constructor gets called before code in my derived class constructor is executed.
Is there a way to invert that order?
Example:
class Animal
{
public Animal()
{
//do stuff
}
}
class Cat extends Animal
{
int var;
public Cat(int v)
{
var = v;
super();
}
}
This is what I would like to do, but calling super() like that gives an error...
No, there is no way to invert that order. If you explicitly call a parent class constructor you are required to do it at the top of your constructor. Calling it later would allow a child class to access the parent class's data before it's been constructed.
No, you can't invert the order of constructor calls this way. A call to super() must be the first statement in a constructor. And if there is no such call, Java inserts an implicit call to super() as the first statement.
The JLS, Section 8.8.7, states:
The first statement of a constructor body may be an explicit invocation of another constructor of the same class or of the direct superclass (§8.8.7.1).
ConstructorBody:
{ [ExplicitConstructorInvocation] [BlockStatements] }
There isn't a way to call run the sub class constructor before superclass constructor. That's basically like trying to create the subclass even before the superclass gets created, which is impossible since the subclass relies on superclass attributes to get created.