简体   繁体   中英

Polymorphism and inheritance

In a situation like this:

class A{
   public int x = 4;
   public void s3(){
      x = 3;
   }
   public void f(){
      x = 8;
      s3();
   }
}

class B extends A{
   public int x = 5;
   public void f(){
      x = 10;
      s3();
   }
}

A a = new B();
B b = (B) a;
a.f();
System.out.println(b.x);
System.out.println(a.x);

af() calls the f() of the class B , then f() , after an assignment, calls the s3() function. At this point, s3() is only defined in A and when it assigns the value 3 to x , x is the copy of the variable owned by the class A . Why s3() doesn't use the x declared in B ? In theory, B shouldn't has its own copy of s3() function inherited from A ? (so the s3() inherited from A in B should use the x declared in B )

You have a misunderstanding of what you should be doing in inheritance. extends is a reserved word that was wisely chosen. The point of B extending A is to say that B is a subset of A with additional attributes. You're not supposed to redefine x in B; A should be handling x . By redefining x in a subclass, you're hiding the superclass' field x (this is true even if x refers to different variable types).

A a = new B();
System.out.println(a.x);  //4 makes sense, since we are of class A
B b = (B) a;
System.out.println(b.x);  //5 makes sense, since we are of class B
a.f();
System.out.println(a.x);  //3 makes sense, since a.f() calls s3(), which sets A's x to 3
System.out.println(b.x);  //10 

The 10 follows from printing b's x, which is assigned to 10 with the call of af() , which then calls s3() which is why the 3rd example prints 3. To see what I mean look at this:

  public void f()
   {
      x = 10; //sets B's x to 10
      s3();  //calls A's s3(), which sets A's x to 3.
   }

Because it is the same. You do not have two copies ("instances") of the object, only one.

Since the one you create is a B instance ( new B() ), it will be used the methods as defined in B . Of course, when no methods are defined in B it will use the superclass methods implementation.

So, you only have an x attribute and s3 forces it to be 3 . It works ok.

Why s3() doesn't use the x declared in B?

Generally, methods in a parent class cannot see member variables in a child class.

I think doing just this:

B b = new B();
b.f();

is enough to reproduce at least part of your confusion. Here is what f() looks like in B:

class B extends A{
   public int x = 5;
   public void f(){
      x = 10;
      s3();
   }
}

f() is equivalent to:

   public void f(){
      this.x = 10;
      this.s3();
   }

So calling bf() means f() is equivalent to:

   public void f(){
      b.x = 10;
      b.s3();
   }

Next, what happens inside the s3() method in A? s3() looks like this:

public void s3(){
      x = 3;
   }

and that is equivalent to:

public void s3(){
      this.x = 3;
   }

'this' is the object that called the method, which from the last example of f() you can see is b. So s3() is equivalent to:

public void s3(){
      b.x = 3;
   }

So bx gets overwritten with 3...uhhhhm not so fast!

An instance of B also inherits an x from A, it's just that inside B it so happens that B's x shadows the x from A. As a result, the f() method in B assigns to the x from B. Inside s3() however, the x that b got from A is not shadowed anymore, and as far as A is concerned there is only one x--the one from A. In other words, the lookup for bx takes a different path depending on what class that statement appears in.

After s3() executes, the end result is that b has two x's with two different values. Inside methods in B, the x from B will be visible, and inside methods in A, the x from A will be visible. Inside methods in B, it is possible to get at the the x from A by using super.

In theory, B shouldn't has its own copy of s3() function inherited from A?

Don't think in terms of copies. Think in terms of pointers from class to class, and pointers from classes to lookup tables. Typically in computer programming, each instance has its own instance variables but methods are shared by all the instances in a class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM