简体   繁体   中英

Java inheritance: multiple extends needed

I design my game application and face some troubles in OOP design. I want to know some patterns which can help me, because java have not any multiple extends option. I will describe my problem below, and also explain why multiple interface doesn't help me at all. Lets go.

What we want is "class is set of features". By feature I mean construction like:

field a;
field b;
field c;

method m1(){
// use, and change fields a,b,c;
}
method m2(){
// use, and change fields a,b,c;
}
//etc

So, basically the feature is a set of methods and corresponding fields. So, it's very close to the java interface.

When I talk that class implemets "feature1" I mean that this class contains ALL "feature needed" fields, and have realisation of all feature related methods. When class implements two features the tricky part begins. There is a change, that two different features contains similar fields (names of this fields are equal). Let the case of different types for such fields will be out of scope. What I want - is "feature naming tolerance" - so that if methodA() from feature A change the field " common_field ", the methodB from feature B , that also use " common_field " as field will see this changes.

So, I want to create a set of features (basically interfaces) and their implementations. After this I want to create classes which will extends multiple features, without any copy-paste and other crap. But I can't write this code in Java:

public static interface Feature1 {
        public void method1();
    }

    public static interface Feature2 {
        public void method2();
    }

    public static class Feature1Impl implements Feature1 {
        int feature1Field;
        int commonField;

        @Override
        public void method1() {
            feature1Field += commonField;
            commonField++;
        }

    }

    public static class Feature2Impl implements Feature2 {
        int feature2Field;
        int commonField;

        @Override
        public void method2() {
            commonField++;
        }

    }

    public static class MyFeaturedClass extends Feature1Impl, Feature2Impl implements Feature1, Features2 {

    }

So, as you can see the problem are really complex. Below I'll describe why some standart approaches doesn't work here. 1) Use something like this:

public static class MyFeaturesClass implements Feature1,Feature2{

        Feature1 feature1;
        Feature2 feature2;

        @Override
        public void method2() {
            feature2.method2();
        }
        @Override
        public void method1() {
            feature1.method1();
        }

    }

Ok, this is really nice approach - but it does not provide "feature field name tolerance" - so the call of method2 will not change the field "commonField" in object corresponding the feature1.

2) Use another design. For what sake you need such approach? Ok. In my game there is a " unit " concept. A unit is MOVABLE and ALIVE object. Movable objects has position , and move() method. Alive objects has hp and takeDamage() and die() methods. There is only MOVABLE objects in my game, but this objects isn't alive. Also, there is ALIVE objects in my game, but this objects isn't movable (buildings for example). And when I realize the movable and alive as classes, that implements interfaces, I really don't know from what I should extends my Unit class. In both cases I will use copy-paste for this. The example above is really simple, actually I need a lot of different features for different game mechanics. And I will have a lot of different objects with different properties.

What I actually tried is:

Map<Field,Object> fields;

So any object in my game has such Map, and to any object can be applied any method. The realization of method is just take needed fields from this map, do its job and change some of them. The problem of this approach is performance. First of all - I don't want to use Double and Interger classes for double and int fields, and second - I want to have a direct accsess to the fields of my objects (not through the map object).

Any suggestions?

PS. What I want as a result:

class A implements Feature1, Feature2, Feature3, Feature4, Feature5 {
// all features has corresponding FeatureNImpl implementations;
// features 1-2-3 has "shared" fields, feature 3-4 has, features 5-1 has. 
// really fast implementation with "shared field tolerance" needed.
}

One possibility is to add another layer of interfaces. XXXProviderInterface could be defined for all possible common fields, that define a getter and setter for them.

A feature implementation class would require the needed providers in the constructor. All access to common fields are done through these references.

A concrete game object class implementation would implement the needed provider interfaces and feature interfaces. Through aggregation, it would add the feature implementations (with passing this as provider), and delegate the feature calls to them.

Eg

public interface Feature1 {
    void methodF1();
}
public interface Feature2 {
    void methodF2();
}

public interface FieldAProvider {
    int getA();
    void setA(int a);
}

public class Feature1Impl implements Feature1 {
    private FieldAProvider _a;
    Feature1Impl(FieldAProvider a) {
        _a = a;
    }
    void methodF1() {
        _a.setA(_a.getA() * 2);
    }
}

// Similar for Feature2Impl

public class GameObject implements Feature1, Feature2, FieldAProvider
{
    int _fieldA;
    Feature1 _f1;
    Feature2 _f2;

    GameObject() {
        _f1 = new Feature1Impl(this);
        _f2 = new Feature2Impl(this);
    }

    int getA() {
        return _fieldA;
    }
    void setA(int a) {
        _fieldA = a;
    }

    void methodF1() {
        _f1.methodF1();
    }

    void methodF2() {
        _f2.methodF2();
    }
}

However, I don't think this is an optimal solution

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