Что значит Base b2 = new Child ();означает? - PullRequest
4 голосов
/ 15 декабря 2010
 class Base {

    public void add() {
        System.out.println("Base ADD");
    }

    void subtract() {
        throw new UnsupportedOperationException("Not yet implemented");
    }

}

class Child extends Base {

    public void add(){
        System.out.println("Child ADD");
    }

    public void subtract() {
        System.out.println("Child Subtract");
    }

}

class MainClass {

    public static void main(String args[]) {

        Base b1 = new Base();
        Base b2 = new Child();

        Child b3 = new Child();

        b1.add();

        b2.subtract();  

        b2.add();
        b3.subtract();

    }

}

Я несколько запутался с приведенным выше кодом.Больше всего меня смущает строка

Base b2 = new Child();

и

 b2.subtract();

Я понимаю, что во время компиляции компилятор проверяет погоду Base в классе есть метод subtract() или нет, затем во время выполненияполиморфизм во время выполнения происходит, когда объект имеет тип Child.

Вопрос в том, как или где мы можем использовать эту строку, т.е. Base b2 = new Child();

В каком сценарии мы должны использовать это?Пожалуйста, помогите, было бы здорово!

Ответы [ 2 ]

10 голосов
/ 15 декабря 2010

Посмотрите на две части инструкции:

Base b2

, которая объявляет переменную с именем b2 типа Base.Вы можете назначить ссылку на эту переменную, если ссылка имеет значение null или ссылается на экземпляр Base или подкласс Base.

Тогда

new Child()

создает новый экземплярChild.Child является подклассом Base, поэтому вы можете присвоить ссылку, возвращаемую конструктором, переменной b2.

Теперь вы можете «видеть» только элементы с Base по b2, хотя фактическое значение относится к экземпляру Child во время выполнения.Но любые методы из Base, которые были переопределены в Child, будут использовать переопределенную версию при вызове ... поэтому, когда вы вызываете

b2.subtract();

, JVM находитиз фактического типа объекта, на который ссылается b2, и использует реализацию этого класса subtract - в этом случае метод, который печатает «Child Subtract».

EDIT: Вы специально спросили, где вы можете использовать такие вещи и как это помогает ...

Вы можете использовать его в любое время, когда захотите объявить переменную более общего типа (суперкласс илиинтерфейс), но присвойте ему значение, которое является подклассом или реализацией интерфейса.В качестве другого примера:

List<String> strings = new ArrayList<String>();

Основным преимуществом объявления переменной обычным способом является то, что вы сохраняете гибкость - позже вы можете перейти от использования ArrayList<T> к другой реализации List<T>и код все еще должен работать.Вы в основном говорите: «Мне нужны только члены и гарантии, предоставляемые List<T> - тот факт, что я использую ArrayList<T>, несколько случайен».

Подобный пример - решение, какой тип методадолжен возвращаться - часто вы хотите объявить, что вы возвращаете общий тип (или интерфейс), даже если реализация знает, какой конкретный тип он возвращает.Это скрывает детали реализации, что позволяет изменить их позже.

1 голос
/ 15 декабря 2010
Base b2 = new Child(); 

Вы можете использовать Reference of Super для объекта child.

для b2.method ();

во время компиляции у вас должен быть метод (); в BaseClass.

Во время выполнения будет вызван метод Object, поэтому здесь object is Child из Base b2 = new Child();

Итак, детская method() версия будет выполнена.

Использование:

Полиморфизм чрезвычайно полезен при проектировании систем уровня предприятия, поскольку вы можете создавать и определять несколько уровней интерфейса, которые позволяют сторонним или внешним программным средствам взаимодействовать с вашей системой определенным образом. Мы все знаем, насколько полезно в системной интеграции иметь опубликованный API, но если внутренние изменения в системе становятся необходимыми, возможно, придется переиздать API, а интегрированные системы, возможно, придется переработать. Чтобы избежать этого, при проектировании следует уделить особое внимание объектным API, а также общим системным API. Один из способов гарантировать, что надежная система может работать с объектами, которые имеют более сложные методологии, чем предполагалось изначально, состоит в том, чтобы объектный API был полиморфным. Таким образом, система знает «лицо» объекта, передаваемого ей, но ей не нужно знать о мгновенных изменениях.

Также см.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...