2010-02-05 3 views
4

У меня есть Parent.java класс и 4 дочерних класса как Child1.java, Child2.java и так далее.Еще одна проблема в наследовании Java?

Есть два способа

  • m1()
  • м2()

и одно поле

  • f1

поле f1 имеет различные значения, основанные на дочернем классе.

Метод m1 имеет общую реализацию, так что я положил его в Parent.java класса. Он также ссылается на метод m2.

Метод м2 имеют общую implemtation, но это поле процесса f1 который различен для всех дочерних классов.

Так мои вопросы заключаются в следующем:

Q1. Должен ли я помещать поле f1 в родительский класс и пусть все дочерние классы наследуют их и инициализируют их в своих собственных конструкторах или я должен создать поле f1 для всех дочерних классов.

Q2. Поскольку метод m2 имеет общую реализацию, но поле процесса f1, которое не имеет одинакового значения для каждого дочернего класса, поэтому следует поместить его в родительский класс или дочерний класс.

Q3. Если я должен поместить метод m2 в родительский класс, существует одна проблема: метод m1 (который имеет общую реализацию) ссылается на метод m2, так что это создаст какие-либо проблемы?

ответ

3

Place m2 и f1 в родительском классе, если реализация m2 одинакова для всех классов. Если для каждого дочернего класса есть определенная часть, которую можно запустить после общей части - отделите ее и поместите в дочерние классы при вызове super.m2(). Установите f1 в конструкторе каждого дочернего класса.

Результат будет выглядеть примерно так:

public abstract class parent { 
    private int field = 0; 

    public parent(int f) { 
     field = f; 
    } 


    public void m1() { /* m1's implementation */ } 
    public void m2() { /* m2's common implementation */ } 
} 

public class child1 { 
    public child1() { 
     super(1); 
    } 

    @Override 
    public void m2() { super.m2() /* m2's child1 implementation */ } 
} 

public class child2 { 
    public child2() { 
     super(2); 
    } 

    @Override 
    public void m2() { super.m2() /* m2's child2 implementation */ } 
} 

Это позволит вам выдвинуть максимальное количество кода еще в иерархии, как это возможно. Меньшее дублирование кода.

Отредактировано для исправления попыток доступа к частному члену из дочернего класса. Изменен для его установки с помощью конструктора.

+0

+1 ........................................... :) –

+0

Будет лучше проинсталлировать поля непосредственно в дочерних классах или инициализировать их, передав значения в качестве параметра в вызове super() конструктору суперкласса. –

+2

Я бы пошел с передачей значений супер. –

3

На мой взгляд:

  1. f1 должна быть в родительском классе и инициализируется в детском конструкторе. Таким образом, методы get и set записываются только один раз.
  2. m2 должно быть в родительском классе.
  3. m1 также должен быть в родительском классе. Не забывайте, что вы также можете создавать методы abstract, если они не имеют общей реализации, но существуют во всех дочерних классах. Это позволит вам вызвать его из других методов в родительском классе, несмотря на то, что он не определен.Также имейте в виду, что родительский класс также должен быть абстрактным в этом случае.
+0

+1 ........................................... :) –

1

То, что вы пытаетесь сделать звук как метод шаблона дизайна шаблона: http://en.wikipedia.org/wiki/Template_method_pattern

Я предлагаю положить f1 в родительском классе и декларирование м2 абстрактного в родительском классе (который будет делать сам класс аннотацию).

+0

+1 для wiki link –

2

Из того, что вы описали, я не вижу никаких проблем с этой реализацией:

public class Parent { 
    private int f1; 

    public Parent(int f1) { 
     this.f1 = f1; 
    } 

    public void m1() { } 
    public void m2() { 
     // do something with f1 
     System.out.println(f1); 
    } 
} 


public class Child1 extends Parent { 

    private final int DEFAULT_FIELD_VALUE = 1; 

    public Child1() { 
     super(DEFAULT_FIELD_VALUE); 
    } 
} 

public class Child2 extends Parent { 
    public Child2(int value) { 
     super(value); 
    } 
} 

{...} 
+0

+1 ................................ :) –

0

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

public class Parent { 

    private Value f1; 

    private Parent(Value f1) { 
     this.f1 = f1; 
    } 

    public static Parent makeChild1() { 
      return new Parent(valueOfF1ForChild1); 
    } 

    public static Parent makeChild2() { 
      return new Parent(valueOfF1ForChild2); 
    } 
} 

Кроме того, вы можете проверить, подходит ли перечисление для вашего случая.

+0

Во-первых, В приведенном выше Проблема Я упомянул только одно поле, но на самом деле существует 4 поля, и все четыре поля (типа String) имеют длинное и постоянное значение, поэтому до моего мышления было бы лучше сделать дочерние классы, каждая из которых содержит окончательные статические значения этих 4 полей и передать их в качестве атрибутов в вызове super() ... Что вы думаете? Я прав? Во-вторых, не могли бы вы отредактировать свой ответ, чтобы пролить свет на статические заводские методы. Раньше я их не использовал. –

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