I try to understand with inheritance in Java . There is some code:

 class A { A getThis() { System.out.println("call getThis() from A"); return this; //(3) } //(3) Object getSuper() { System.out.println("call getSuper() from A"); return null;} } class B extends A { B getThis() { System.out.println("call getThis() from B"); return this; } A getSuper() { System.out.println("call getSuper() from B"); return super.getThis(); } } class Tester { public static void main (String[] args) { Object a = new B().getSuper(); //(1) System.out.println(a); a = new B().getSuper().getSuper(); //(2) System.out.println(a); } } 

As a result, the following text is output to the console:

call getSuper () from B

call getThis () from A

B @ 25154f

call getSuper () from B

call getThis () from A

call getSuper () from B

call getThis () from A

B @ 10dea4e

I expected that when working out line (1) in a will be an instance of class A , and after working out line (2) in a will be null . Why does the return of this from line (3) return the link not to the parent class, but to the original one?


As I understand it, when creating an instance of class B , it stores a reference to an instance of the parent class A I see indirect confirmation of my words:

When a class B constructor is called, the class A constructor is called. Even by redefining the method f in class B, one can get to the method f class A through the construction super.f() ;
Despite this, when working with an instance of class B , I see no way to return from it a reference to an instance of class A , which is used in it. Is there any way to realize this opportunity?

  • one
    A a = new B() ? - Grundy
  • 3
    From the point of view of the PLO, B is A, therefore you can use B where A. is expected. In addition, if necessary, you can link the link. - free_ze
  • @free_ze I understand this, but it is the answer to the question that interests me). A a = new B(); It is also not an answer to the question, since we are only performing an upward transformation. By reference a will still be an instance of class B Even when calling af(); the call to the overridden method, but not the base method, will work. - Roxio0
  • 2
    "As I understand it, when creating an instance of class B, it contains a link to an instance of the parent class A. I see indirect confirmation of my words:" - no, you understand incorrectly. - Pavel Mayorov
  • 2
    @ Roxio0 because no "instance of class A" in your case exists. So, there can be no links to it. - Pavel Mayorov

4 answers 4

I think you confuse the concepts of class and object.

A class is a way of describing an entity, defining a state and behavior depending on this state, as well as rules for interacting with a given entity (contract).

An object (instance) is a separate representative of a class that has a specific state and behavior that is fully defined by the class.

The keyword this indicates not a class, but an instance of a class (object). The super keyword provides access to the properties and methods of the same object but described in the superclass.

For example: You have created a бирюса object of the бирюса class, and the Холодильник class is inherited from the БытоваяТехника class. The object of бирюса is both a refrigerator and household appliances. This will return a link to the object of the бирюса , no matter through which class the link Холодильник or БытоваяТехника , the object does not change from this.

So your object a is an instance of class B , and at the same time it is an instance of class А , since it is inherited from it. When you call the getSuper () method on a chain, this is eventually returned, that is, a reference to the object a

The class and object definitions are taken from here .

  • Thanks for the detailed answer. But my curiosity is not satisfied) As I understand it, super holds a link to a superclass instance. Can I somehow still explicitly return it from an instance of the extended class? - Roxio0
  • Object one - a . You can do this: B b = new B(); A a = b; B b = new B(); A a = b; Variables а and b will point to the same object. - privod
  • We only do the upward transformation in this case, the object remains the same. This is not exactly what I wanted) - Roxio0
  • 9
    "As I understand it, super holds a link to a superclass instance" - no, you understand completely wrong. super is not a variable or a link, super is a keyword that allows you to call the superclass method and nothing more. - Pavel Mayorov

This answer was given to the question " Link to the superclass, " poured here. He had a slightly different wording.


  1. As I understand it, when creating an instance of class B , it stores a reference to an instance of the parent class A

    No, it is not stored. An instance of class B is an instance of class A To make it clearer, consider how the inheritance mechanism is implemented in Java, C ++, and several other languages.

    Let class A defined as follows:

     public class A { public int Foo; private short Bar; } 

    Then the instances of this class will have in mind the following form:

     ref -> +-----------------------+ | Внутренние данные JVM | +=======================+ | Foo | +-----------------------+ | Bar | +-----------------------+ 

    where ref is a reference to a region of memory with class instance data.

    In the above scheme, you can notice two features:

    1. Open and closed class fields are mixed; access modifiers act only at the compilation stage when checking the validity of field calls.
    2. The Java Virtual Machine stores its own internal data next to the data of the class itself. Depending on the specific virtual machine, these can be: a smart pointer pointer, a link to meta information, or a link to a table of pointers to overridden functions of functions.

    In the case of inheritance:

     public class B extends A { public AnotherClass Foo2; private int Bar2; } 

    The data inherent in the parent class are attributed to the end data inherent in the child class:

     ref -> +-----------------------+ | Внутренние данные JVM | +=======================+ | Foo | +-----------------------+ | Bar | +=======================+ | Foo2 | +-----------------------+ | Bar2 | +-----------------------+ 

    This whole bundle denotes an instance of class B You may notice that the reference to it exactly coincides with the reference to the instance of class A As a result, bringing links up the hierarchy is simply a re-naming of an existing link.

    A "link to an instance of the parent class" is used in the nested classes that really refer, that's just not to the parent, but to the closing class.

  2. Despite this, when working with an instance of class B, I see no way to return from it a reference to an instance of class A, which is used in it.

    Ascending type conversion is always performed implicitly (automatically):

     B foo = getFoo(); A bar = foo; 
    1. When a class B constructor is called, the class A constructor is called.

    2. Even by redefining the method f in class B, one can get to the method f of class A through the construction super.f() ;

    All this magic occurs due to the fact that the virtual machine knows the entire hierarchy of all classes, due to which it can explicitly or implicitly substitute a call to methods up the hierarchy.

    In order to understand why you cannot get a reference to an instance of the base class when calling a method of this class, you need to understand in the successor how the call to the inherited method works in java.

    First, we create one object in memory with all the fields inherited from the parents. And this object is accessible by one link and it does not contain any nested parents. Compare this references when calling constructor A and B

     public A(){ System.out.println(this); } public B(){ System.out.println(this); } 

    Second, the instance methods are stored separately from the object fields and the inherited methods from class A are invoked even for object B through class А But when calling inherited methods, they are passed a link to an instance of the descendant that calls them. Thus, the method is invoked on an actual instance of the created object.

    This method is used as the first argument.

      The call to the class A constructor when creating a class-successor class B is performed at the JVM job level and only to initialize the fields of the class B object, you cannot get this link programmatically, because there is no class A object. But if class B were an inner class A class, then it would store a reference to an object of class A.