2015-11-08 3 views
3

Это простой вопрос о том, как следует использовать наследование.Наследование: использование базового класса или производного класса для работы

Учтите, что я должен предоставить бизнес-логику для печати «foo» и «bar», и у меня есть иерархия из двух классов: одна, у которой есть метод для печати только «foo», а другой, который распространяется первым и имеет метод для печати ' бар'. В обоих классах у меня есть метод с именем necessaryMethod(), который берет на себя ответственность за вызов тех методов, которые печатают «foo» и «bar».

Как я реализовал ее в двух подходах:

Первый подход пусть базовый класс делать некоторые вещи и производный класс воспользоваться этим. Второй подход позволяет базовому классу не делать каких-либо вещей (только обеспечивая реализацию) и нести всю ответственность за производный класс.

Рассмотрим следующий код:

подход 1:

public class A{ 

    protected void necessaryMethod(){ 
     callFoo(); 
    } 

    protected void callFoo(){ 
     System.out.pritln("foo"); 
    }  
} 

public class B extends A{ 

    @Override 
    protected void necessaryMethod(){ 
     super.necessaryMethod(); 
     callBar(); 
    } 

    protected void callBar(){ 
     System.out.println("bar"); 
    } 
} 

public class FooBarClass{ 
    public static void main(String args[]){ 
     B b = new B(); 
     b.necessaryMethod(); 
    } 
} 

подход 2:

public abstract class A{ 

    protected abstract void necessaryMethod(); 

    protected void callFoo(){ 
     System.out.pritln("foo"); 
    }  
} 

public class B extends A{ 

    @Override 
    protected void necessaryMethod(){ 
     calFoo(); 
     callBar(); 
    } 

    protected void callBar(){ 
     System.out.println("bar"); 
    } 
} 

public class FooBarClass{ 
    public static void main(String args[]){ 
     B b = new B(); 
     b.necessaryMethod(); 
    } 
} 

Какой подход был бы хорош для ремонтопригодности и читаемость кода (в контексте крупных программных продуктов/иерархии большого класса, это это просто пример)?

(Это общий вопрос программирования. Я не просил мнение.)

+1

Этот вопрос будет более уместным на http://codereview.stackexchange.com/. – jaco0646

+0

@ jaco0646 Как перенести вопрос? –

ответ

1

Если вы хотите использовать производные классы, но маскируют их в качестве базовых классов, базовый класс должен иметь все функции производного класса (потому что вы говорите объекту «думать», что это А, и забываете, что это B). Поэтому, на мой взгляд, лучший подход:

public abstract class A{ 
    protected abstract void callBar(); 
    protected abstract void callFooBar(); 
    protected void callFoo() { 
     System.out.pritln("foo"); 
    } 
} 

public class B extends A { 
@Override 
    protected void callBar(){ 
    System.out.println("bar") 
    } 
@Override 
    protected void callFooBar(){ 
    callFoo(); 
    callBar(); 
    } 
} 

А потом называют В как например:

A b = new B(); 
b.callFooBar(); 

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

2

Откажитесь от технического аспекта программирования на мгновение, как что-то ведет (его методы) помогает определить его. т. е. собака лает().

Общий вопрос:

  1. поведение callFoo() заставляет вас думать о 'А' (класс А), или 'B' ли?

1.1. организовать методы (поведения) в классах, которые они будут принадлежать вне программирования, - в определении класса.

Большие Кодовые Основы

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

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

Вопрос в этом контексте: помогает ли это наследование организовать код? Помогло бы оно другому программисту?

Абстрактные классы

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

+0

+1 для обсуждения обязанностей, а не технических ограничений реализации. Может быть полезно обратиться к GRASP: https://en.wikipedia.org/wiki/GRASP_(object-oriented_design) – Guillaume

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