java полиморфизм

98
06 июля 2021, 02:00

Использование дочернего класса в качестве родительского класса

Важным аспектом полиморфизма является возможность использовать объект дочернего класса, где ожидается объект его родительского класса. Один из способов сделать это явно - создать экземпляр объекта дочернего класса в качестве члена родительского класса.

Теперь вопрос

ЗАчем

Noodle biangBiang = new Spaghetti();

если мы можем написать и результат получим один и тот же

Spaghetti biangBiang = new Spaghetti();

Пример всего кода

class Noodle {
  protected double lengthInCentimeters;
  protected double widthInCentimeters;
  protected String shape;
  protected String ingredients;
  protected String texture = "brittle";
  Noodle(double lenInCent, double wthInCent, String shp, String ingr) {
    this.lengthInCentimeters = lenInCent;
    this.widthInCentimeters = wthInCent;
    this.shape = shp;
    this.ingredients = ingr;
  }
  public String getCookPrep() {
    return "Boil noodle for 7 minutes and add sauce.";
  }
  public static void main(String[] args) {
    Noodle n = new Noodle(30.0, 0.2, "round", "semolina flour");
    System.out.println(n.getCookPrep());
    Spaghetti a = new Spaghetti();
    System.out.println(a.getCookPrep());

  }
}
class Spaghetti extends Noodle {
  Spaghetti() {
    super(30.0, 0.2, "round", "semolina flour");
  }
  public String getCookPrep() {
    return "Boil spaghetti for 8 - 12 minutes and add sauce, cheese, or oil and garlic.";
  }
}

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

Answer 1

Например, для этого

public static void main(String[] args) {
    Noodle n = new Noodle(30.0, 0.2, "round", "semolina flour");        
    Spaghetti a = new Spaghetti();        
    printCookPrep(n);
    printCookPrep(a);
}
public static void printCookPrep(Noodle n){
    System.out.println(n.getCookPrep());
}
Answer 2

Например, у вас имеется база данных сотрудников фирмы. В ней есть абстрактный класс "Сотрудник" (который имеет поля имя и зарплата, а также методы доступа к ним), и от него наследуются более конкретные "Менеджер", "Программист", "Уборщик" и т.д., которые имеют свои более специфические состояния и поведения.

И вот задача: вывести список всех сотрудников и их зарплату в один файл.

Для абстрактных классов можно создавать объектные переменные, но такие переменные должны ссылаться на объект неабстрактного класса. Если заранее собирать в список всех сотрудников, то такая задача решится за один обход коллекции.

public abstract class Employee {
    private String name;
    private Integer pay;
    public void setName(String aName) {
        name = aName;
    }
    public String getName() {
        return name;
    }
    public void setPay(int value) {
        pay = value;
    }
    public Integer getPay() {
        return pay;
    }
}
public class Coder extends Employee {
    private String position;
    public Coder(String name, int pay, String _position) {
        setName(name);
        setPay(pay);
        setPosition(_position);
    }
    public void setPosition(String value) {
        position = value;
    }
    public String getPosition() {
        return position;
    }
}

public class Manager extends Employee {
    public Manager(String name, int pay) {
        setName(name);
        setPay(pay);
    } 
}
public class TEST {
    public static void main(String[] args) {
        LinkedList<Employee> employees = new LinkedList<Employee>();
        // Нанимаем менеджера
        employees.add(new Manager("John", 25000));
        // Нанимаем программиста
        Coder coder1 = new Coder("Nick", 30000, "Junior");
        employees.add(coder1);
        // Нанимаем ещё менеджера
        Manager manager1 = new Manager("Cameron", 25000);
        employees.add(manager1);
        // Выводим список всех сотрудников
        for (Employee current : employees) {
            System.out.println(current.getName() + " - " + current.getPay().toString());
        }
    }
}

Вот пример реализации принципа полиморфизма, к объектам подкласса можно обращаться из ссылочных переменных их суперкласса. НО здесь например нельзя будет из коллекции вызвать метод setPosition для объекта класса Coder, так как класс Employee не имеет о нём понятия.

employees.get(1).setPosition("Middle"); //error: cannot find symbol
// правильное решение, однако для этого необходимо проверять, является ли данный объект коллекции объектом требуемого класса, например используя instanceof
Coder myCoder = employees.get(1);
myCoder.setPosition("Middle");

Могу посоветовать книгу Кей Хорстманна "Java Библиотека профессонала" том 1. В главе о "Наследование" об этом рассказывается подробнее и с примерами кода.

READ ALSO
JS - Передача функции в Web Worker

JS - Передача функции в Web Worker

Всем приветПредположим есть файл - script1

80
Webpack. Ошибка после обновления

Webpack. Ошибка после обновления

Всем приветПосле обновления webpack с версии 2

106
Как использовать ymaps.geocode на react?

Как использовать ymaps.geocode на react?

Для достижения цели:

104