Это в порядке, чтобы иметь 'пустой' класс, который расширяет другой класс?

9
задан SCdF 27 September 2008 в 06:06
поделиться

10 ответов

По-моему, это является лучшим если Foo и Bar подкласс от класса общего предка (возможно, AbstractFoo), который имеет всю функциональность. Между чем должно существовать различие в поведении Foo и Bar? Кодируйте то различие как абстрактный метод в AbstractFoo, не при помощи a if оператор в Вашем коде.

Пример: Вместо этого:

if (foo instanceof Bar) {
    // Do Bar-specific things
}

Сделайте это вместо этого:

class Bar extends AbstractFoo {
    public void specialOp() {
        // Do Bar-specific things
    }
}

// ...
foo.specialOp();

Преимущество этого подхода - то, что, если Вам нужен третий класс, это во многом как Foo но имеет просто определенное различие, Вы не должны пройти весь свой код и добавить, редактируют весь if операторы.:-)

14
ответ дан 4 December 2019 в 10:06
поделиться

Все это зависит от значения классов Нечто и Панели. Что они представляют, и что является их целью. Разъяснитесь.

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

3
ответ дан 4 December 2019 в 10:06
поделиться

Если существует вероятность это Foo и Bar мог когда-нибудь отличаться в реализации, затем на Ваш вопрос отвечают - наследование использования любым способом кажется лучшим.

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

И с тем сделанным классом, вместо того, чтобы дать ему булево свойство как isFoo, было бы намного лучше бросить другой взгляд на то, почему необходимо дифференцировать Нечто от Панели. Что о Foos заставляет Вас обработать их по-другому, чем Панели? Поймите это и сделайте свойство, которое указывает информацию, которая отличается. Действительно ли Foos больше? Затем сделайте свойство для размера (даже если это - перечисление со значениями, "размера нечто" и "размера панели").

Это - приблизительно столько же, сколько можно сказать без определенных примеров того, каковы Foo и Bar могли бы быть.

1
ответ дан 4 December 2019 в 10:06
поделиться

Нечто и Панель наследовались FooBarImplementation

Я сделал бы класс FooBarImplementation, который реализует типичные опции Foo и Панели. Foo и Панель произошли бы из него. Но в Вашем коде, никогда не используйте тип FooBarImplementation. Мои дни Java находятся несколько позади меня, но я предполагаю, что должен быть некоторый способ для сокрытия FooBarImplementation от пользовательского кода (делающий, он защитил, или пакет, видимый только, в зависимости от организации проекта. Таким образом, никакой пользовательский код не смешает Foo для Панели (и наоборот)?

class FooBarImplementation
{
   public void doSomething() { /* etc. */ }
   /* etc. */
}

class Foo inherits FooBarImplementation { /* etc. */ }
class Bar inherits FooBarImplementation { /* etc. */ }

Нечто и Панель составлены с FooBarImplementation

Другая возможность состояла бы в том, чтобы заставить Foo и Bar передать каждый из их методов к внутреннему классу (снова, FooBarImplementation). Таким образом, нет никакого способа, которым пользовательским кодом мог быть Foo и Панель.

class FooBarImplementation
{
   public void doSomething() { /* etc. */ }
   /* etc. */
}

class Foo
{
   private FooBarImplementation fooBarImplementation = new FooBarImplementation() ;

   public void doSomething() { this.fooBarImplementation.doSomething() ; }
   /* etc. */
}


class Bar
{
   private FooBarImplementation fooBarImplementation = new FooBarImplementation() ;

   public void doSomething() { this.fooBarImplementation.doSomething() ; }
   /* etc. */
}

Не делайте Foo, наследовался Панели (или наоборот)

Shoudl Foo наследовался Сараю, Foo была бы Панель, что касается языка. Не делайте этого, Вы потеряете различие между объектами, и это - то, что Вы не хотите.

Не используйте булевскую переменную, и безотносительно поля типа

Это - худшая идея, через которую Вы могли приехать. Bjarne Stroustrup предостерег от этого вида антишаблона для C++, и C++ не все об ООП. Таким образом, я предполагаю, что этот шаблон еще более "анти-" для Java... :-)

2
ответ дан 4 December 2019 в 10:06
поделиться

В основном необходимо применить Стратегическую модель.

1
ответ дан 4 December 2019 в 10:06
поделиться

Определенно используйте булево свойство. Это - простое решение, если Вы не предвидите класс Панели, бывший должный измениться, это - интерфейс позже (например, переопределение, это - методы).

0
ответ дан 4 December 2019 в 10:06
поделиться

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

0
ответ дан 4 December 2019 в 10:06
поделиться

Ваши данные не были достаточно ясны, но на основе того, что я думаю, что Вам нужно, я озадачен, почему Вы просто не идете с 4-й опцией:

Class MainStuff;
Class TypeA;
Class TypeB;

Нет или сделайте TypeA, и B наследовались MainStuff или делают MainStuff элементом данных TypeA и TypeB. Это зависит от значения того, каковы эти 3 класса.

0
ответ дан 4 December 2019 в 10:06
поделиться

Как другие сказали, это зависит, но если у Вас есть общая функциональность между Foo и Bar, и различие в функциональности может быть выражено как параметры, затем я голосую за подклассы. Это было в основном, что мы делали в конце практического курса программного обеспечения.

Мы должны реализовать игру судоку, и в конце, у нас был "AbstractPlayfield", который смог применить произвольный подшипник к произвольному playfield. Этот AbstractPlayfield был разделен на подклассы отдельными вариантами, которые мы, как предполагалось, реализовали. Те подклассы устанавливают параметры (главным образом правила и форма платы) для краткого обзора playfield, и все работало как очарование. Мы даже закончили с большим количеством наследования в тех подклассах, потому что несколько из вариантов содержали правила "Числа, должно быть уникальным подряд", и "Числа должны быть уникальными в столбце".
Используя это, мы смогли закончить работу, которая была оценена для приблизительно 2-месячного приблизительно за 3 дня :) (И они раздражали нас из-за "Теста те крошечные устанавливающие атрибут классы, потому что у Вас могли бы быть ошибки там! Протестируйте их! Протестируйте их! Мы не заботимся, что вся важная логика тестируется!".)

С другой стороны, если класс Панель не имеет никакой специальной другой функциональности от Панели, я не вижу точку добавления его - по крайней мере, от данных, которые Вы даете мне. Это могло бы иметь смысл, если бы Вы хотели сделать некоторые операции на основе типов и диспетчеризировать на типе, но я не могу считать это от Foo и Панели. В этом случае я не создал бы Панель, из-за YAGNI.

0
ответ дан 4 December 2019 в 10:06
поделиться

Если нет никакого поведенческого различия между Foo и Панелью, то имя класса "Нечто" не достаточно абстрактно. Определите общую абстракцию между Foo и Bar и переименуйте класс соответственно. Затем обеспечьте членское поле в классе для идентификации экземпляров как "Нечто", "Панель", и т.д. Используйте перечисление, если Вы хотите ограничить возможные значения "Нечто" и "Панелью".

0
ответ дан 4 December 2019 в 10:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: