2014-10-21 4 views
1

У меня есть класс A, расширяющий класс B. Мой класс B имеет 5 абстрактных методов. Во всех этих 5 методах мне нужно сделать один вызов каждому методу A(). Проблема заключается в том, что, поскольку мне нужно создать вокруг, скажем, 40 классов, которые расширяют класс B, мне нужно написать одинаковые вызовы метода А, 5 раз в классе и во всех этих 40 классах. SO Я в конечном итоге пишу звонки методу А, около 200 раз.Дизайн классов - Избегание избыточного кода

Теперь, как я могу создать такое, чтобы мне не нужно было делать эти вызовы на уровне дочернего класса?

Пример ниже

Methoda здесь является метод, который регистрирует действия пользователя в базе данных. Итак, каждый раз, когда я создаю класс, расширяющий класс B, во всех 5 абстрактных методах мне нужно вызвать методA, который регистрирует действие пользователя в базе данных.

Благодаря

+2

Не могли бы вы привести конкретный пример проблемы? –

+0

Класс a расширяет класс b – Manish

+0

@TedHopp, я отредактировал вопрос, чтобы было легче понять. Дайте мне знать, если вам нужна какая-либо информация – Manish

ответ

4

Вы можете использовать шаблон, как это:

abstract public class B { 
    /** Override to implement the subclass logic */ 
    abstract protected SomeClass reallyCalculateStuff(); 

    /** The public API method to be called by clients of the class */ 
    final public SomeClass calculateStuff() { 
     executeSharedCode(); 
     return reallyCalculateStuff(); 
    } 

    /** The method all other methods need to call */ 
    private void executeSharedCode() { 
     // ... 
    } 
} 

public class A extends B { 
    @Override 
    protected SomeClass reallyCalculateStuff() { 
     // ... 
    } 
} 

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

Это также будет работать, если executeSharedCode должно быть реализовано по-разному в каждом подклассе. Просто сделайте это abstract.

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

+0

Спасибо Ingo. Я сделал что-то подобное, как раньше, похожее на шаблон шаблона. Небольшая проблема заключается в том, что у меня есть 10 методов в моем классе B с 5 как абстрактный метод и 5 как не абстрактный метод. – Manish

+0

@Manish Я не вижу проблемы с этим. Можете ли вы уточнить? Возможно, стоит добавить фактический (вырезанный) пример к исходному сообщению. –

+0

@Manish Если вы хотите сказать, что вы не хотите, чтобы подкласс реализовывал все методы, но предоставлял «реализацию по умолчанию», просто используйте ту же идею, но вместо создания абстрактного метода «reallyXyz» вы реализовать его. Подкласс может затем переопределить его, но не обязательно. –

0

Если вы хотите, чтобы уменьшить код копирование, вы можете сделать методы в B неабстрактного и дать им тело методов. Это будет означать, что они больше не абстрактны, но поскольку все подклассы наследуют это поведение, вы все равно можете быть уверены, что все они смогут использовать этот метод. Таким образом, методы из B могут вызывать метод A(), даже если methodA определен в подклассах, и они также могут быть переопределены вашими подклассами, если им нужно уникальное поведение.

+0

Но мне нужно сделать все эти 5 методов абстрактными, поскольку я хочу, чтобы дочерний класс предоставлял свои собственные реализации. – Manish

+0

Если все реализации различны, и единственным общим элементом является вызов метода A(), тогда нет лучшего способа сделать это. Просто придерживайтесь метода callA() 200 раз. – DaaaahWhoosh

+0

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

0

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

Ваш родительский класс:

public class B { 
    public methodA() {} 
    public firstMethod() { 
     methodA(); 
    } 
} 

Ваша реализация:

public class A extends B { 
    public firstMethod() { 
     super.firstMethod(); 
     // method body 
    } 
} 

Итак, вы все равно должны вызвать super.firstMethod в вашей реализации, но, по крайней мере, таким образом, вы можете иметь более широкий по умолчанию чем один вызов метода.

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