2015-08-19 2 views
-1

«Введение в Java программирование», говорит:Почему это хорошая практика для определения переменной с супертипом?

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

Пример кода:

Object myObject = new Circle(); 

... // Some lines of code 

System.out.println("The circle diameter is " + 
((Circle)myObject) .getDiameter()); 

... // Some lines of code 

Почему бы не определить MyObject как тип Circle в первую очередь?

+3

Пример вы предоставили, может быть хорошей практикой в ​​очень редких случаях. Для меня это ужасно. –

+0

Введение в программирование на Java звучит как ужасно плохая книга, или ОП понимает что-то неправильно. – Kayaman

+2

В большинстве случаев самый простой и понятный код лучше всего. Вероятно, пример, который они предоставляют, не является хорошим. –

ответ

2

Позволяет сделать простой пример с классом Fruit

public class Fruit { 
    public void eat() { 
     //some code 
    } 
} 

И два других класса

public class Banana extends Fruit{ 

} 
// 
public class Apple extends Fruit{ 

} 

Теперь давайте создать Person

public class Person { 
    public void eat(Fruit f) { 
     f.eat(); 
    } 
} 

Давайте использовать этот в настоящее время

public static void main(String[] args) { 
    Person p = new Person(); 
    // We are creating a random Fruit, and pass it to the person to eat. 
    // We can´t be more specific here and don´t need to be more specific 
    Fruit f = getRandomFruit(); 
    p.eat(f); 
} 

public static Fruit getRandomFruit() { 
    if(new Random().nextInt(2) == 0) { 
     return new Banana(); 
    } else { 
     return new Apple(); 
    } 
} 
1

Я думаю, что в этом случае этот пример приносит больше вреда, чем пользы. Чтобы выполнить какие-либо операции Circle или Shape, вам необходимо будет использовать текущий объект. Помимо добавления потенциальных накладных расходов, это может привести к таким проблемам, как несовместимые типы.

Обычно рекомендуется использовать универсальное программирование, так как оно позволяет вашему коду быть гибким. В отличие от примера, который вы опубликовали, рекомендуется только тогда, когда это сделано правильно. Создание всего как объекта почти всегда приносит больше вреда, чем пользы.

Принимая List в качестве примера, если вы где есть метод, который возвращает ArrayList<String> в результате: public ArrayList<String> foo(), то вы обязаны к этому конкретному типу. Если вам нужен связанный список, вам, вероятно, потребуется написать какой-то конвертер, который создает LinkedList<String> от ArrayList<String>.

С другой стороны, если вы используете общий интерфейс, ваш метод станет примерно таким: public List<String> foo(). Это позволит тем, кто когда-либо потребляет foo, чтобы иметь возможность создавать любую из структур данных, которые реализуют интерфейс List без необходимости прохождения обручей.

EDIT: Согласно вашему комментарию, большую часть времени это не помогает. Как я уже упоминал в своем ответе, это приносит больше вреда, чем пользы. Одним из примеров, когда работа с объектами имеет смысл, является метод readObject(), предоставляемый ObjectInputStream. Этот метод используется, когда вы читаете пользовательский объект, о котором ObjectInputStream не знает. Поскольку в Java все расширяет класс Object, этот метод дает объект. Даже тогда, каждая иллюстрация, которую я видел в этом методе, они в конце концов отбросили ее на что-то другое.

+0

** Как определить метод myObject как тип объекта в общем программировании? ** Можете ли вы привести случай, когда это делает актуальный смысл. – Saud

+0

@Saud: Как я и другие упоминали, объявили что-то как «Объект» делает больше вреда, чем пользы. Приведенный пример «List» должен дать что-то более практичное. Я обновил свой ответ с ситуацией, в которой Java API дает «Object», но даже тогда объект будет в конечном итоге применен к чему-то более конкретному. – npinti

1

Если вы модифицируем пример немного, путем получения Circle, Square, RectAngle из Shape вместо объекта, это будет здравый смысл.Shape может иметь такие методы, как getArea() и атрибуты, такие как высота и ширина, которые могут быть переопределены производными классами.

Shape circle = new Circle(); 
Shape rectangle = new Rectagle(); 

В примерах из реальной жизни, то лучше использовать общие типы базы для производных классов, так что реализация может изменяться во время выполнения.

Если вы ищете объекты, используйте простой Factory.

Если вы хотите изменить поведение объекта во время выполнения, используйте Strategy_pattern.

Если вы работаете над несколькими стратегиями для функции, стратегию можно заменить динамически, изменив базу на новую производную стратегию.

Посмотрите ниже примеры:

Design Patterns: Factory vs Factory method vs Abstract Factory

Real World Example of the Strategy Pattern

Смежные вопросы