2013-11-13 1 views
1

Ну, надеюсь, вы меня понимаете. У меня есть два класса: A и B. B является подклассом A. Они имеют одни и те же общедоступные методы и означают одно и то же, но B делает некоторые вещи немного разными, поэтому у него есть дополнительные методы и атрибуты, которые используют только сам. Скажем, класс А реализует метод newFromWizard, который интерактивно создает объект. Могу ли я реализовать логику, в зависимости от пользовательского ввода, создать объект A или или объект B в методе newFromWizard A. Я имею в виду, могу ли я создать объект B из этого метода A? Или мне нужно реализовать это в другом месте? Как это лучший способ сделать это? На практике я могу. Но это правильно для ООП?Правильно ли возвращать объект, класс которого не является ожидаемым классом?

Кстати, если это имеет значение, я использую Smalltalk.

+0

Это немного бит нарушения ООП (почему родительский класс знает о своих детях?), но в основном я бы сказал, что не делайте этого для удобочитаемости и предсказуемости. Используйте статический заводский метод (или эквивалент Smalltalk). –

+0

@ChrisHayes on, родитель знает о подклассах. Вы просто выполняете «Object allSubclasses» и получаете все подклассы в системе.Также как класс отвечает за создание подкласса, все в порядке, что он знает о подклассах – Uko

ответ

0

Я бы сказал, что это не интуитивный способ делать вещи. Давайте упростим это и скажем, что вы просто переопределяете new. Затем в какой-то момент вы делаете A new и получаете экземпляр B. То, что они похожи, делает это не так уж плохо. Но представьте, что кто-то еще начинает работать с вашим кодом. И hew знает, что сообщение new должно привести к созданию экземпляра приемника. И тогда что-то по-другому. Я бы сказал, что концептуально это неправильно. Почему теперь для реализации какого-то класса строителя? И есть что-то вроде

createInstanceOfAB 
    |className| 
    className := "do what you need". 
^className asClass new. 

Это более четкий способ.

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

1
public class A{ 

    public B method(){ 
     B b = new B(); 
     return b; 
    } 
} 

class B extends A{ 

} 

Если это то, о чем вы говорите, это действительно.

+0

ОК. Но я хочу убедиться. Это верно, потому что это правильно, или просто потому, что вы можете это сделать? Это не плохая практика? – sanfilippopablo

+0

Это действительно зависит от вашей ситуации и того, что вы пытаетесь выполнить. Если это единственный способ выполнить вашу задачу, сделайте это. Но трудно сказать, не понимая точного контекста вопроса –

2

Да, это хорошо известный образец в OO. В библиотеках Cocoa Objective-C вы обнаружите, что он применяется систематически и известен как кластер классов. В результате библиотеки Cocoa намного легче понять, чем эквивалентные C# или java. Это позволяет скрывать иерархию наследования за абстрактным классом, который имеет методы создания класса, которые возвращают подклассы.

0

Я думаю, вам не стоит слишком беспокоиться о том, является ли это «чистой OO», чтобы вернуть экземпляр подкласса. Он используется и делается так часто, потому что он очень полезен и делает ваш код очень удобочитаемым по сравнению с собственными фабриками и т. Д.

Мое самое большое беспокойство здесь заключается в том, что вы должны называть свой метод класса тщательно. Не использовать #new, вероятно, самое важное правило, но вы всегда должны использовать имя, которое уже сказано: дайте мне пример того, что подходит прямо сейчас.

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

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