Выбор метода Java с перегрузкой и переопределением

Мне трудно понять некоторые принципы переопределения и перегрузки.

public class Figure{
    public void stampa(Figure f){
        System.out.println("Figure");
    }
}
public class Square extends Figure{
    public void stampa(Square q){
        System.out.println("Square");
    }
}
public class Rectangle extends Square{
    public void stampa(Rectangle r){
        System.out.println("Rectangle");
    }
    public void stampa(Square r){
        System.out.println("Particular Rectangle");
    }
    public void stampa(Figure f){
        System.out.println("Particular Figure");
    }
}

public class Test{
    public static void main(String args[]){

        Figure f1,f2;
        Square q = new Rectangle();
        Rectangle r = new Rectangle();
        f1 = new Square();
        f2 = new Rectangle();

        f1.stampa(f2); //Figure
        q.stampa(r); //Particular Rectangle 
        f1.stampa(q); //Figure
        q.stampa(f1); //Particular Figure 
        q.stampa(q); //Particupar Rectangle
    }
}

я знаю это public void stampa(Square q) перегружает public void stampa(Figure f) и не отменять это.

А также public void stampa(Rectangle r) а также public void stampa(Figure f) также перегружены public void stampa(Square q),

Также public void stampa(Square q) в классе Rectangle переопределяет метод в классе Square.

Первый вопрос

это об этом результате: q.stampa(f1); //Particular Figure Я знаю что во время компиляции q является Square так что я буду смотреть на этот метод public void stampa(Square q)в Square учебный класс. и во время выполнения q является Rectangle поэтому я подумал, что результатом может быть "Конкретный прямоугольник" вместо "Конкретная фигура"

Не уверен что я делаю не так

Второй вопрос

Если в этот момент Rectangle продолжается Figure и не больше SquareУ меня наверняка будет ошибка компиляции на Square q = new Rectangle(); что происходит с варибале q (там будет иметь такую ​​переменную как Square q или у нас нет никакой переменной с именем q?) и каков будет результат q.stampa(f1);

Спасибо и извините за мой английский и, пожалуйста, поправьте меня, если я ошибаюсь в какой-то момент.

2 ответа

Решение

Я знаю что во время компиляции q является Square так что я буду смотреть на этот метод public void stampa(Square q)в сквере

Ты забываешь это Square содержит два метода: stampa(Square q) а также stampa(Figure f), Последний наследуется от Figure и выбирается во время компиляции как наиболее подходящая перегрузка.

и во время выполнения q Rectangle, поэтому я подумал, что результатом может быть "Конкретный прямоугольник" вместо "Конкретная фигура"

Перегрузки выбираются во время компиляции и переопределяются во время выполнения. Как указано, stampa(Figure f) уже выбран во время компиляции. Как только он на самом деле вызывается, среда выполнения видит, что q это пример Rectangle и делегирует вызов Rectangle.stampa(Figure f),

Что касается второго вопроса, я не очень понимаю, что вы спрашиваете. Ошибка компиляции означает, что код неверен и ничего не происходит. q.stampa(f1) никогда не будет вызван и никогда не вернет результат.

Первый вопрос:

qОбъявленный тип - Квадрат. f1Объявленный тип - рисунок. Таким образом, компилятор ищет метод с именем stampa в классе Square и его суперклассах, если существует метод, принимающий рисунок (или суперкласс Figure). Находится на рисунке: public void stampa(Figure f), Во время компиляции важен объявленный тип переменной.

Теперь, во время выполнения, фактический тип времени выполнения объекта, на который ссылается q рассматривается: это прямоугольник. Таким образом, среда выполнения ищет метод public void stampa(Figure f) который переопределяет метод Figure в Rectangle и все его суперклассы до Figure. Вот что позволяет полиморфизм. Он находит один в прямоугольнике:

public void stampa(Figure f) {
    System.out.println("Particular Figure");
}

Второй вопрос:

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

Другие вопросы по тегам