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

Я прочитал много блогов, руководств и т. Д., Но я ничего не понимаю о динамической привязке в java. Когда я создаю объект под названием «myspecialcar», он создает объект из класса «автомобиль» как тип транспортного средства класса в качестве динамической привязки, верно? Итак, java знает, что когда я выполняю метод myspecialcar.getType(), у меня есть объект автомобиля, и он выполняет метод из класса car. Но почему я получил тип от автомобиля класса? Это потому, что переменная из класса транспортного средства (тип) является статической привязкой?

С уважением,

Код:

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

person CLNRMN    schedule 09.08.2017    source источник
comment
Ознакомьтесь с соглашениями об именах. Это помогает другим разработчикам читать ваш код.   -  person Silk0vsky    schedule 09.08.2017


Ответы (4)


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

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

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

person Adeel    schedule 09.08.2017
comment
Спасибо, но у меня есть еще один вопрос. Я просто думал, что транспортное средство — это мой суперкласс, так почему я скрываю переменную-член своего подкласса? Или автомобиль теперь является суперклассом, потому что я использовал Vehicle mySpecialCar = new Car()? - person CLNRMN; 09.08.2017
comment
Ты выглядишь очень растерянным. Посмотрите, что вы сделали, это законно, но не рекомендуется, как брак с двоюродным братом :). Вызов поля с использованием родительской ссылки вызовет поле родителя, а не дочерний объект, но для метода это противоположно. - person Adeel; 09.08.2017
comment
Да, я запутался :-) спасибо за вашу помощь, и это не рекомендуется. (это был пример учебника...) - person CLNRMN; 09.08.2017

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

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

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

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

person Yusuf Kapasi    schedule 09.08.2017
comment
Это на самом деле заставило меня понять это спустя долгое время. Большое спасибо! - person Brosch; 14.02.2020

Вы столкнулись с скрытием полей.

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

person Silk0vsky    schedule 09.08.2017

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

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

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

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

Car myCar = new Car()

ты получишь

myCar.type // car
myCar.super.type // vehicle
person Murat Karagöz    schedule 09.08.2017