Полиморфизм
Last updated: 3 мая 2025 г.Что же такое полиморфизм
?
Это способность использовать одно и тоже имя для разных задач.
Поясним на примере:
1class Animal {
2 private String eats;
3 private int noOfLegs;
4
5 //То есть например у нас может быть
6 //несколько конструкторов с одним и тем же именем.
7
8 //конструктор без параметров
9 //(конструктор по умолчанию называется)
10 public Animal(){}
11
12 //конструктор с одним параметром
13 //задает значение только eats
14 public Animal(String food){
15 this.eats = food;
16 }
17
18 //конструктор с несколькими параметрами
19 //задает значения обоим полям
20 public Animal(String food, int legs){
21 this.eats = food;
22 this.noOfLegs = legs;
23 }
24
25 //сеттеры и геттеры
26 public String getEats() {
27 return eats;
28 }
29
30 public void setEats(String eats) {
31 this.eats = eats;
32 }
33
34 public int getNoOfLegs() {
35 return noOfLegs;
36 }
37
38 public void setNoOfLegs(int noOfLegs) {
39 this.noOfLegs = noOfLegs;
40 }
41}
42
43class Polimorphism {
44 public static void main(String[] args) {
45 //Теперь создавая объект Animal можно задаться
46 //вопросом, а какой из конструкторов
47 //Animal, которые мы определили будет использован
48 //при создании объекта животного?
49 //Ведь у них же всех одинаковые имена.
50
51 //А собственно тот, который вызывается –
52 //то есть как видим в строке кода ниже
53 //вызывается конструктор с одним параметром.
54 Animal animal = new Animal("Grass");
55 //То есть конструктор выбирается исходя
56 //из параметров переданных в конструктор.
57
58 //В выводе видим, что строка Grass успешно
59 //записалась в поле объекта animal.
60 System.out.println(animal.getEats());
61 }
62}
Вывод:

Также полиморфизм может применяться не только к конструкторам класса, а и методам класса.
Переопределение метода родителя наследником
Под полиморфизмом также понимается переопределение метода класса родителя классом наследником.
То есть, например, в классе Животное есть метод Voice (то есть голос животного), он издает какой-то звук (вообще любой, например alalala) и, например, класс кошки наследует класс животного. При этом, как мы помним, класс кошки наследует все поля и методы класса Животное. Но кошке не нужен метод Voice класса животного, который издает lalala, поскольку ясное дело кошка должна издавать конкретное Мяу, а не lalala.
То есть метод Voice(), который издает lalala может подходить как издаваемый звук классу Животное, но он точно не подходит классу, который наследует от Животного.
Соответственно метод Voice() должен быть переопределен наследником, то есть классом кота, чтобы при вызове Voice() у объекта класса кота выводилось не lalala, а Мяу.
Поясним на примере:
1class Animal {
2 private String eats;
3 private int noOfLegs;
4
5 public Animal(){}
6 public Animal(String food){
7 this.eats = food;
8 }
9 public Animal(String food, int legs){
10 this.eats = food;
11 this.noOfLegs = legs;
12 }
13
14 public String getEats() {
15 return eats;
16 }
17
18 public void setEats(String eats) {
19 this.eats = eats;
20 }
21
22 public int getNoOfLegs() {
23 return noOfLegs;
24 }
25
26 public void setNoOfLegs(int noOfLegs) {
27 this.noOfLegs = noOfLegs;
28 }
29
30 // должен быть переопределен наследником (Полиморфизм)
31 public void Voice(){
32 System.out.println("alalala");
33 }
34}
35
36class Cat extends Animal{
37 private String name;
38 private String color;
39
40 Cat(){}
41 Cat (String catName, String catColor) {
42 name = catName;
43 color = catColor;
44 System.out.println(color);
45 }
46
47 public String getName(){
48 return name;
49 }
50
51 public void setName(String catName){
52 name = catName;
53 }
54
55 public String getColor(){
56 return color;
57 }
58
59 public void setColor(String catColor){
60 color = catColor;
61 }
62
63 //Мы убрали старый метод sayMeow. Пусть теперь кошка
64 //будет издавать Мяу через переопределенный метод Voice()
65 public void Voice(){
66 //Переопределили Voice. Теперь кошка будет говорить Meow.
67 System.out.println("Meow");
68 }
69}
70
71class Polimorphism2 {
72 public static void main(String[] args) {
73 Cat cat = new Cat();
74 //Пусть кошка скажет Мяу
75 cat.Voice();
76 //Если бы мы не переопределили Voice в классе кота
77 //то на консоль вывелось бы alalala. Но кошка не
78 //говорит alalala, это было бы не правильно.
79 }
80}
Вывод:

И, ясное дело, каждое наследующее Animal конкретное животное должно переопределять Voice по своему, будь-то птица или собака.
Метод Voice в классе Animal, можно сказать, просто задавал то, что каждое животное должно издавать какой-то звук, а наследники уже, переопределяя этот метод, задавали какой именно.
Следующие уроки
Абстрактный класс
16
мин.
Интерфейсы в Java
13
мин.
Статические поля
10
мин.