2016-12-12 18 views
0

Скажем, у меня есть несколько интерфейсов, которые все простираются от родительского интерфейса. В родительском интерфейсе есть некоторые члены, которые должны использоваться всеми дочерними интерфейсами, поэтому обычно я хотел бы добавить конструктор в родительский интерфейс для установки этих общих элементов. Но это невозможно сделать, поскольку классы являются интерфейсами, а не абстрактными классами. И я не могу просто изменить их на абстрактные классы, потому что я бы позволил классу реализовать несколько интерфейсов, что невозможно сделать с помощью абстрактных классов. Как вы разрешаете это, но при этом соблюдаете требования к дизайну?Устранение недостающего конструктора в родительском интерфейсе JAVA

например.

interface Parent { 
    SomeCommonMember commMember; 
    Parent(SomeParameter para) { 
     // do some calculations to init commMember based on para 
     commMember = ...; 
    } 
} 

interface ChildA extends Parent { 
    void ChildAMethod(); 
} 

interface ChildB extends Parent { 
    void ChildBMethod(); 
} 

public class MyImplementation implements ChildA, ChildB { 
    MyImplementation(SomeParameter para) { 
     super(para); 
    }; 
    void ChildAMethod() { 
     // uses commMember 
    }; 
    void ChildBMethod() { 
     // uses commMember 
    }; 
} 

public class Test { 
    public static void main(String[] args) { 
     Parent generic = new MyImplementation(new SomeParameter()); 
     if (generic instanceof ChildA) { 
      generic.ChildAMethod(); 
     } 
     if (generic instanceof ChildB) { 
      generic.ChildBMethod(); 
     } 
    } 
} 

ответ

2

Если вы используете Java 8, вы можете определить интерфейс default methods. Обратите внимание, что вы не можете иметь свойства на уровне интерфейса. Поэтому вам придется изменить свой процесс для этого.

1

Я думаю, что единственное, что вы можете сделать для обеспечения каждой реализации интерфейса Parent, состоит в том, что общие члены должны определить геттеры и сеттеры для этих общих членов (и дополнительные методы в отношении этих элементов) в интерфейсе Parent. Таким образом, вы уверены, что каждая реализация интерфейса будет иметь что-то, что представляет общий член, и что вы можете его получить, установите его (и другой материал, который вы определили по умолчанию в родительском интерфейсе).

Таким образом, вы будете иметь:

interface Parent { 

    //getter 
    CommonMember getCommonMember(); 

    //setter 
    void setCommonMember(CommonMember newValue); 

    //if needed, additional mandatory method for processing common member 
    void processCommonMember(); 
} 

в реализующих классах, то вы можете использовать эти методы. У вас все еще будет какая-то типовая (реализация тех же методов), но это цена, которую нужно заплатить при использовании интерфейсов ... Если вы действительно не хотите перепечатывать все эти вещи, вам придется идти с абстрактными классами и использовать агрегацию или композиции, чтобы попытаться «имитировать» расширение множественного (аннотация) класса:

class A { 
    //some methods 
} 

class B { 
    //some methods 
} 

class AwithB { 
    private A a; 
    private B b; 

    //implement methods of A using a 
    ... 

    //implement methods of B using b 
    ... 
} 

Но вы-то ограничены (по-другому), с помощью этой опции тоже ...