Вызов метода с одинаковым именем из другого класса - PullRequest
4 голосов
/ 26 марта 2019

У меня есть несколько классов, у которых есть методы с одинаковыми именами.Например,

public class People {
    private Long id;
    private String nm;
    private String nmBn;
    .............
    public Long getId() {
        return id;
    }

    public String getNm() {
        return nm;
    }

    public String getNmBn() {
        return nmBn;
    }
}

public class Company {
    private Long id;
    private String nm;
    private String nmBn;
    .............
    public Long getId() {
        return id;
    }

    public String getNm() {
        return nm;
    }

    public String getNmBn() {
        return nmBn;
    }
}

Затем мне нужен метод, который работает следующим образом:

public String getPeopleString(People people) {
    if (people == null) {
        return "";
    }
    return people.getNmBn() + "|" + people.getNm() + "#" + people.getId();
}

public String getCompanyString(Company company) {
    if (company == null) {
        return "";
    }
    return company.getNmBn() + "|" + company.getNm() + "#" + company.getId();
}

Так что методы делают то же самое, но на объектах другого типа.

Есть ли способ сделать это с помощью одного метода?

Обратите внимание, что я не могу внести никаких изменений в класс People или класс Company.

Ответы [ 2 ]

4 голосов
/ 26 марта 2019

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

String getString(Object companyOrPeople) throws InvocationTargetException, IllegalAccessException
{
    if (companyOrPeople == null) {
        return "";
    }
    final Method getNmBn = companyOrPeople.getClass().getDeclaredMethod("getNmBn");
    final String nmBm = getNmBn.invoke(companyOrPeople).toString();
    // same with the other two methods
    return nmBm + "|" + nm + "#" + id;
}

Однако это не рекомендуется.Вы теряете все гарантии времени компиляции, что эти методы действительно существуют.Ничто не мешает кому-то передавать Integer, String или любой другой тип, у которого нет этих методов получения.

Лучшее, что можно сделать, - это изменить существующие типы, но если вы не можете, вы можете 'т.

Если вы решите изменить существующие типы, сделайте себе одолжение и измените имя атрибутов.Потому что, черт возьми, это nmBn?О, конечно, в каждой компании есть нумбун.Как глупо с моей стороны.

1 голос
/ 26 марта 2019

Во-первых, вы должны создать интерфейс с общими методами, назовем его Identifiable:

public interface Identifiable {

    Long getId();

    String getNm();

    String getNmBn();
}

В идеале вы могли бы заставить и People, и Company реализовать этот интерфейс, но, как вы сказали, вы не можете изменять существующие классы Company и People, вам нужно будет их расширить, и заставить подклассы реализовать интерфейс Identifiable:

public PeopleExtended extends People implements Identifiable { }

public CompanyExtended extends Company implements Identifiable { }

Теперь просто измените методы getCompanyString и getPeopleString на:

public String getIdString(Identifiable id) {
    return id == null ?
           "" :
           id.getNmBn() + "|" + id.getNm() + "#" + id.getId();
}

И, очевидно, используйте подклассы PeopleExtended и CompanyExtended.

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