Как использовать метод из класса в другом классе без расширения - PullRequest
2 голосов
/ 12 ноября 2009

Извините, если мой вопрос звучит странно, лол, я попытаюсь объяснить. У меня 4 класса: Карактер, Карактерс, Орк, Человек. Орк и Человек оба расширяют Карактер. Karakters является ArrayList с Карактером в нем.

У меня есть метод в Orc и Human, который называется public public String getRace (). Теперь я хочу использовать этот метод в Karakters? !! Когда я пытаюсь сделать это, это терпит неудачу, потому что Орк и Человек расширяют Карактер, а не Карактер! Есть ли способ сделать это? Я что-то слышал о создании чего-то абстрактного: P

Спасибо

Ответы [ 6 ]

5 голосов
/ 12 ноября 2009

Объявите метод getRace() в Karakter (обратите внимание, что на английском языке написано "Символ", но это ни здесь, ни там).

Поскольку Karakters знает только то, что имеет дело с объектами типа Karakter, он не может знать, что в обеих реализациях есть метод getRace. Объявление метода в базовом классе решает эту проблему.

Это должно выглядеть так:

public abstract String getRace();

И класс Karakter также должен быть сделан abstract.

3 голосов
/ 12 ноября 2009

Что вы ожидаете от звонка Karakters.getRace()?

Поскольку Karakters является ArrayList, почему бы просто не иметь метод getRace(int position), чтобы вы могли найти расу интересующего вас человека.

Я не понимаю, как получить расу массива имеет какой-либо смысл.

2 голосов
/ 12 ноября 2009

Это на самом деле не имеет смысла. Если у вас есть ArrayList, вы можете вызвать getRace() для каждого элемента:

class Karakters {
    ArrayList<Karakter> kars = new ArrayList<Karakter> ();
    public String getRace () {
        for (Karakter k: kars) {
            ... uh ... which one to return?
        }
        return null; // List is empty
    }
}
1 голос
/ 12 ноября 2009

Вы можете вызвать метод для объекта, который реализует этот метод, при условии, что он доступен из вашего текущего класса. В частности, поскольку метод getRace является открытым, любой класс может вызывать его, если у него есть соответствующий экземпляр Orc или Human для его вызова.

Я полагаю, что ваша проблема в том, что у вас есть список Karakter с, а не орков или людей. Таким образом, Karakters знает только в этот момент, что объект является Karakter, и поэтому может вызывать только методы, определенные в Karakter классе / интерфейсе.

Одним из решений является добавление метода getRace к классу Karakter. Если для этого не имеет смысла возвращать значение в суперклассе, то вы можете сделать суперкласс abstract (что означает, что вы не можете создать его экземпляр напрямую, вы можете создать только один из его подклассов). ) и объявите метод abstract в Karakter тоже:

public abstract class Karakter
{
    /*
     ...
     ... Same as before
     ...
     */

     public abstract String getRace();
}

Это заставляет подклассы иметь реализацию getRace (что в данном случае не является проблемой, поскольку они в любом случае) и означает, что Karakters теперь может быть уверенным , независимо от того, какого рода Karakter объекта, который он имеет, есть метод getRace () для вызова.

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

1 голос
/ 12 ноября 2009

Вы можете проверить в время выполнения , что является конкретным типом Karakter и привести к соответствующему подтипу.

for(Karakter k : karakters) {
   if (k instanceof Orc) {
       ((Ork)k).getRace();
   } else if (k instanceof Human) {
       ((Human)k).getRace();
   }
}

Кроме того, похоже, что вы могли бы поднять метод getRace() в Karakter, если для Karakter имеет смысл иметь getRace().

class/interface Karakter {
   abstract String getRace();
}

Если для Karakter нет смысла иметь getRace(), например, если есть другой тип Alien extends Karakter, у которого нет getRace(), вы можете абстрагироваться с помощью дополнительного интерфейса:

public interface IRacer {
    abstract String getRace();
}

public class Human extends Karakter implements IRacer { ... }
public class Orc extends Karakter implements IRacer { ... }

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

for(Karakter k : karakters) {
   if (k instanceof IRacer) {
       ((IRacer)k).getRace();
   }
}

Кроме того, похоже, что ваш class Karakters расширяется ArrayList. Не. Пользуйся композицией, а не наследуй, и всегда используй универсальную версию ArrayList<Karakter>.

1 голос
/ 12 ноября 2009

Для вызова getRace (), определенного в Orc или Human, вам нужен объект Orc или Human или один из его производных классов (при условии, что метод не является закрытым в базе) Конечно, если getRace () является общедоступной статической, вы можете использовать имя класса для его вызова из любого места.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...