2014-03-19 4 views
1

мне нужно, чтобы добавить новые функции в мои рамки, которые выглядят любят это:Совместимых рамки с новыми функциями

interface firstInterface{} 

abstract class ReadOnly extends Forward{} 

class Reference extends ReadOnly implements firstInterface{} 

Абстрактный класс ReadOnly является ограничением функции от Forward бросая unsupportedaction. Мне теперь нужно поддерживать эту функцию, но в другом классе (таким образом, есть оба варианта).

Мой первый шаг был,

class baseReference implements firstInterface{} 

abstract class ReadOnly extends Forward{} 

class Reference extends baseReference, Readonly{} 

class Loading extends baseReference, Forward{} 

это приводит к множественному наследованию. Нужна помощь с новым дизайном без большого дублирования кода.

+0

В чем конкретно ваш вопрос? – EthanB

+0

Использует ли «Forward» или «ReadOnly» классы «firstInterface»? – umlcat

ответ

1

Преимущество Состав над наследованием. Оберните реализацию с помощью другой реализации путем делегирования (шаблон адаптера)

public class ReadOnly implements Forward{ 

    private Forward delegate; 

    public ReadOnly(Forward adaptee){ 
      //check for null here if you want 
      this.delegate = adaptee; 
    } 

    public void loadFoo(Foo foo){ 
     //invalid since this is read-only 
     //this is the exception mentioned in OP 
     throw new UnsupportedAction(): 

    } 


    public Foo readFoo(){ 
      //allowed return delegate's foo 
      return delegate.readFoo(); 
    } 

} 
+0

Вперед - это не интерфейс! Также как я могу выполнить загрузку? – change

+0

Извините, ваш пример запутан, так как вы сказали: class BaseReference реализует Forward {} '. что означает, что Forward является интерфейсом. Чтобы ответить на другой вопрос, загрузка выполняется в базовом объекте. Версия, предназначенная только для чтения, удаляет функциональные возможности загрузки, не позволяя вызывающим методам загрузки делегатов. – dkatzel

+0

мой плохой! теперь это должно быть ясно. – change

0

Похоже, вы вводите в заблуждение реализацию интерфейса с помощью реализации класса.

Позвольте мне ответить на ваш вопрос, используя текстовые диаграммы классов UML, а не код. Пожалуйста, считайте точки пустыми.

[1] Ваш фреймворк имеет интерфейс «FirstInterface» и этот интерфейс определяет метод «Load», возможно, существуют другие методы или свойства.

..................................... 
..+-------------------------------+.. 
..|.........<<interface>>.........|.. 
..|........FirstInterface.........|.. 
..+-------------------------------+.. 
..|.[+].void Load()...............|.. 
..+-------------------------------+.. 
..................................... 

Обратите внимание, что «+» внутри квадратные скобки означают, что функция или свойство может быть accesed как «общественность».

[2] В вашей инфраструктуре есть класс под названием «ForwardClass», который поддерживает «FirstInterface».

Следовательно, этот класс имеет свой собственный метод «Загрузить».

..................................... 
..+-------------------------------+.. 
..|.........<<interface>>.........|.. 
..|........FirstInterface.........|.. 
..+-------------------------------+.. 
..|.[+].void Load()...............|.. 
..+-------------------------------+.. 
..................|.................. 
................/---\................ 
................|.O.|................ 
..................|.................. 
..+-------------------------------+.. 
..|...........<<class>>...........|.. 
..|.........ForwardClass..........|.. 
..+-------------------------------+.. 
..|.[+].void Load()...<<virtual>>.|.. 
..+-------------------------------+.. 
..................................... 

Обратите внимание, что в Java, в отличие от других языков, все методы считаются «виртуальные», и могут быть заменены без указания ничего.

Я буду использовать «виртуальный» текст, когда метод объявлен в первый раз, и «переопределить» текст на диаграммах, когда метод уже существует, и его заменить.

[3] Теперь класс «ForwardClass» расширяет его классом «ReadOnlyClass», который заменяет метод «Загрузить» и вызывает исключение «UnsupportedActionException», помните, что исключения - это особый вид классов или объектов.

Класс «ReadOnlyClass», также добавьте дополнительные методы.

..................................... 
..+-------------------------------+.. 
..|...........<<class>>...........|.. 
..|.........ForwardClass..........|.. 
..+-------------------------------+.. 
..|.[+].void Load()...<<virtual>>.|.. 
..+-------------------------------+.. 
..................|.................. 
..................^.................. 
................./.\................. 
................/---\................ 
..................|........................................................... 
..+---------------------------------+......+-------------------------------+.. 
..|............<<class>>............|...+--|.........<<exception>>.........|.. 
..|..........ReadOnlyClass..........|...|..|...UnsupportedActionException..|.. 
..+---------------------------------+...|..+-------------------------------+.. 
..|.[+].void Load()....<<override>>.|---+..................................... 
..|.[+].void DoExtra()..<<virtual>>.|......................................... 
..+---------------------------------+......................................... 
.............................................................................. 

[4] Теперь, вы хотите расширить класс "ReadOnlyClass" с "LoadingClass". Давайте предположим, что он добавляет некоторые свойства или заменяет метод DoExtra.

.............................................................................. 
..+---------------------------------+......+-------------------------------+.. 
..|............<<class>>............|...+--|.........<<exception>>.........|.. 
..|..........ReadOnlyClass..........|...|..|...UnsupportedActionException..|.. 
..+---------------------------------+...|..+-------------------------------+.. 
..|.[+].void Load()....<<override>>.|---+..................................... 
..|.[+].void DoExtra()..<<virtual>>.|......................................... 
..+---------------------------------+......................................... 
..................|.................. 
..................^.................. 
................./.\................. 
................/---\................ 
..................|.................. 
..+----------------------------------+.. 
..|............<<class>>.............|.. 
..|...........LoadingClass...........|.. 
..+----------------------------------+.. 
..|.[+].void DoExtra()..<<override>>.|.. 
..+----------------------------------+.. 
........................................ 

[5] Теперь давайте применим сценарий вашего сообщения.

Подходит для того, чтобы любой объект «LoadingClass» также использовал метод «Загрузить» родительского класса «ForwardClass», игнорируя метод «Загрузить» родительского класса «ReadOnlyClass», который генерирует исключение.

Потенциальное решение, чтобы создать новый защищенный метод с названием «ConfirmedLoad» в «ForwardClass». Давайте добавим поле с символом «#», чтобы очистить его «защищенный» метод.

Переместить весь код «Загрузить» в «ConfirmedLoad», а затем выполнить «Загрузить» выполнить «ConfirmedLoad».

Наследование классов, продолжается так же, и другой код, который использует эти классы, не изменяется с изменениями. Обратите внимание, что я не поместил «виртуальный» текст в «ConfirmedLoad», потому что мы не заинтересованы в замене этого метода.

............................................ 
..+---------------------------------------+.. 
..|...............<<class>>...............|.. 
..|.............ForwardClass..............|.. 
..+---------------------------------------+.. 
..|.[#].void ConfirmedLoad()..............|.. 
..|.[+].void Load()...........<<virtual>>.|.. 
..+---------------------------------------+.. 
............................................. 

[6] Затем мы можем добавить логический «CanLoad» метод, в «ReadOnlyClass», что в этом случае всегда возвращать ложь, но ожидать можно изменить позже. Мы также изменяем здесь метод «Загрузить», который вызывает функцию «CanLoad», а если asnwer - false, генерирует исключение.

............................................ 
..+---------------------------------------+.. 
..|...............<<class>>...............|.. 
..|.............ForwardClass..............|.. 
..+---------------------------------------+.. 
..|.[#].void ConfirmedLoad()..............|.. 
..|.[+].void Load()...........<<virtual>>.|.. 
..+---------------------------------------+.. 
..................|.................. 
..................^.................. 
................./.\................. 
................/---\................ 
..................|.................. 
..+---------------------------------------+.. 
..|...............<<class>>...............|........+-------------------------------+.. 
..|.............ReadOnlyClass.............|.....+--|.........<<exception>>.........|.. 
..+---------------------------------------+.....|..|...UnsupportedActionException..|.. 
..|.[+].bool CanLoad()........<<virtual>>.|.....|..+-------------------------------+.. 
..|.[+].void Load()..........<<override>>.|..---+..................................... 
..|.[+].void DoExtra()........<<virtual>>.|.. 
..+---------------------------------------+.. 
............................................. 

[7] Теперь, в другом, чтобы сделать метод «Load» выполняются в любом объекте «LoadingClass», а затем, позволяет заменить метод «CanLoad», всегда возвращает истину.

............................................. 
..+---------------------------------------+.. 
..|...............<<class>>...............|.. 
..|.............ForwardClass..............|.. 
..+---------------------------------------+.. 
..|.[#].void ConfirmedLoad()..............|.. 
..|.[+].void Load()...........<<virtual>>.|.. 
..+---------------------------------------+.. 
.......................|.................. 
.......................^.................. 
....................../.\................. 
...................../---\................ 
.......................|.................. 
..+---------------------------------------+.. 
..|...............<<class>>...............|........+-------------------------------+.. 
..|.............ReadOnlyClass.............|.....+--|.........<<exception>>.........|.. 
..+---------------------------------------+.....|..|...UnsupportedActionException..|.. 
..|.[+].bool CanLoad()........<<virtual>>.|.....|..+-------------------------------+.. 
..|.[+].void Load()..........<<override>>.|..---+..................................... 
..|.[+].void DoExtra()........<<virtual>>.|.. 
..+---------------------------------------+.. 
.......................|.................. 
.......................^.................. 
....................../.\................. 
...................../---\................ 
.......................|.................. 
..+---------------------------------------+.. 
..|...............<<class>>...............|.. 
..|.............LoadingClass..............|.. 
..+---------------------------------------+.. 
..|.[+].bool CanLoad().......<<override>>.|.. 
..+---------------------------------------+.. 
............................................. 

[8] Если добавить другие классы, реализующие «LoadInterface», а также подклассы «ForwardClass», «ReadOnlyClass» или «LoadingClass» классов, это не имеет значения, так как интерфейс может поддерживаться несколько раз, интерфейс добавляет только «Я ожидаю, что это», а не настоящий код.

............................................. 
..+---------------------------------------+.. 
..|...............<<class>>...............|.. 
..|............FirstInterface.............|.. 
..+---------------------------------------+.. 
..|.[+].void Load().......................|.. 
..+---------------------------------------+.. 
.......................|...................... 
...................../---\.................... 
.....................|.O.|........................ 
.......................|.......................... 
.......................+-----------------------+.. 
.......................|.......................|.. 
.......................|.......................|.. 
..+---------------------------------------+....|.. 
..|...............<<class>>...............|....|.. 
..|.............ForwardClass..............|....|.. 
..+---------------------------------------+....|.. 
..|.[#].void ConfirmedLoad()..............|....|.. 
..|.[+].void Load()...........<<virtual>>.|....|.. 
..+---------------------------------------+....|.. 
.......................|.......................|.. 
.......................^.......................|.. 
....................../.\......................|.. 
...................../---\.....................|.. 
.......................|.......................|.. 
..+---------------------------------------+....|.. 
..|...............<<class>>...............|....|.. 
..|.............ReadOnlyClass.............|....|.. 
..+---------------------------------------+....|.. 
..|.[+].bool CanLoad()........<<virtual>>.|....|.. 
..|.[+].void Load()..........<<override>>.|....|.. 
..|.[+].void DoExtra()........<<virtual>>.|....|.. 
..+---------------------------------------+....|.. 
.......................|.......................|.. 
.......................^.......................|.. 
....................../.\......................|.. 
...................../---\.....................|.. 
.......................|.......................|.. 
..+---------------------------------------+....|.. 
..|...............<<class>>...............|....|.. 
..|.............LoadingClass..............|....|.. 
..+---------------------------------------+....|.. 
..|.[+].bool CanLoad().......<<override>>.|....|.. 
..+---------------------------------------+....|.. 
.......................|.......................|.. 
.......................^.......................|.. 
....................../.\......................|.. 
...................../---\.....................|.. 
.......................|.......................|.. 
..+---------------------------------------+....|.. 
..|...............<<class>>...............|----+.. 
..|...........BaseReferenceClass..........|....... 
..+---------------------------------------+....... 
.................................................. 

В "BaseReferenceClass" класс реализует, косвенно, интерфейс "FirstInterface" через класс "LoadingClass", но также реализует, опять же, непосредственно, один и тот же интерфейс. Это его ОК с интерфейсами, но, НЕ с классами.

Если интерфейс «FirstInterface» был классом (возможно, абстрактным), проблема множественного дублированного наследования вызовет ошибку компиляции.

Cheers.