Рубрики
Без рубрики

Чего некоторые люди не знают о полиморфизме

Этот пост был впервые опубликован в моем блоге: https://pleasefindencoded.blogspot.com/2020/04/post-79-what … Помечено как полиморфизм, информатика, java, ооп.

Этот пост был впервые опубликован в моем блоге: Этот пост был впервые опубликован в моем блоге:

В контексте программирования полиморфизм означает – в абстрактных терминах – когда программные конструкции или части кода, например классы или методы, могут быть применены к нескольким объектам разных типов.

Обычно на этом знания большинства людей заканчиваются. Большинство людей не знают, что существуют различные виды полиморфизма. В этом посте я объясню различные типы полиморфизма и расскажу о преимуществах и недостатках каждого из них:

Если люди говорят о полиморфизме, они обычно имеют в виду этот тип полиморфизма. Это также самый простой вид полиморфизма. При подтипировании объект подтипа может использоваться везде, где используется его супертип. Например:

class Supertype {}
class Subtype extends Supertype {}
...
Supertype sup1 = new Supertype();
Supertype sup2 = new Subtype(); 

В приведенном выше примере подтип может использоваться там, где используется супертип.

Другой пример – это:

class MyObject1 {}
class MyObject2 {}

MyObject1 o1 = new MyObject1();
MyObject2 o2 = new MyObject2();
List obList = new ArrayList<>();
obList.add(o1);
obList.add(o2);
obList.add(2);
obList.add("hello");

В приведенном выше примере obList может принимать объекты разных типов – от пользовательских объектов до чисел и строк.

Преимущества

  • Полиморфизм подтипов дает вам гибкость

Недостатки

  • Трудно ограничить гибкость
  • Вы теряете безопасность типов, потому что у вас есть только ограниченный контроль над тем, какой объект разрешено добавлять в контейнер, и если вы извлекаете объект из контейнера, вам нужно привести его к исходному типу, чтобы использовать его осмысленным образом

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

При создании класса вы задаете универсальный тип T . Внутри класса вы обрабатываете универсальный тип так же, как и любой другой тип. При инициализации вы указываете общий тип T для определенного типа. Например:

public class MyObject1 {
    T obj;    
    void setObj(T obj) {
        this.obj = obj;
    }

    T getObj() {
        return this.obj;
    }
}

Допустим, вы хотите применить этот класс только к целым числам, затем вы инициализируете его следующим образом:

MyObject1 object1 = new MyObject1();

В другом экземпляре вы хотите повторно использовать тот же класс, но для другого типа, затем вы инициализируете его другим классом:

MyObject1 object2 = new MyObject1();

Вы можете использовать этот метод не только для одного типа, но и для нескольких типов. Например:

public class KeyValue {
    private K key;    
    private V value;        
    void setKeyValue(K key, V value) {
        this.key = key;
        this.value = value;
    }

    K getKey() {
        return this.key;
    }

    V getValue() {
        return this.value;
    }
}

Преимущества

  • Обычно гораздо более мощный анализ типов во время компиляции

Недостатки

  • Параметрический полиморфизм обеспечивает меньшую гибкость по сравнению с полиморфизмом подтипа
  • Универсальный параметр не знает об атрибутах и методах типа, к которым будет применен в конце

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

Например, у вас есть корзина с различными продуктами питания, и вы хотите знать, какой из этих элементов является самым старым. Используя ограниченный параметрический полиморфизм, вы могли бы реализовать это следующим образом:

public interface Ageable {
    Date getBestBeforeDate();
}
public class FoodBasket {
    private T oldestFood;
    public void put(T food) {
        if (oldestFood == null ||
food.getBestBeforeDate().compareTo(oldestFood.getBestBeforeDate()) < 0) {
            oldestFood = food;
        }
    }

    public T getOldestFood() {
        return oldestFood;
    }
}

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

Допустим, вы хотите использовать корзину для определенного вида продуктов и хотите расширить ее дополнительными функциями, вы бы поступили следующим образом:

public class Egg implements Ageable {
    private Date bestBeforeDate;
    Egg(Date bestBeforeDate) {
        this.bestBeforeDate = bestBeforeDate;
    }

    @Override
    public Date getBestBeforeDate() {
        return this.bestBeforeDate;
    }
}
public class OldEggsBasket extends FoodBasket {
    // additional functions
}

Типы также могут реализовывать несколько интерфейсов. Интерфейсы разделены амперсандом & :

public interface Printable {
    void print();
}
public class FoodBasket {
    private T oldestFood;
    public void put(T food) {
        if (oldestFood == null ||
 food.getBestBeforeDate().compareTo(oldestFood.getBestBeforeDate()) < 0) {
            oldestFood = food;
        }
        food.print();
    }
    //...
 }

Преимущества

  • Пишите повторно используемый код, например библиотечные классы, которые используются другими программистами, которые могут параметризовать в соответствии со своими потребностями

Недостатки

  • Меньшая гибкость по сравнению с вышеупомянутыми видами полиморфизма

Большинство разработчиков, вероятно, уже знают эту концепцию под другим названием: перегрузка. При перегрузке вы предоставляете разные методы с одинаковым именем для При перегрузке вы предоставляете разные методы с одинаковым именем для

При перегрузке вы предоставляете разные методы с одинаковым именем для

  • Гибкость в именовании (перегруженных) методов

Недостатки

  • Никакого повторного использования кода. Поэтому на самом деле это не считается полиморфизмом, как другие виды полиморфизма

Мне интересно, знаете ли вы больше преимуществ и недостатков для каждого из типов полиморфизма.

Оригинал: “https://dev.to/pandaquests/what-some-people-don-t-know-about-polymorphism-3eok”