Философия Java

         

Забывание типа объекта


Это выражение может показаться странным для Вас. Почему кто-то должен намеренно забыть тип объекта? А это происходит, когда, Вы производите приведение к базовому типу, и выглядит это более прямо если бы tune( ) просто брала ссылку на Wind в качестве аргумента. Тем самым приносится еще одна неотъемлемая часть полиморфизма: Если бы Вы сделали так, как написано выше, то Вам было бы необходимо писать новый метод tune( ) для каждого типа Instrument в вашей системе. Допустим, мы последовали этой технике и добавили инструменты Stringed и Brass:

//: c07:music2:Music2.java

// Перегрузка, вместо приведедния к базовому типу.

class Note { private int value; private Note(int val) { value = val; } public static final Note MIDDLE_C = new Note(0), C_SHARP = new Note(1), B_FLAT = new Note(2); } // И т.д.

class Instrument { public void play(Note n) { System.out.println("Instrument.play()"); } }

class Wind extends Instrument { public void play(Note n) { System.out.println("Wind.play()"); } }

class Stringed extends Instrument { public void play(Note n) { System.out.println("Stringed.play()"); } }

class Brass extends Instrument { public void play(Note n) { System.out.println("Brass.play()"); } }

public class Music2 { public static void tune(Wind i) { i.play(Note.MIDDLE_C); } public static void tune(Stringed i) { i.play(Note.MIDDLE_C); } public static void tune(Brass i) { i.play(Note.MIDDLE_C); } public static void main(String[] args) { Wind flute = new Wind(); Stringed violin = new Stringed(); Brass frenchHorn = new Brass(); tune(flute); // Не приведение к базовому типу

tune(violin); tune(frenchHorn); } } ///:~

Ура, работает, но при этом возникает большая работа по переписки кода: Вы должны писать типо-зависимые методы, для каждого нового класса Instrument, которые Вы добавите. А это означает, что во-первых нужно больше программировать, во-вторых, если Вы захотите добавить новый метод по типу tune( ) или просто новый тип инструмента, то придется проделать много работы. К этому следует добавить, что компилятор не сообщит о том, что Вы забыли перегрузить некоторые методы или о том, что некоторые методы работают с неуправляемыми типами.

А не было бы намного лучше, если бы Вы написали один метод, который получает в качестве аргумента базовый класс, а не каждый по отдельности дочерний класс? Было бы, но не было бы хорошо, если бы Вы смогли забыть, что есть какие-то дочерние классы и написали бы ваш код только для базового класса?

Именно это полиморфизм и позволяет делать. Но все равно, многие программисты пришедшие из процедурного программирования имеют небольшие проблемы при работе с полиморфизмом.



Содержание раздела