Есть ли способ избежать наложения этого типа?

Рассмотрим следующий класс, который определяет и реализует Foo интерфейс:

public class MyClass {

    public Foo getFoo() {
        return new FooImpl();
    }

    public void fooMethod(Foo foo) {
        final fooImpl = (FooImpl) foo;
        fooImpl.hiddenMethod();
    }

    public interface Foo {
        void doSomething();
    }

    private class FooImpl implements Foo {
        public void doSomething();

        void hiddenMethod() {
        }
    }
}

Вне классов будут звонить MyClass.getFoo() чтобы получить Foo объект и может передать его обратно fooMethod(), fooMethod() ожидает FooImpl реализация Foo и бросает Foo в FooImpl так что он может вызвать метод package-private hiddenMethod(),

Мой вопрос, я не без ума от кастинга Foo в FooImpl, Есть ли другой шаблон, который я могу использовать, чтобы сделать то же самое?

Заранее спасибо...

3 ответа

Проблема здесь в том, что вы неявно нарушаете принцип инкапсуляции. В вашем классе есть метод, который зависит от реализации и, следовательно, не является частью интерфейса Foo. Это нарушение принципов ОО, этот актерский состав - только вершина айсберга. Что если вы хотите создать новый класс реализации Foo, в котором нет методов, которые вы хотите вызвать?

Вам следует переделать свой код, чтобы можно было вызывать только методы из интерфейса Foo.

Вы можете добавить hiddenMethod метод к Foo интерфейс

public interface Foo {
    ...   
    void hiddenMethod();
}

Поскольку интерфейс является контрактом для поддерживаемых операций, вам не нужно (не нужно?) Приводить объект для доступа к методам вне интерфейса.

Вы должны быть удручены.

Делай так

public void fooMethod(Foo foo) {
   if(foo instanceof FooImpl){
      final FooImpl fooImpl = (FooImpl) foo;
      fooImpl.hiddenMethod();
   }
}

Супер тип не может быть понижен без явного снижения. Не забудьте проверить его перед использованием instanceof оператор.


--РЕДАКТИРОВАТЬ--

Сделайте еще одну вещь, если хотите избежать кастинга. добавлять hiddenMethod() в Foo Интерфейс также.

public interface Foo {
    void doSomething();
    void hiddenMethod();
}
Другие вопросы по тегам