Java наследование, методы
Мучаюсь весь вечер, не могу реализовать пару моментов. Разработать приложение для вычисления результирующей информации об объектах, описанных с помощью наследования: • Базовый класс «Рабочий» (Worker). Класс имеет следующие поля: имя (name), возраст (age) и зарплата (salary) и методы: setName, getName, setAge, getAge, setSalary, getSalary. • Класс Worker1, производный от класса Worker имеет дополнительный метод checkAge, который будет проверять возраст на корректность (от 1 до 100 лет). Этот метод должен использовать метод setAge перед уста-новкой нового возраста (если возраст не корректный - он не должен ме-няться) • Класс Worker2, производный от класса Worker1, проверяет корректность зарплаты: положительное число, больше прожиточного минимума и меньше некоторого предельного числа.
- Создать список работников на основе класса Worker2
- Обеспечить возможность поиска в списке по различным полям (имя. возраст, диапазон зарплат) Классы есть, Worker работает отлично, Searcher тоже, то есть, поиск в списке по полям реализован. Как сделать Worker1 с методом checkAge и Worker2 с проверкой на корректность? В java далеко не силен, поэтому проблема.
Worker.java
package com.company;
public class Worker {
public String name;
public int age;
public int salary;
// private final String name;
// private final int age;
// private final int salary;
public Worker(String name, int age, int salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int getSalary() {
return salary;
}
@Override
public String toString() {
return "Worker{" + "name=" + name + ", age=" + age + ", salary=" + salary + "}\n";
}
}
WorkerSearcher.java
package com.company;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
public class WorkerSearcher {
private String name;
private Integer minAge;
private Integer maxAge;
private Integer minSalary;
private Integer maxSalary;
public WorkerSearcher setName(String name) {
this.name = name;
return this;
}
public WorkerSearcher setMinAge(Integer minAge) {
this.minAge = minAge;
return this;
}
public WorkerSearcher setMaxAge(Integer maxAge) {
this.maxAge = maxAge;
return this;
}
public WorkerSearcher setMinSalary(Integer minSalary) {
this.minSalary = minSalary;
return this;
}
public WorkerSearcher setMaxSalary(Integer maxSalary) {
this.maxSalary = maxSalary;
return this;
}
public List<Worker> search(Collection<Worker> workers) {
return workers.stream()
.filter(worker->name == null || worker.getName().equals(name))
.filter(worker->rangeOf(worker.getAge(), minAge, maxAge))
.filter(worker->rangeOf(worker.getSalary(), minSalary, maxSalary))
.collect(Collectors.toList());
}
private boolean rangeOf(Integer value, Integer min, Integer max) {
if (min==null && max==null) return true;
if (min!=null && max==null && min<=value) return true;
if (max!=null && min==null && max>=value) return true;
if (max!=null && min!=null && max>=value && min<=value) return true;
return false;
}
}
Worker1.java
package com.company;
public class Worker1 extends Worker {
public Worker1(String name, int age, int salary) {
super(name, age, salary);
}
}
Worker2.java
package com.company;
public class Worker2 extends Worker1{
public Worker2(String name, int age, int salary) {
super(name, age, salary);
}
public void checkSalary(){
if (salary > 0) {
System.out.println("Зарплата " + name + " - положительное число");
} else System.out.println("Зарплата " + name + " - отрицательное число");
if (salary > 12038) {
System.out.println("Зарплата " + name + " выше прожиточного минимума");
} else System.out.println("Зарплата " + name + " ниже прожиточного минимума");
if (salary < 100000) {
System.out.println("Зарплата " + name + " ниже предельного числа");
} else System.out.println("Зарплата " + name + " выше предельнего числа");
}
}
Main.java
package com.company;
import java.util.ArrayList;
//import java.util.Scanner;
//import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Worker> workers = new ArrayList<>();
workers.add(new Worker("Ivan", 25, 12000));
workers.add(new Worker("Sergey", 22, 9800));
workers.add(new Worker("Michael", 32, 123000));
workers.add(new Worker("Vladislav", 45, 6500));
workers.add(new Worker("Nikolay", 19, 12200));
workers.add(new Worker("Valery", 37, 32500));
List<Worker> result = new WorkerSearcher()
.setMinSalary(9500)
.setMaxSalary(33000)
.setMaxAge(36)
.search(workers);
System.out.println(result);
}
}
Ответы (2 шт):
В данном случае вы находитесь в заложниках у своего конструктора и финальных полей. Боюсь, что самый простой способ реализации - избавиться от указанных проблем, но придется немного переписать код. Во-первых, убираем модификатор final со всех полей и конструктор с параметрами. Во-вторых, для инициализации полей добавим сеттеры. При этом все сеттеры будут возвращать this, т.е. самого себя. В целом так делать нехорошо, но я боюсь, что вам не знаком паттерн билдер, а стандартные сеттеры усложнят инициализацию экземпляров класса worker. Ну и, собственно, все, теперь можно наследоваться и переопределять нужные нам сеттеры.
public class Worker {
private String name;
private int age;
private int salary;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int getSalary() {
return salary;
}
public Worker setName(String name) {
this.name = name;
return this;
}
public Worker setAge(int age) {
this.age = age;
return this;
}
public Worker setSalary(int salary) {
this.salary = salary;
return this;
}
@Override
public String toString() {
return "Worker{" + "name=" + name + ", age=" + age + ", salary=" + salary + '}';
}
}
public class Worker1 extends Worker{
@Override
public Worker setAge(int age) {
return age>0 && age<=100 ? super.setAge(age): this;
}
}
public class Worker2 extends Worker{
private final static int LIVING_WAGE = 12_038;
private final static int SAKARY_LIMIT = 100_000;
@Override
public Worker setSalary(int salary) {
return salary<LIVING_WAGE || salary>SAKARY_LIMIT ? this : super.setSalary(salary);
}
}
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Worker> workers = new ArrayList<>();
workers.add(new Worker().setName("Ivan").setAge(25).setSalary(12000));
workers.add(new Worker1().setName("Sergey").setAge(22).setSalary(9800));
workers.add(new Worker2().setName("Artem").setAge(48).setSalary(54000));
List<Worker> result = new WorkerSearcher()
.setMinSalary(10000)
.setMaxAge(40)
.search(workers);
System.out.println(result);
System.out.println("*** TEST 'SET AGE'***");
workers.get(1).setAge(105);
System.out.println(workers);
workers.get(1).setAge(23);
System.out.println(workers);
System.out.println("*** TEST 'SET SALARY'***");
workers.get(2).setSalary(200_000);
workers.get(2).setSalary(0);
System.out.println(workers);
workers.get(2).setSalary(55000);
System.out.println(workers);
}
}
А мне кажется не нужно тут сильно заморачиваться, в плане, что сеттеры должны возвращать this. Это дико странно. Каждый класс просто добавляет новый функционал. Вот просто берите и реализуйте в нужном классе нужные методы. А в классе Worker2 используйте весь функционал