Java for Beginner
742 subscribers
709 photos
201 videos
12 files
1.15K links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Основы ООП в Java

Глава 4. Полиморфизм

Поведение через суперкласс и интерфейс


Полиморфизм (от греч. "много форм") — это способность объектов разных классов отвечать на один и тот же вызов метода по-разному. Это ключевой принцип ООП, который делает код гибким и расширяемым: вы можете работать с объектами через общий тип, не зная их конкретного класса.

Типы полиморфизма в Java:
Compile-time (статический): Через перегрузку методов (overloading) — выбор метода на этапе компиляции.
Runtime (динамический): Через переопределение методов (overriding) — выбор на этапе выполнения, основан на типе объекта.



Поведение через суперкласс: Наследование и overriding

Через суперкласс полиморфизм достигается, когда подкласс переопределяет методы суперкласса. Ссылка суперкласса может указывать на объект подкласса, и вызов метода выполнит версию подкласса (динамическая диспетчеризация).

Пример
// Animal.java
public class Animal {
protected String name;

public Animal(String name) {
this.name = name;
}

public void makeSound() {
System.out.println(name + " издает звук.");
}
}

// Dog.java
public class Dog extends Animal {
public Dog(String name) {
super(name);
}

@Override
public void makeSound() {
System.out.println(name + " лает: Гав!");
}
}

// Cat.java (еще один подкласс)
public class Cat extends Animal {
public Cat(String name) {
super(name);
}

@Override
public void makeSound() {
System.out.println(name + " мяукает: Мяу!");
}
}


Теперь полиморфизм в действии:
public class Main {
public static void main(String[] args) {
Animal animal1 = new Dog("Шарик"); // Ссылка Animal на объект Dog
Animal animal2 = new Cat("Мурка"); // Ссылка Animal на объект Cat

animal1.makeSound(); // Вывод: Шарик лает: Гав! (версия Dog)
animal2.makeSound(); // Вывод: Мурка мяукает: Мяу! (версия Cat)
}
}

Здесь Animal animal1 = new Dog("Шарик"); Тип ссылки — Animal (статический тип), тип объекта — Dog (динамический тип).
Вызов makeSound(): JVM смотрит на динамический тип и вызывает переопределенную версию.


Нюанс: Если метод не переопределен, вызовется версия суперкласса.

Это позволяет писать общий код:

например, массив Animal[] animals = {new Dog(), new Cat()}; и цикл for (Animal a : animals) a.makeSound(); — каждый издаст свой звук.


Поведение через интерфейс: Implements и полиморфизм

Интерфейс — это контракт, определяющий методы без реализации. Полиморфизм через интерфейсы достигается, когда классы реализуют (implements) интерфейс, предоставляя свою реализацию. Ссылка интерфейса может указывать на любой реализующий объект.

Синтаксис:
public interface InterfaceName { void method(); }


Класс:
public class ClassName implements InterfaceName { @Override public void method() { ... } }


Пример интерфейса SoundMaker:
public interface SoundMaker {
void makeSound(); // Абстрактный метод
}


Теперь классы реализуют его:
// Dog.java (теперь implements SoundMaker, без extends для простоты)
public class Dog implements SoundMaker {
private String name;

public Dog(String name) {
this.name = name;
}

@Override
public void makeSound() {
System.out.println(name + " лает: Гав!");
}
}

// Cat.java
public class Cat implements SoundMaker {
private String name;

public Cat(String name) {
this.name = name;
}

@Override
public void makeSound() {
System.out.println(name + " мяукает: Мяу!");
}
}


Полиморфизм:
public class Main {
public static void main(String[] args) {
SoundMaker sound1 = new Dog("Шарик"); // Ссылка интерфейса на Dog
SoundMaker sound2 = new Cat("Мурка");

sound1.makeSound(); // Шарик лает: Гав!
sound2.makeSound(); // Мурка мяукает: Мяу!
}
}


Интерфейс обеспечивает полиморфизм без наследования: классы не связаны иерархией, но объединены контрактом.


#Java #для_новичков #beginner #poliphormizm
👍6
Нюансы полиморфизма через суперкласс и интерфейс

Статический vs динамический тип:
Статический: Тип ссылки (Animal a) — проверяется на компиляции.
Динамический: Тип объекта (new Dog()) — определяет метод на runtime.
Нюанс: Для полей — статический тип (field hiding), для методов — динамический.


Перегрузка vs переопределение:
Перегрузка: Compile-time, разные сигнатуры.
Переопределение: Runtime, одинаковые сигнатуры.


Интерфейсы vs абстрактные классы:
Интерфейсы: Только абстрактные методы (до Java 8), множественная реализация.
Суперклассы: Могут иметь реализацию, состояние, одиночное наследование.


Ошибки:
Если метод не переопределен: Вызов супер/интерфейс версии (или ошибка, если abstract).
Несовместимая сигнатура: Не overriding, а новый метод.
@Override помогает ловить ошибки.

Полиморфизм в коллекциях:
List list = new ArrayList<>(); list.add(new Dog()); — затем цикл по list с вызовом makeSound().

Ограничения:
Private/final/static методы: Не участвуют в полиморфизме.
Конструкторы: Не полиморфны.



Как создать это в IntelliJ IDEA

Создайте интерфейс: New → Interface → SoundMaker.
Implements: В классе Dog: extends/implements, IDE подскажет override.
Полиморфизм: В Main создайте ссылки и протестируйте.



Полезные советы для новичков

Используйте полиморфизм для обобщения: Пишите код для супер/интерфейса, добавляйте подклассы без изменений.
@Override всегда: Избегайте ошибок.
Интерфейсы для контрактов: Когда нужно поведение без состояния.
Ресурсы: Oracle Tutorials on Polymorphism.



#Java #для_новичков #beginner #poliphormizm
👍3🔥2
Основы ООП в Java

Глава 4. Полиморфизм

instanceof и приведение типов

В полиморфизме ссылка суперкласса или интерфейса может указывать на объект подкласса, но статический тип ссылки ограничивает доступ только к методам суперкласса. Чтобы получить доступ к методам подкласса или проверить тип, используются приведение типов и instanceof.

Приведение типов (Casting): Это преобразование ссылки одного типа в другой.

В Java:
Upcasting: Автоматическое приведение к суперклассу или интерфейсу (безопасно).
Downcasting: Явное приведение к подклассу (рискованно, может вызвать ошибку на runtime).


instanceof: Оператор, проверяющий на runtime, является ли объект экземпляром класса, подкласса или реализатором интерфейса. Возвращает boolean.

Это инструменты для безопасной работы с полиморфизмом: сначала проверка instanceof, затем downcasting.


Приведение типов: Upcasting и Downcasting

Upcasting: Автоматическое, безопасное. Ссылка подкласса преобразуется в суперкласс или интерфейс.
Почему: Для полиморфизма — общий код работает с разными объектами.
Нюанс: После upcasting доступны только методы суперкласса.


Пример:
Dog dog = new Dog("Шарик");
Animal animal = dog; // Upcasting: Dog → Animal (автоматически)
animal.makeSound(); // Вызывает версию Dog (полиморфизм)

Здесь animal — тип Animal, но объект Dog.


Downcasting: Явное, с риском. Используйте (Type) перед ссылкой.
Почему: Чтобы получить доступ к методам подкласса через ссылку суперкласса.
Риск: Если объект не того типа — ClassCastException на runtime.


Пример:
Animal animal = new Dog("Шарик");  // Upcasting
Dog dog = (Dog) animal; // Downcasting: Animal → Dog
dog.bark(); // Доступен метод Dog

Работает, потому что объект действительно Dog.


Нюанс: Без проверки:
Animal animal = new Cat("Мурка");
Dog dog = (Dog) animal; // ClassCastException: Cat cannot be cast to Dog



#Java #для_новичков #beginner #poliphormizm #instanceof #Upcasting #Downcasting
👍5
Оператор instanceof: Проверка типа

instanceof проверяет совместимость типов на runtime.

Синтаксис:
object instanceof Type

Возвращает true, если объект является экземпляром Type (класс, интерфейс) или его подтипа.


Нюанс: Для null — всегда false.

С Java 14+: Pattern matching (instanceof с переменной), но для простоты используем классический.

Пример безопасного downcasting:
Animal animal = new Dog("Шарик");

if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark(); // Безопасно
} else {
System.out.println("Не собака!");
}

Проверка предотвращает ClassCastException.


С интерфейсами:
SoundMaker sound = new Dog("Шарик");
if (sound instanceof SoundMaker) { // true
// ...
}


Нюансы instanceof:
Работает с классами, интерфейсами, массивами.
Для примитивов — нет (они не объекты).
В иерархии: Dog instanceof Animal — true; Animal instanceof Dog — false (если объект Animal).
Performance: Не дорогой, но избегайте в горячих циклах.
Альтернативы: getClass().equals(Class.class) — строже, не учитывает подтипы.



Полный пример с полиморфизмом

Используем Animal, Dog, Cat:
public class Main {
public static void main(String[] args) {
Animal[] animals = {new Dog("Шарик"), new Cat("Мурка"), new Animal("Зверь")};

for (Animal a : animals) {
a.makeSound(); // Полиморфизм: каждый свой звук

if (a instanceof Dog) {
Dog d = (Dog) a;
d.bark(); // Только для Dog
} else if (a instanceof Cat) {
Cat c = (Cat) a;
// Специфический метод Cat, если есть
}
}
}
}

Цикл работает с массивом Animal, но проверяет и приводит для специфического поведения.


Нюансы

ClassCastException
: Всегда проверяйте instanceof перед downcasting.
Null: null instanceof Type — false; (Type) null — null (без исключения).
Generics: instanceof не работает с параметризованными типами на runtime (type erasure).
Массивы: Object[] instanceof String[] — false, даже если элементы String.
Интерфейсы: Класс может реализовывать несколько — instanceof true для любого.
Final классы: Не влияет на instanceof.
Performance и дизайн: Избегайте чрезмерного использования instanceof — это признак плохого дизайна (лучше полиморфизм через overriding). Используйте, когда нужно специфическое поведение.
Java 14+ Pattern Matching: if (animal instanceof Dog d) { d.bark(); } — упрощает, но для совместимости используйте классику.



Как создать это в IntelliJ IDEA

Проверка instanceof: IDE подскажет автодополнение.
Генерация: После if (a instanceof Dog) { } — IDE предложит создать переменную.
Debug: Поставьте breakpoint и смотрите типы объектов.



Полезные советы для новичков

Всегда проверяйте перед cast: Избегайте runtime ошибок.
Предпочитайте overriding: Вместо instanceof + cast, переопределяйте методы.
В коллекциях: Полезно для фильтрации типов.


#Java #для_новичков #beginner #poliphormizm #instanceof #Upcasting #Downcasting
👍3