Java, эквивалентный из Какао, делегирует / Objective C неофициальные протоколы?

Если я понимаю Ваш вопрос правильно, следующий код должен сделать задание:

l = [
 ['4', '21', '1', '14', '2008-10-24 15:42:58'], 
 ['3', '22', '4', '2somename', '2008-10-24 15:22:03'], 
 ['5', '21', '3', '19', '2008-10-24 15:45:45'], 
 ['6', '21', '1', '1somename', '2008-10-24 15:45:49'], 
 ['7', '22', '3', '2somename', '2008-10-24 15:45:51']
]

def compareField(field):
   def c(l1,l2):
      return cmp(l1[field], l2[field])
   return c

# Use compareField(1) as the ordering criterion, i.e. sort only with
# respect to the 2nd field
l.sort(compareField(1))
for row in l: print row

print
# Select only those sublists for which 4th field=='2somename'
l2somename = [row for row in l if row[3]=='2somename']
for row in l2somename: print row

Вывод:

['4', '21', '1', '14', '2008-10-24 15:42:58']
['5', '21', '3', '19', '2008-10-24 15:45:45']
['6', '21', '1', '1somename', '2008-10-24 15:45:49']
['3', '22', '4', '2somename', '2008-10-24 15:22:03']
['7', '22', '3', '2somename', '2008-10-24 15:45:51']

['3', '22', '4', '2somename', '2008-10-24 15:22:03']
['7', '22', '3', '2somename', '2008-10-24 15:45:51']
13
задан PlagueHammer 30 July 2009 в 23:27
поделиться

3 ответа

Короткий ответ: в Java нет ничего настолько близкого, насколько вам хотелось бы, но есть альтернативы. Шаблон делегирования несложно реализовать, просто он не так удобен, как в Objective-C.

Причина, по которой «неформальные протоколы» работают в Objective-C, заключается в том, что язык поддерживает категорий , которые позволяют добавлять методы к существующим классам, не создавая их подклассов или даже не имея доступа к исходному коду. Таким образом, наиболее неформальные протоколы относятся к категории NSObject. Это явно невозможно в Java.

Objective-C 2.0 выбирает методы протокола @optional, что является гораздо более чистой абстракцией и предпочтительным для нового кода, но даже дальше от эквивалента в Java.

Честно говоря, наиболее гибкий подход - определить протокол делегата, а затем позволить классам реализовать все методы. (Для современных IDE, таких как Eclipse, это тривиально.) Многие интерфейсы Java имеют сопутствующий класс адаптера, и это общий подход, не требующий от пользователя реализации большого количества пустых методов, но он ограничивает наследование, что делает разработку кода негибкой. . (Джош Блох рассматривает это в своей книге «Эффективная Java».) Я бы посоветовал сначала предоставить интерфейс, а затем добавить адаптер, если это действительно необходимо.

Что бы вы ни делали, избегайте создания исключения UnsupportedOperationException для «нереализованных» методов. Это заставляет делегирующий класс обрабатывать исключения для методов, которые должны быть необязательными. Правильный подход - реализовать метод, который ничего не делает, возвращает значение по умолчанию,

8
ответ дан 2 December 2019 в 00:18
поделиться

Ничто не мешает вам использовать шаблон делегата в ваших Java-объектах (это просто не часто используемый шаблон в JDK, как в Какао). Просто имейте делегат ivar типа, который соответствует вашему интерфейсу WhateverDelegate , а затем в методах вашего экземпляра, которые вы хотите делегировать, перенаправьте вызов метода на объект делегата, если он существует. Вы, вероятно, получите что-то похожее на this , за исключением Java вместо Obj-C.

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

2
ответ дан 2 December 2019 в 00:18
поделиться

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

public class MyClass {

    private MyClassDelegate delegate;

    public MyClass () {

    }

    // do interesting stuff

    void setDelegate(MyClassDelegate delegate) {
        this.delegate = delegate;
    }

    interface MyClassDelegate {
        void aboutToDoSomethingAwesome();
        void didSomethingAwesome();
    }

    class MyClassDelegateAdapter implements MyClassDelegate {

        @Override
        public void aboutToDoSomethingAwesome() {
            /* do nothing */
        }

        @Override
        public void didSomethingAwesome() {
            /* do nothing */
        }
    }
}

Тогда кто-то может прийти и просто реализовать вещи, которые их волнуют:

class AwesomeDelegate extends MyClassDelegateAdapter {

    @Override
    public void didSomethingAwesome() {
        System.out.println("Yeah!");
    }
}

Либо это, либо чистое отражение, вызывающее "известные" методы. Но это безумие.

5
ответ дан 2 December 2019 в 00:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: