Proper workaround for multiple inheritence in Java (Android)

I have a conceptual problem with a proper implementation of code which seems require multiple inheritance, that would not be a problem in many OO languages, but as the project is for Android, there is no such thing like multiple extends.

I have a bunch of activities, derived from different base classes, such as simple Activity, TabActivity, ListActivity, ExpandableListActivity, etc. Also I have some code fragments which I need to place into onStart, onStop, onSaveInstanceState, onRestoreInstanceState and other standard event handlers in all activities.

If I have a single base class for all activities, I’d place the code into a special intermediate derived class, and then create all activities extending it. Unfortunately, this is not the case, because there are multiple base classes. But placing the same portions of code into several intermediate classes is not a way to go, imho.

Another approach could be to create a helper object and delegate all calls of the abovementioned events to the helper. But this requires the helper object to be included, and all handlers to be redefined in all intermediate classes. So there is no much difference to the first approach here – still a lot of code duplicates.

If a similar situation occured under Windows, I’d subclass base class (something that “corresponds” to the Activity class in Android) and trap appropriate messages there (in a single place).

What can be done in Java/Android for this? I know there is interesting tools such as Java instrumentation (with some real examples), but I’m not a Java guru, and not sure if it’s worth trying in this specific case.

If I missed some other decent solutions, please, mention them.

UPDATE:

For those who may be interested in solving the same problem in Android I’ve found a simple workaround. There exist the Application class, which provides, among other things, the interface ActivityLifecycleCallbacks. It does exactly what I need allowing us to intercept and add some value into important events for all activities. The only drawback of this method is that it’s available starting from API level 14, which is not enough in many cases (support for API level 10 is a typical requirement today).

I am afraid you can-t implement your classsystem without codeduplication in android/java.

However you can minimize codeduplication if you combine special intermediate derived class with
composite helper object. This is called the Decorator_pattern:

    class ActivityHelper {
        Activity owner;
        public ActivityHelper(Activity owner){/*...*/}
        onStart(/*...*/){/*...*/}   
    }

    public class MyTabActivityBase extends TabActivity {
        private ActivityHelper helper;
        public MyTabActivityBase(/*...*/) {
            this.helper = new ActivityHelper(this);
        }

        protected void onStart() {
            super.onStart();
            this.helper.onStart();
        }
        // the same for onStop, onSaveInstanceState, onRestoreInstanceState,...
    }

    Public class MySpecialTabActivity extends MyTabActivityBase  {
       // non helper logic goes here ....
    }

so every base class you create an intermediate baseclass that delegates its calls to the helper.
The intermediate basesclasses are identical except the the baseclase where they inherit from.

1

I think you’re trying to avoid the wrong type of code duplication. I believe Michael Feathers wrote an article about this but unfortunately I can’t find it. The way he describes it is you can think of your code as having two parts like an orange: The rind and the pulp. The rind is the stuff like method declarations, field declarations, class declarations, etc. The pulp is the stuff inside these methods; the implementation.

When it comes to DRY, you want to avoid duplicating pulp. But often in the process you create more rind. And that’s ok.

Here’s an example:

public void method() { //rind
    boolean foundSword = false;
    for (Item item : items)
        if (item instanceof Sword)
             foundSword = true;
    boolean foundShield = false;
    for (Item item : items)
        if (item instanceof Shield)
             founShield = true;
    if (foundSword && foundShield)
        //...
}  //rind

This can be refactored into this:

public void method() {  //rind
    if (foundSword(items) && foundShield(items))
        //...
} //rind

public boolean foundSword(items) { //rind
    return containsItemType(items, Sword.class);
} //rind

public boolean foundShield(items) { //rind
    return containsItemType(items, Shield.class);
} //rind

public boolean containsItemType(items, Class<Item> itemClass) { //rind
    for (Item item : items)
        if (item.getClass() == itemClass)
             return true;
    return false;
} //rind

We added a lot of rind in this refactoring. But, the second example has a much cleaner method() with less DRY violations.

You said you’d like to avoid the decorator pattern because it leads to code duplication. If you look at the image in that link you’ll see it will only duplicate the operation() signature (ie: rind). The operation() implementation (pulp) should be different for each class. I think your code will end up cleaner as a result and have less pulp duplication.

You should prefer composition over inheritance. A nice example is the IExtension “pattern” in the .NET WCF framework. Baiscally you have 3 interfaces, IExtension, IExtensibleObject and IExtensionCollection. You can then compose the different behaviors with an IExtensibleObject object by addig IExtension instances to it’s Extension IExtensionCollection property. In java it should look something like that, not however that you have to create your own IExtensioncollection implementation that calls the attach and detach methods when items are being added/removed. Also note that it is up to you to define the extension points in your extensible class The example uses an event-like callback mechanism:

import java.util.*;

interface IExtensionCollection<T> extends List<IExtension<T>> {
    public T getOwner();
}

interface IExtensibleObject<T> {
    IExtensionCollection<T> getExtensions();
}

interface IExtension<T> {
    void attach(T target);
    void detach(T target);
}

class ExtensionCollection<T>
    extends LinkedList<IExtension<T>>
    implements IExtensionCollection<T> {

    private T owner;
    public ExtensionCollection(T owner) { this.owner = owner; }
    public T getOwner() { return owner; }
    public boolean add(IExtension<T> e) {
        boolean result = super.add(e);
        if(result) e.attach(owner);
        return result;
    }
    // TODO override remove handler
}

interface ProcessorCallback {
    void processing(byte[] data);
    void processed(byte[] data);
}

class Processor implements IExtensibleObject<Processor> {
    private ExtensionCollection<Processor> extensions;
    private Vector<ProcessorCallback> processorCallbacks;
    public Processor() {
        extensions = new ExtensionCollection<Processor>(this);
        processorCallbacks = new Vector<ProcessorCallback>();
    }
    public IExtensionCollection<Processor> getExtensions() { return extensions; }
    public void addHandler(ProcessorCallback cb) { processorCallbacks.add(cb); }
    public void removeHandler(ProcessorCallback cb) { processorCallbacks.remove(cb); }

    public void process(byte[] data) {
        onProcessing(data);
        // do the actual processing;
        onProcessed(data);
    }
    protected void onProcessing(byte[] data) {
        for(ProcessorCallback cb : processorCallbacks) cb.processing(data);
    }
    protected void onProcessed(byte[] data) {
        for(ProcessorCallback cb : processorCallbacks) cb.processed(data);
    }
}

class ConsoleProcessor implements IExtension<Processor> {
    public ProcessorCallback console = new ProcessorCallback() {
        public void processing(byte[] data) {

        }
        public void processed(byte[] data) {
            System.out.println("processed " + data.length + " bytes...");
        }
    };
    public void attach(Processor target) {
        target.addHandler(console);
    }
    public void detach(Processor target) {
        target.removeHandler(console);
    }
}

class Main {
    public static void main(String[] args) {
        Processor processor = new Processor();
        IExtension<Processor> console = new ConsoleProcessor();
        processor.getExtensions().add(console);

        processor.process(new byte[8]);
    }
}

This approach has the benefit of extension reuse if you manage to extract common extension points between your classes.

4

Starting in Android 3.0, it may be possible to solve this elegantly by using a Fragment. Fragments have their own lifecycle callbacks and can be placed inside an Activity. I’m not sure this will work for all the events though.

Another option I’m also not sure about (lacking in-depth Android know-how) might be to use a Decorator in the opposite way k3b suggests: create an ActivityWrapper whose callback methods contain your common code and then forward to a wrapped Activity object (your actual implementation classes), and then have Android start that wrapper.

It is true that Java doesn’t allow multiple-inheritance, but you could simulate it more or less by making each one of your SomeActivity subclasses extend the original Activity class.

You’ll have something like:

public class TabActivity extends Activity {
    .
    .
    .
}

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật