Задать вопрос
@zaorduu
учу java, надеюсь на лучшее

Ковариантность возвращаемых типов в Javа, я правильно понял суть?

Читаю книгу "Философия java" Брюса Эккеля и дошел до небольшого раздела о ковариантности возращаемых типов в Java. Никак не могу понять, правильно ли я понял в чём идея? Пример кода :
package com.company;

public class Main {
    public static void main(String[] args) {
        Shape s;
        s = new BuildCircle().build();
        System.out.println(s);
        s.methodShape(); 
    }
}

class Shape {
    public String toString() {
        return "Shape";
    }
    public void drawShape(){
        System.out.println("draw Shape");
    }
}

class Circle extends Shape {
    public String toString() {
        return "Circle";
    }
    public void drawShape(){
        System.out.println("draw Circle");
    }
}

class BuildShape {
    Shape build() {
        return new Shape();
    }
    public void BuildingShape(){
        System.out.println("Building Shape");
    }
}

class BuildCircle {
    Circle build() {
        return new Circle();
    }
    public void BuildingCircle(){
        System.out.println("Builiding Circle");
    }
}

output:
Circle
draw Circle

Я так понимаю, на выходе мы получаем объект shape преобразованый к circle (более "специализированый" объект).
В результате чего все его методы переопределились, на те, который находятся в классе Circle, но, объект не получил новых методов, лишь переопределил свои собственные на те, что находятся в производном классе
Какое-то недонаследование в обратную сторону выходит.
Правильно ли я понял в чём заключается суть ковариантности? Если нет подскажите ресурс (можно и на английском) где можно почитать об этом более подробно. Заранее спасибо
  • Вопрос задан
  • 645 просмотров
Подписаться 2 Простой 1 комментарий
Решения вопроса 1
@Mercury13
Программист на «си с крестами» и не только
Ковариантность начинается, когда мы делаем class BuildCircle extends BuildShape.
(Лучше BuildShape оформить как интерфейс, а не как класс, но шут с ним.)

Ковариантность связана с принципом подстановки Лисков: чтобы потомок вписывался в контракт, установленный предком, он может ужесточать требования к себе (скажем, выдавать более узкий тип) и ослаблять требования к другим (скажем, принимать поток реального времени вроде консоли/сокета — а не только файл, который знает себе длину и позволяет перемотку).

Вот это «выдавать более узкий тип, чем полагает предок» — и есть ковариантность.

Обратное — принимать поток реального времени, а не только файл — называется контравариантность. Насколько мне известно, в Java на уровне языка её нет, но какие-то части ухитряются делать через шаблоны.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы