Why "THIS" keyword denotes Child object into Parent class's method? - java

I'm using Child and Parent relationship using Inheritance. I had written a code where I use 'THIS' keyword in a method of Parent class and the same method is overridden in my Child class. When I call Parent class method from Child class overridden method using 'Super' keyword then in Parent class method, the 'THIS' keyword denotes Child object class, and when I call a method from Parent class method using 'THIS' keyword then It call Child class method(this method is same and also available in Parent & Child Class using overriding).
class Parent {
void onResume() {
println("Parent:OnResume" + this) // Here 'this' denotes Child class's Object
this.show() // here Child class's method is invoked
show() // here Child class's method is invoked as well
}
void show() {
println("Parent:Show")
}
}
class Child extends Parent {
override
void onResume() {
super.onResume()
println("Child:->OnResume" + this)
}
override
void show() {
println("Child:Show")
}
}
//Calling code
Parent parentRef = new Child()
parentRef.onResume()
If I create an Object of Child class using Parent class reference variable like
Parent parentRef = new Child()
then 'this' denotes Child object in onResume() method of Parent class and when we call show() method in Parent then it call Child class's show() method.
Please let me clear why it happens so. As I know 'this' refers Current object of the class so here why 'this' refers Child object from Parent class.
Please provide deep and internal details for this reason. Thanks in advance.

this references the current instance. If you create an instance of Child, the runtime type of this is Child, regardless of whether you write this in the parent class code or the child class code.
And if you call this.someMethod() in the Parent class code, if someMethod is overridden by Child class, the Child class method will be executed.

When you override a method, you overwrite the functionality of the overridden method.... unless the child class calls super.show() from somewhere. In other words, the child is in full control of whether the original (overridden) functionality is still available or not and from where it is available. (The child is not limited to calling super.show() from within the overridden show() but may call it from other methods and constructors as well!)

Related

How can we access super class's method which a sub class has overidden? Hows that possibly on memory level?

I saw an example where a super class's original method was accessed from the subclass's method which is an overridden method. But a sub class's instance will only have a method that's an overridden method and not the superclass's method.But how come subclass is able to access super class's method.
Reference which says an sub class instance has only overiden method
// A Java program to demonstrate that overridden
// method can be called from sub-class
// Base Class
class Parent
{
void show()
{
System.out.println("Parent's show()");
}
}
// Inherited class
class Child extends Parent
{
// This method overrides show() of Parent
#Override
void show()
{
super.show();
System.out.println("Child's show()");
}
}
// Driver class
class Main
{
public static void main(String[] args)
{
Parent obj = new Child();
obj.show();
}
}
OUTPUT:
Parent's show()
Child's show()
A class probably has a table of function pointers to its implementation methods. It probably has a reference (implicit by class layout or explicit via a pointer or some sort of reference) to its super class and has indirectly access to that class's table of function pointers. All these are implementation details not specified in the Java language.
An analogy can be found http://www.faq3.de/OrganizeMe/pg/pdf/inside.the.c++.object.model.pdf on page 93
Calling super.show() logically moves to the super class's (Parent) table of function pointers and calls that class's show() method.

Overridden method call in parent method

Considering the following:
public class Child extends Parent{
public boolean isMeh(){
return true;
}
public void childMethod() {
System.out.println("child: "+isMeh());
}
public static void main(String... args){
Child child = new Child();
child.parentMethod();
child.childMethod();
}
}
class Parent{
public boolean isMeh(){
return false;
}
public void parentMethod() {
System.out.println("parent: "+isMeh());
}
}
Output:
parent: true
child: true
It is pretty obvious when isMeh() is called within Child class, it calls the overridden method.
But when the overriden method is called within a method of the parent object, it still calls the child object's method.
I see that we create one child object and parentMethod is just inherited so when we call isMeh() it calls the available(overridden) one.
What would be the reason for this implementation in java?
Any class in an inheritance hierarchy of Parent, be it a Child, a Parent, or some Grandchild deriving from them, has exactly one implementation of the method called isMeh. When Child overrides isMeh of Parent with its own implementation, it replaces the implementation; as far as the Child is concerned, the implementation in the Parent no longer applies*.
When you instantiate Child and call its parentMethod, the method has access to only one method isMeh - that is, the implementation provided by the Child. That is why you get the behavior that you describe.
This behavior allows for very nice patterns: for example, you can write a "partial implementation" of a method in the parent by relying on "plug-in" functionality in the child class provided through overrides. This technique is known as Template Method Design Pattern.
* although Child retains an ability to call Parent's isMeh explicitly.

Private method of call from Child Object

class Parent {
public Parent() {
System.out.println("Parent Default..");
System.out.println("Object type : " + this.getClass().getName());
this.method();
}
private void method() {
System.out.println("private method");
}
}
class Child extends Parent {
public Child() {
System.out.println("Child Default..");
}
public static void main(String[] args) {
new Child();
}
}
When I run this code it prints the class name of "this" = Child
but the "this" object is able to call the private method of parent class why?
when you extend the class the private methods will not be inherited .but the object of the child class contains object of the parent class so when the superclass constructor is called .you are able to call the superclass private method inside the super class
First of all, when calling new Child(), since there is not a declared non-argument constructor in Child class, it will simple call super() which is invoking the Parent constructor.
Then, when executing this.getClass().getName(), here this stands for a Child instance, this is why you get "Child" as the result. Remember, Object#getClass() returns the most specific class the object belongs to. see more from here.
About why this.method() works. First, because Child extends Parent, the Child instance is also a Parent instance. The java scope modifier controls where the methods or fields can be accessed. Taking Parent#method() as the example, the private modifier indicates that this method can only be accessed (invoked) inside the Parent class. And this is exactly how you code does. it invokes the method inside the constructor of Parent class, which compiles the rule. See more about java access control from here
private has nothing to do with the actual class of the object. A private member can be accessed by any code within the same top-level class. (A top-level class is one that's not nested, which is unrelated to inheritance)
method is defined in Parent, and the call this.method() is also in Parent, so it's allowed.
A parent instance is not created here, you can confirm this using jvisualjvm in the /bin folder of your jdk installation, the child instance is not created either. Parent constructor is still invoked.
output:
Parent Default..
Object type : com.packagename.Child
private method
Child Default..
Parent constructor can be invoked by child class.
While in the constructor of parent, as Krishanthy Mohanachandran has noted above, a private method can be legally invoked.
It is abvious, you can call any private members within the class but not outside the class.
In this case it is legal. In this program first the constrctor of the Parent will be called and you can call private method within the class.

How to access methods of ancestor class when intermediate parent class overrides it? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
abstract class Parent {
int i = 9;
void display() {
System.out.println("base");
}
}
class Child extends Parent {
int i = 8;
public void display() {
System.out.println("derived");
}
}
public class A {
public static void main(String args[]) {
Parent a1 = new Child();
a1.display(); // calls child class method
System.out.println(a1.i);// calls parent class member
}
}
when i run this code display method of derived class is being called
Looks like you have programmed in other programming languages like C++ or C# where you must specify the method as virtual in order to use the subclass method. In Java, all the methods except private, final and static are virtual.
Knowing this, since Child class already overrides display method from Parent class, when you do this:
Parent a1 = new Child();
a1.display();
a1.display will execute the display method of the actual object reference class, in this case, Child#display.
In order to fix the code, change the initialization of a1 to be a new Parent:
Parent a1 = new Parent();
a1.display();
More info:
Can you write virtual functions / methods in Java?
After your edit, now you face the problem when printing a1 in the console, probably printing 9 instead of 8. What you're doing here is hiding the field. Fields do not get overridden, so the value of the i variable will depend on the actual class type declared for the variable. Since you have declared a1 as Parent, then a1.i will take the value of Parent#i.
In order to fix this code, change the a1 variable type to Child:
Child a1 = new Child();
System.out.println(a1.i);
a1.display();
Or a even better solution: NEVER try to override a field, and what's worse, don't try to access to class fields from other classes directly, instead use the respective getters and setters.
More info:
Hiding fields
How to access methods of ancestor class when intermediate parent class overrides it?
Assuming this is your real question, then the answer is simple: you can't.
You cannot access Parent class display() method directly without creating an object of it.
But you can access it from you child class.like this
class Child extends Parent {
int i = 8;
public void display() {
super.display();
System.out.println("derived");
}
}
According to java docs Accessing Superclass Members
If your method overrides one of its superclass's methods, you can invoke the overridden method through the use of the keyword super. You can also use super to refer to a hidden field (although hiding fields is discouraged).
If I understand your question right you are trying to invoke the PARENTS display method using CHILD instance.
With just the derived class object there's NO way to instruct the compiler to make the non-virtual call to the base-class version.
You just cannot. If you want the code in parent class to be executed then you either have to create a parent class (note: Parent is not abstract class) or you have to provide call to super.someMethod() in one of the methods of the child. For example:
public void display() {
super.display();
System.out.println("derived");
}
I think what you are trying to ask is why the variables of parent class is displayed and method of child class.
Firstly, overriding is not applied to variables,it is applied on methods. Whatever class the reference belongs to, that variable will be displayed straight away.In your code,
Parent a1 = new Child();
System.out.println(a1.i);
Here a1 is a reference to Parent class, so variable of Parent class is displayed.
In case of methods, it is decided at run time which version of methods would be called. That method is called whose object is created, here object of Child class is crated Parent a1 =new Child(); . See the part new Child() and hence the Child class method. But remember, this method should be present in the class that the reference belongs. For example
Class Parent
{
}
Class Child extends Parent
{
public void display()
{
System.out.println("derived");
}
public static void main (String []args)
{
Parent a1 = new Child();
a1.display(); //Error
}
}
To call the base class method in your original example, use super as others have mentioned. Or simply create an object of parent class
Parent o = new Parent();
o.display(); //prints base

Why call super() in a constructor?

I'm dealing with a class which extends JFrame.
It's not my code and it makes a call to super before it begins constructing the GUI. I'm wondering why this is done since I've always just accessed the methods of the superclass without having to call super();
There is an implicit call to super() with no arguments for all classes that have a parent - which is every user defined class in Java - so calling it explicitly is usually not required. However, you may use the call to super() with arguments if the parent's constructor takes parameters, and you wish to specify them. Moreover, if the parent's constructor takes parameters, and it has no default parameter-less constructor, you will need to call super() with argument(s).
An example, where the explicit call to super() gives you some extra control over the title of the frame:
class MyFrame extends JFrame
{
public MyFrame() {
super("My Window Title");
...
}
}
A call to your parent class's empty constructor super() is done automatically when you don't do it yourself. That's the reason you've never had to do it in your code. It was done for you.
When your superclass doesn't have a no-arg constructor, the compiler will require you to call super with the appropriate arguments. The compiler will make sure that you instantiate the class correctly. So this is not something you have to worry about too much.
Whether you call super() in your constructor or not, it doesn't affect your ability to call the methods of your parent class.
As a side note, some say that it's generally best to make that call manually for reasons of clarity.
None of the above answers answer the 'why'.
Found a good explanation here:
A subclass can have its own private data members, so a subclass can
also have its own constructors.
The constructors of the subclass can initialize only the instance
variables of the subclass. Thus, when a subclass object is
instantiated the subclass object must also automatically execute one
of the constructors of the superclass.
You might also want to read everything about the super keyword here or watch everything about the super keyword here.
We can access super class elements by using super keyword
Consider we have two classes, Parent class and Child class, with different implementations of method foo. Now in child class if we want to call the method foo of parent class, we can do so by super.foo(); we can also access parent elements by super keyword.
class parent {
String str="I am parent";
//method of parent Class
public void foo() {
System.out.println("Hello World " + str);
}
}
class child extends parent {
String str="I am child";
// different foo implementation in child Class
public void foo() {
System.out.println("Hello World "+str);
}
// calling the foo method of parent class
public void parentClassFoo(){
super.foo();
}
// changing the value of str in parent class and calling the foo method of parent class
public void parentClassFooStr(){
super.str="parent string changed";
super.foo();
}
}
public class Main{
public static void main(String args[]) {
child obj = new child();
obj.foo();
obj.parentClassFoo();
obj.parentClassFooStr();
}
}
It simply calls the default constructor of the superclass.
We use super keyword to call the members of the Superclass.
As a subclass inherits all the members (fields, methods, nested classes) from its parent and since Constructors are NOT members (They don't belong to objects. They are responsible for creating objects), they are NOT inherited by subclasses.
So we have to explicitly give the call for parent constructor so that the chain of constructor remains connected if we need to create an object for the superclass. At the time of object creation, only one constructor can be called. Through super, we can call the other constructor from within the current constructor when needed.
If you are thinking why it's there for a class that is not extending any other class, then just remember every class follows object class by default. So it's a good practice to keep super in your constructor.
Note: Even if you don't have super() in your first statement, the compiler will add it for you!
We can Access SuperClass members using super keyword
If your method overrides one of its superclass's methods, you can invoke the overridden method through the use of the keyword super. You can also use super to refer to a hidden field (although hiding fields is discouraged). Consider this class, Superclass:
public class Superclass {
public void printMethod() {
System.out.println("Printed in Superclass.");
}
}
// Here is a subclass, called Subclass, that overrides printMethod():
public class Subclass extends Superclass {
// overrides printMethod in Superclass
public void printMethod() {
super.printMethod();
System.out.println("Printed in Subclass");
}
public static void main(String[] args) {
Subclass s = new Subclass();
s.printMethod();
}
}
Within Subclass, the simple name printMethod() refers to the one declared in Subclass, which overrides the one in Superclass. So, to refer to printMethod() inherited from Superclass, Subclass must use a qualified name, using super as shown. Compiling and executing Subclass prints the following:
Printed in Superclass.
Printed in Subclass
as constructor is not a part of class,
so while calling it cannot be implemented,
by using SUPER() we can call the members and memberfunctions in constructor.

Categories