Java 继承与多态(一)

今天在看java编程思想的时候,遇到了一个问题,没有想明白,于是放在这里讨论一下,一面自己忘记。
先上代码吧

package test;

import edu.princeton.cs.algs4.StdOut;

class Cycle{
    public int x = 1;
    static void ride(Cycle c){
        System.out.println("" + c);
        System.out.println("the number is :" + c.wheels());
    }
    public int wheels(){
        return this.x;
    }
}

class Unicycle extends Cycle{
    public int x = 2;
    public void f(){
        StdOut.println(x);
    }
}

class Bicycle extends Cycle{
    public int x = 3;
}

class Tricycle extends Cycle{
    public int x = 4;
}

public class test {
    public static void main(String[] args){
        Unicycle uc = new Unicycle();
        Bicycle bc = new Bicycle();
        Tricycle tc = new Tricycle();
        Cycle.ride(uc);
        Cycle.ride(tc);
        Bicycle.ride(bc);
        uc.f();
    }
}

下面是输出结果

test.Unicycle@15db9742
the number is :1
test.Tricycle@6d06d69c
the number is :1
test.Bicycle@7852e922
the number is :1
2

问题是这样的:

三个子类都继承于Cycle父类,并且覆盖了父类的成员变量x,但是在通过子类对象来调用父类方法的时候,方法中使用的依然是父类自己的成员变量(如上输出的number都是父类的1).于是就想是不是因为成员变量没有覆盖父类的成员变量。于是写了一个子类方法输出了一下,发现成员变量覆盖成功。那么问题是什么呢?或者说,我要如何才能通过多态来调用子类成员变量,而不用重写一遍父类方法?(有点绕,看输出就明白了,我想通过父类的wheels来调用子类的x变量。)

我的理解:

我自己在查了一些别人的问题与解决,发先一些原理。

  • 第一 子类在继承父类的过程中,会把父类的所有方法与成员变量都Copy一边,放在自己的super域(可以通过super关键字主动访问,private不能访问),在子类调用一个方法的时候,会先在自己的this域内搜索是否含有该方法,没有发现,就会向上转型,到super域进行访问,找到该方法后便开始执行,在执行的过程中因为就近原则(看网友这么说的,不知道这个就近原则准不准确),方法中调用的成员变量会是父类的成员变量,于是才会有我现在的结果。

  • 第二 也是别人总结的一个规律“成员变量的调用与调用的引用类型严格一致”即这个成员变量的调用与调用时所用的引用类型一致,下面有一个例子,大家一看一看就明白

class Base2 {
  int i = 1;
  String s = "Base";
}

class Child2 extends Base2 {
  int i = 9;
  String s = "Child";
  public static void main(String[] args) {
    Child2 c1 = new Child2();
    Base2 c2 = new Child2();
    System.out.println(c1.i);
    System.out.println(c1.s);
    System.out.println(c2.i);
    System.out.println(c2.s);
  }
}

以下是输出结果:

9
Child
1
Base

也许在后面学习了其他机制以后就知道怎么做了吧,我隐约记得有个Class类型,支持向下转型。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章