2015-06-29 2 views
0

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

Итак, мой вопрос заключается в том, как заставить клиента быть осведомленным о самоиспользовании. Если мы упоминаем его в явном виде в Javadocs вроде этого:

/** 
* This class is self-use, thus it cannot be inherited. 
*/ 

Или мы должны даже отказаться от соблазна self-use.

Образец кода: Следует ли документировать класс, как описано выше, или мы должны избегать такого самообслуживания?

public class MyClass{ 

    public void overrideMe(){ 
     //something 
     ovMe(); 
    } 

    public void ovMe(){ 
     //some staff 
    } 
} 
+5

Если вы не хотите, чтобы метод был переопределен, не просто дайте небольшую подсказку в виде ключевого слова в комментариях. Соберите его с помощью 'final'. – tilois

+0

@ St.Antario Не у всех есть копия * Эффективной Java * с ними везде, куда бы они ни пошли. Просьба привести соответствующие абзацы и любые образцы кода, которые их сопровождают. – CKing

+0

Это пункт 17, «Дизайн и документ для наследования или его запрет» – tilois

ответ

5

Как вы заявили, самообслуживание - это когда один переопределяемый метод вызывает другой переопределяемый метод. Например, когда AbstractList.addAll звонит AbstractList.add.

Важно убедиться, что кто-то, кто расширяет класс, это знает. Представьте, что вы писали новую реализацию списка на основе AbstractList - вам нужно знать, нужно ли переопределять как addAll, так и add, или вам нужно только переопределить add.

Самостоятельное использование. Что говорит Джошуа Блох, так это то, что , если вы его используете, вы должны убедиться, что кто-то, кто расширяет класс, знает об этом.

Есть несколько способов, чтобы удовлетворить эту рекомендацию:

  • Вы могли бы просто избежать собственного использования.
  • Вы можете использовать один из методов final, поэтому его нельзя переопределить.
  • Вы можете сделать класс final, поэтому его нельзя продлить.
  • Вы можете описать шаблоны самопотребления класса в своем комментарии Javadoc (отвечающем требованию дать другим знать).

Кроме того, чтобы избежать возможной путаницы, отметим, что Java сам язык не заботится о шаблонах самостоятельного использования. Также не компилятор, JVM или какой-либо другой программный продукт. Эта рекомендация предназначена исключительно для помощи программистам, которые могут работать с вашим кодом (включая вас, через 6 месяцев).

+0

Не могли бы мы объединить некоторые из этих способов вместе? Например, документирование и объявление окончательного. –

+0

@ St.Antario Ну, если ваш класс или метод является окончательным, тогда у вас нет возможности переопределить ваш метод, поэтому у них нет причин заботиться о самообслуживании. – immibis

+0

@ St.Antario Именно поэтому я попросил вас привести соответствующие разделы из книги. Ваш вопрос был вне контекста. Особенно это заявление * Он описал так называемый самопользовательский шаблон, который, насколько я сказал, что мы не должны использовать переопределяемые методы в других переопределяемых методах *, было высказано из контекста, поскольку методы «overidable» не могут быть окончательными. – CKing

1

Может быть, вы можете использовать final для метода или класса.

+0

* Он описал так называемый самопомощь, который, насколько я уже сказал, не должен использовать переопределяемые методы в других переопределяемых методах *. С каких это пор методы 'final' становятся сверхъестественными? – CKing

1

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

/** * Этот класс является само- поэтому его нельзя унаследовать. */

Единственный способом, которым вы можете запретить программист из не overriding метода overridable (не окончательный) является пометка класса как final и предотвратить его получение по наследству.

public final class MyClass{ 

    public void overrideMe(){ 
     //something 
     ovMe(); 
    } 

    public void ovMe(){ 
     //some staff 
    } 
} 

Если пометить метод как final, он больше не overridable поэтому он не соответствует описанию, которую вы предоставили в вашем quesiton.

1

Ваш класс должен быть final класс.

Например, вы можете следить за классом String, где вы не можете переопределить какой-либо метод.

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