Java: статическое и динамическое связывание (снова)

Я прочитал много блогов, учебных пособий и сотрудничества, но я не понимаю, что такое динамическое связывание в Java. Когда я создаю объект с именем "myspecialcar", он создает объект из класса "car" как тип транспортного средства класса как динамическое связывание, верно? Так что Java знает, что когда я выполняю метод myspecialcar.getType(), у меня есть объект car, и он выполняет метод из класса car. Но почему я получил тип от автомобиля класса? Это потому, что переменная из класса vehicle (тип) является статической привязкой?

С Уважением,

Код:

public class vehicle {
    String type = "vehicle";

    public String getType(){
        return type;
    }
}

public class car extends vehicle {
    String type = "car";

    public String getType(){
        return type;
    }
}

public class test {
    public static void main (String[] args){
        vehicle myvehicle = new vehicle(); // static binding
        car mycar = new car(); // static binding
        vehicle myspecialcar = new car(); //dynamic binding

        System.out.println(myspecialcar.getType());
        System.out.println(myspecialcar.type);
        System.out.println(myspecialcar.getClass());
    }
}

Выход:

car
vehicle
class car

4 ответа

Решение

Вы не переопределяете переменные класса в Java, вы их скрываете.

Переопределение, например, методы. Сокрытие отличается от переопределения.

В вашем случае вы скрываете переменную-член суперкласса. Но после создания объекта вы можете получить доступ к скрытому члену суперкласса.

Правило метода экземпляра

Когда метод экземпляра вызывается для объекта с использованием ссылки, класс текущего объекта, обозначенный ссылкой, а не тип ссылки, определяет, какая реализация метода будет выполнена.

Свойство экземпляра / Правило поля

Когда к полю объекта обращаются с использованием ссылки, именно тип ссылки, а не класс текущего объекта, обозначенный ссылкой, определяет, к какому полю будет фактически осуществляться доступ.

Вы столкнулись с полями, скрывающимися.

Внутри класса поле с тем же именем, что и поле в суперклассе, скрывает поле суперкласса, даже если их типы различны. Внутри подкласса на поле в суперклассе нельзя ссылаться по его простому имени. Вместо этого поле должно быть доступно через super, что рассматривается в следующем разделе. Вообще говоря, мы не рекомендуем скрывать поля, так как это затрудняет чтение кода.

Есть разница между hiding а также overriding, Вы не можете переопределить поля класса, а скорее методы класса. В вашем конкретном примере это означает, что

Vehicle mySpecialCar = new Car() // use upperCase and lowerUpperCase pls

У вас есть тип Vehicle который является примером Car, Переопределенные методы будут использоваться, пока поля класса будут скрыты.

Если вы используете

Car myCar = new Car()

ты получишь

myCar.type // car
myCar.super.type // vehicle
Другие вопросы по тегам