简体   繁体   中英

Same implementation in different subclasses

Say I have the following scenario:

    abstract class A {
        abstract method1();
        abstract method2();
    }

    class B extends A {
        method1() {
            // implementation 1
        }
        method2() {
            // implementation 3
        }
    }

    class C extends A {
        method1() {
            // implementation 1
        }
        method2() {
            // implementation 4
        }
    }

    class D extends A {
        method1() {
            // implementation 2
        }
        method2() {
            // implementation 4
        }
    }

Bottom line: several subclasses of the same class, using different method implementations for different methods.

The problem is that I have the same implementation in different subclasses. My question is what to do with these common implementations?
The logical way to do it would be to create another level of abstraction but that only works if I have one method with common implementations (since Java doesn't have multiple inheritence). I could also put the implementation most commonly used in the superclass and only implement it differently in the other classes. However, I wouldn't do that because in time the most common implementation might change with the addition of other classes, and besides, I'd like to keep the methods abstract in the superclass.

Is there some pattern that would solve my problem in an "elegant manner"?

You're running into the classic OOP issue with inheritance heirarchies becoming unwieldy :-)

My suggested solutions:

  • Prefer composition to inheritance - factor out the implementations into separate objects that can be "plugged in" to provide the required behaviour. The methods in your base class just call the implementation plugin via its defined interface. This is basically the Strategy Pattern . It's a very solid approach, though can sometimes become prone to a lot of over-engineering / boilerplate when you have a lot of different strategy types.
  • Adopt a prototype-based model - use prototype-based objects rather than traditional OOP. This solves all the problems - you escape the inherent restrictions of inheritance hierarchies and can just copy the implementation you want to whichever objects need it at runtime. This is the most radical option, but can bring some big benefits.
  • Factor implementations out into static functions - this way you can share the implementations - it's a bit messy since you still need to do all the overrides, but they just become one-liners delegating the call to the right implementation. This is often the least intrusive option.

I would recommend Composition. Consider the following:

interface I1 {
     method1();
}

abstract class A implements I1{
    abstract method1();
    abstract method2();
}

class CommonOperations implements I1 {
    method1() {
        // implementation 1
    }
}

class B extends A {
    CommonOperations common;

    method1() {
        common.method1();
    }
    method2() {
        // implementation 3
    }
}

class C extends A {
    CommonOperations common;

    method1() {
        common.method1();
    }
    method2() {
        // implementation 4
    }
}

class D extends A {
    method1() {
        // implementation 2
    }
    method2() {
        // implementation 4
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM