Неудаленные методы в реализации удаленного объекта

Я работаю над распределенной версией (rmi) игры Морской бой для школы. В игре у каждого игрока есть флот и сетка, поэтому я хотел иметь возможность использовать итераторы для написания кода как такового

class Fleet implements Iterable<Ship> {

    private List<Ship> fleet;
    ...
    @Override
    public Iterator<Ship> iterator() { return fleet.iterator(); }
}

class Player {

    private Fleet fleet;
    ...
    public void placeFleet() {
        for (Ship s : fleet) {
            ...
        }
    }
}

Но мой класс Fleet также должен быть удаленным классом, поэтому у меня есть что-то вроде этого

interface IFleet extends Remote, Iterable<IShip> {...}

class Fleet extends UnicastRemoteObject implements IFleet {...}

Однако это вызывает ошибку, потому что метод iterator() не является удаленным методом, т.е. я получаю illegal remote method encountered: public abstract java.util.Iterator java.lang.Iterable.iterator()

Я также пробовал с

interface IFleet extends Remote {...}

class Fleet extends UnicastRemoteObject implements IFleet, Iterable<IShip> {...}

И так у меня два вопроса:

  1. Может ли удаленный объект реализовать только Remote и его подынтерфейсы?
  2. Могу ли я каким-то образом скрыть методы в удаленных объектах от клиента rmi (сделать их недоступными и, таким образом, позволить им НЕ учитывать потребности удаленного интерфейса)?

Спасибо!

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


person C. Miranda    schedule 09.12.2017    source источник
comment
Iterable<T> — это интерфейс, вы имели в виду implements вместо extends?   -  person StaticBeagle    schedule 09.12.2017
comment
Ах да, извините, я ошибся во втором фрагменте кода.   -  person C. Miranda    schedule 09.12.2017


Ответы (1)


implements Remote

Это уже неправильно. Вы должны определить свой собственный удаленный интерфейс, который расширяет Remote, и реализовать его. Я подозреваю, что это вызывает проблему. У вас вообще нет реальных удаленных методов в вашем классе. А по сути UnicastRemoteObject уже реализует Remote.

Ответы на ваши вопросы:

  1. Удаленный объект может реализовывать любые интерфейсы, которые ему нравятся, независимо от того, удаленные они или нет.
  2. Они уже скрыты, если не отображаются в вашем удаленном интерфейсе.

Ваш код не имеет смысла, если Player не является локальным объектом на стороне сервера. Так ли это?

ИЗМЕНИТЬ Ваше редактирование также неверно:

interface IFleet extends Remote, Iterable<IShip> {...}

class Fleet extends UnicastRemoteObject implements IFleet {...}

Удаленный интерфейс может содержать только удаленные методы, и они должны быть объявлены для генерирования RemoteException, и это является причиной сообщения об ошибке, которое вы получили: метод(ы) Iterable не генерируют RemoteException.

Таким образом, ваш удаленный интерфейс должен расширять Remote, а не расширять Iterable. В любом случае это не имеет смысла, если вы хотите скрыть это от клиента. Это удаленный объект, который должен реализовать Iterable.

Я также пробовал с

interface IFleet extends Remote {...}

class Fleet extends UnicastRemoteObject implements IFleet, Iterable<IShip> {...}

Это единственное, что вы должны были попробовать. Это работает и удовлетворяет ваш вопрос (2).

person user207421    schedule 10.12.2017
comment
Нет, извините, я так написал, чтобы упростить (думал, вы поймете, я изменю). На самом деле у меня есть интерфейсы IFleet и IPlayer, расширяющие Remote и IFleet, а также расширяющие Iterable‹Ship›. Это не имеет к этому никакого отношения. И когда я реализую метод, который не объявлен в удаленном интерфейсе, я получаю ошибку времени выполнения (подобную той, которую я показал). - person C. Miranda; 10.12.2017
comment
Что ж, это тоже неправильно: см. Правку. Никто не поймет, если вы не опубликуете настоящий код. - person user207421; 10.12.2017