Выбор метода 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 не имеют смысла: такой переменной не будет, поскольку код не компилируется, и, следовательно, класс не генерируется компилятором.