Попытка понять наследование в Java - PullRequest
0 голосов
/ 29 апреля 2018

Я чувствую, что у меня хорошее понимание наследования в 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 в этом случае), но пока я не могу назвать subMethod из SubClass вообще. Извините, если я не очень хорошо сформулировал это, я просто не могу обернуться, что на что ссылаются, какие методы можно использовать, почему вы это делаете, почему SubClass переопределяет метод, если метод является общим, но не может быть вызван иначе.

Ответы [ 2 ]

0 голосов
/ 29 апреля 2018

Скажем, у вас есть, вы сказали кому-то, что у вас был автомобиль:

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().

Компилятор не может делать предположения, поэтому, если вы сделаете ссылку Vehicle v, которая специфична для МЕНЬШЕ (суперкласс), компилятор получит доступ только к элементам этого объекта, к которому он ЗНАЕТ, что он наверняка имеет к ним доступ. Если вы сделаете более конкретную ссылку (подкласс), то вы расскажете компилятору больше о том, что может делать этот объект.

0 голосов
/ 29 апреля 2018

К SuperClass test = new SubClass("Laura", 30) вы создаете экземпляр SubClass, но ссылаетесь на него по SuperClass.

На этапе компиляции компилятор обнаружил, что SuperClass не имеет метода subMethod, поэтому вы получаете ошибку компиляции.

Во время выполнения JVM обнаружила, что test на самом деле SubClass, поэтому sharedMethod из SubClass:

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

будет выполнено.

...