试图理解Java中的继承

时间:2018-04-29 15:05:45

标签: java inheritance subclass superclass

我觉得我对Java中的继承有一个很好的理解,但我正在努力解决以下问题:

public class SuperClass {

    private String name;
    private int age;

    public SuperClass(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void sharedMethod() {
        System.out.println("I'm a shared method in the SuperClass");
    }

}


public class SubClass extends SuperClass {

    public SubClass(String name, int age) {
        super(name, age);
    }

    public void sharedMethod() {
        System.out.println("I'm a shared method in the SubClass");
    }

    public void subMethod() {
        System.out.println("I'm subMethod");
    }

}


public class Main {

    public static void main(String args[]) {

        SuperClass test = new SubClass("Laura", 30);

        test.sharedMethod();

        test.subMethod(); // causes an error
    }
}

在使用SuperClass test = new SubClass("Laura", 30);时,我主要是在努力了解这里实际创建的内容(只有在SubClass扩展SuperClass时似乎才有效 - 如果没有强制转换,该怎么办? ?)。

我不理解它的原因是因为我可以调用sharedMethod来打印SubClass方法中的文字(因此大概SubClass会覆盖SuperClass 1}}此方法中的方法),但我无法从subMethod调用SubClass。对不起,如果我没有表达清楚,我似乎无法理解所引用的内容,可以使用的方法,为什么要这样做,为什么SubClass如果方法是共享的,则覆盖方法,但不能以其他方式调用。

2 个答案:

答案 0 :(得分:2)

SuperClass test = new SubClass("Laura", 30),您可以创建SubClass个实例,但可以SuperClass引用它。

在编译阶段,编译器发现SuperClass没有方法subMethod,因此会出现编译错误。

在运行时,JVM发现test实际上是SubClass,因此来自sharedMethod的{​​{1}}:

SubClass

将被执行。

答案 1 :(得分:1)

让我们说你告诉别人你有一辆车:

class Vehicle {

  public void drive() {
    System.out.println("Driving vehicle");
  }
}

这意味着,你告诉的人知道你有能力驾驶......但是,你有一辆摩托车:

class Motorcycle extends Vehicle {

  public void wheely() {
    System.out.println("Doing a wheely");
  }

  public void drive() {
    System.out.println("Driving motorcycle");
  }
}

哪个可以drive(),因为它是Vehicle,也可以wheely()。但是,你从未告诉过他们你所拥有的汽车类型是摩托车。因此,他们知道你能做的最多就是开车。

此人拥有的知识水平与对象参考类似:

Vehicle vehicle = new Motorcycle();

Vehicle引用仅知道您是Vehicle。它并不重要"如何"你开车,它只知道你知道怎么开车。因此,当您致电drive()时,它会驱动Motorcycle驾驶(被覆盖的方法)的方式,但您仍在驾驶。

但是,如果你更具特异性并告诉别人你拥有的车辆类型是摩托车,那么你就会向他们提供有关你车辆功能的更多信息。

Motorcycle motorcycle = new Motorcycle();

你知道,因为它是Vehicle,它仍然可以完成车辆可以做的所有事情drive()。但是,既然您现在已经引用了子类,那么您可以更多地了解它可以做什么 - wheely()

编译器不能进行假设,因此如果你创建一个LESS特定的引用Vehicle v(一个超类),编译器将只访问它知道它有权访问的那个对象的元素。如果你做了一个更具体的引用(一个子类),那么你告诉编译器更多关于该对象可以做什么。