开发者

Another problem in inheritance of Java?

开发者 https://www.devze.com 2022-12-19 13:04 出处:网络
I have a Parent.java class and 4 child classes as Child1.java, Child2.java and so on. There are two methods

I have a Parent.java class and 4 child classes as Child1.java, Child2.java and so on.

There are two methods

  • m1()
  • m2()

and one field

  • f1

Field f1 has different values based on the child class.

Method m1 has the common implementation so I have put it in Parent.java class. It also refer开发者_StackOverflow社区s method m2.

Method m2 has common implemtation but it process field f1 which is different for all the child classes.

So my questions are as follows:

Q1. Should I place the field f1 in the parent class and let all the child classes inherit them and initialize them in their own constructors or Should I make a field f1 for all the child classes.

Q2. As the method m2 has common implementation but process field f1 which doesn't have same value for every child class, so should I place it in parent class or child class.

Q3. If I should place the method m2 in parent class, the there is one problem that method m1 (which have common implementation) refer method m2, so would it create any problem?


Place m2 and f1 in the parent class if m2's implementation is the same for all classes. If there's a specific part for each child class that can be run after the common part - separate it and place it in the child classes while calling super.m2(). Set f1 in each child class's constructor.

The result will look something like this:

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 */ }
}

This should allow you to push the maximum amount of code as far back in the hierarchy as it can go. Least code duplication.

Edited to fix trying to access a private member from a child class. Changed to setting it using the constructor.


In my opinion:

  1. f1 should be in the parent class and initialized in the child constructor. This way, the get and set methods are only written once.
  2. m2 should be in the parent class.
  3. m1 should be also be in the parent class. Don't forget that you can also make methods abstract if they do not have a common implementation but exist in all child classes. This would allow you to call it from other methods in the parent class despite not being defined there. Also keep in mind that the parent class would also need to be abstract in this case.


From what you described, I don't see any problem with this implementation:

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);
   }
}

{...}


What you are trying to do sound like Template Method design pattern: http://en.wikipedia.org/wiki/Template_method_pattern

I suggest putting f1 in the parent class and declaring m2 abstract in the parent class (which will make the class abstract itself).


If the child classes differ only in the value of f1 then there is no point in even creating subclasses, you should just pass f1 in a constructor or use static factory methods to create instances for the different cases. For example:

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);
    }
}

Also, you might want to check out if an enumeration is suitable for your case.

0

精彩评论

暂无评论...
验证码 换一张
取 消