Наследование коллекций

156
07 ноября 2019, 23:10

В моей программе реализован абстрактный класс Users от которого наследуются классы Worker и Customer. Я хочу создать списки пользователей отдельно для Worker и Customer. У этих списков довольно похожий функционал. Вопрос: Могу ли я как то реализовать методы в абстрактном классе чтобы я мог применить их на все ArrayList'ы в моей программе или для каждого списка нужно реализовывать методы отдельно? Про наследование коллекций не смог найти понятной инфы. Я пытался использовать Raw - тип и дженерики, но тогда эти методы не работают для Worker и Customer списков. Пример моего использования находится после кода.

Код:

package BankCode;
public abstract class User {
    private String name, surname, lastname;
    private String login, password;
public User(String name, String surname, String lastname, String login, String password){
    this.name = name;
    this.surname = surname;
    this.lastname = lastname;
    this.login = login;
    this.password = password;
}
public String getName() {
    return name;
}
public String getSurname() {
    return surname;
}
public String getLastname() {
    return lastname;
}
public String getLogin() {
    return login;
}
public String getPassword(){
    return password;
}
public abstract void Im();
}
package BankCode;
public class Customer extends User {
    private boolean count, card;
    public Customer(String name, String surname, String lastname, String login, String password){
        super(name, surname, lastname, login, password);
    }
    public void PutMoneyOnAcc(){}
    public void WithdrawFromCard(){}
    public void TransferCardAcc(){}
    public void Im(){
        System.out.print("Я посетитель");
    }
}
package BankCode;
public class Worker extends User {
    public Worker(String name, String surname, String lastname, String login, String password){
        super(name, surname, lastname, login, password);
    }
    public void OpenAccount(){}
    public void CreateCard(){}
    public void CloseCount(){}
    public void CreateAccount(){}
    public void Im(){
        System.out.print("Я рабочий");
    }
}

Пример использования дженериков:

package BankCode;
import java.util.List;
abstract class UserList {
private boolean loginCheck(String login, List<?> b){
    boolean availability = true;
    for (Object u : b){
        if (login.equals(u.getLogin())) availability = !availability;
    }
    return availability;
}
boolean addUser(User a, List<?> b){
    boolean adding = true;
    if (loginCheck(a.getLogin(), b))b.add(a);
    else adding = false;
    return adding;
    }
}

В этом примере возникает ошибка когда я пытаюсь обратиться к методу a.getLogin. А при использовании Raw - типа выдаёт ошибку когда я пытаюсь передать ArrayList<Worker> в метод addUser.

Answer 1

Ваш код избыточный. Все переменные типа boolean фактически лишние. Ваш метод loginCheck имеет модификатор доступа private , это значит, что к нему может обратиться исключительно метод addUser. Поскольку тип возвращаемого значения у двух методах boolean , то вполне логично если метод addUser после проверки условия и обращения к методу loginCheck будет возвращать значение, которое вернул метод loginCheck (инче смысла в возвращаемом значении метода loginCheck нет!). Посему Ваша проблема решается примерно так:

import java.util.List;
abstract class UserList<T extends User> {
    private boolean loginCheck(final String login, final List<T> b) {
        return b.stream().noneMatch(t -> login.equals(t.getLogin()));
    }
    boolean addUser(final T t, final List<T> b) {
        return loginCheck(t.getLogin(), b) ? b.add(t) : false;
    }
}
Answer 2

Я думаю наследоваться от коллекций нормальная практика, вот пример org.jsoup.select.Elements реализует это таким образом

  1. Содержит в себе приватный список(!).

    public class Elements implements List<Element>, Cloneable {
        private List<Element> contents;
    ...
    }
    
  2. Конструкторы, которые предоставляю исчерпывающий функционал инициализации

    public Elements() {
        this.contents = new ArrayList();
    }
    public Elements(int initialCapacity) {
        this.contents = new ArrayList(initialCapacity);
    }
    public Elements(Collection<Element> elements) {
        this.contents = new ArrayList(elements);
    }
    public Elements(List<Element> elements) {
        this.contents = elements;
    }
    public Elements(Element... elements) {
        this(Arrays.asList(elements));
    }
    
  3. Внутренний функционал использует итератор.

    public Elements addClass(String className) {
        Iterator i$ = this.contents.iterator();
        while(i$.hasNext()) {
            Element element = (Element)i$.next();
            element.addClass(className);
        }
        return this;
    }
    public Elements removeClass(String className) {
        Iterator i$ = this.contents.iterator();
        while(i$.hasNext()) {
            Element element = (Element)i$.next();
            element.removeClass(className);
        }
        return this;
    }
    
  4. Специальные методы доступа.

    public Element first() {
        return this.contents.isEmpty() ? null : (Element)this.contents.get(0);
    }
    public Element last() {
        return this.contents.isEmpty() ? null : (Element)this.contents.get(this.contents.size() - 1);
    }
    
  5. Реализацию интерфейса List, делегируем нашему приватному полю.

    public <T> T[] toArray(T[] a) {
        return this.contents.toArray(a);
    }
    public boolean add(Element element) {
        return this.contents.add(element);
    }
    public boolean remove(Object o) {
        return this.contents.remove(o);
    }
    
READ ALSO
Как подставлять значения в нужные поля средствами spring при написании тестов?

Как подставлять значения в нужные поля средствами spring при написании тестов?

Требуется написать тесты с использованием restTemplate чтобы протестировать рест-сервисы на спринге

157
Как реализовать тайм-аут на кнопке?

Как реализовать тайм-аут на кнопке?

Я хочу поставить на кнопку что-то вроде таймера, то есть у меня есть кнопка, после нажатия она становится неактивной, скажем, на 2 часа, через...

158
Парсинг ассоциативных массивов json java

Парсинг ассоциативных массивов json java

Мне нужно спарсить данные в следующие классыЯ раньше не сталкивался с JSON

115
RecyclerView многосоставной

RecyclerView многосоставной

Нужно реализовать RecyclerView в котором должен быть заголовок и под ним список который зависит от данных БДПо началу сделал несколько RecyclerView...

111