Все началось с того, что я прочитал про static
и про то, что методы помеченные static
не переопределяются. Написал вот такой код, да бы убедиться:
public class Main {
public static void main(String[] args) {
SuperClass.run();
SubClass.run();
}
}
public class SubClass extends SuperClass {
public static void run(){
System.out.println("А SubClass и не думает оставать");
}
}
public class SuperClass {
public static void run(){
System.out.println("SuperClass бежит");
}
}
Вот что он у меня вывел:
SuperClass бежит
А SubClass и не думает оставать.
После этого я задумался почему везде написано что нельзя переопределять, если я переопределил? Но почувствовав себя гением, я зашел на Stackoverflow чтобы спросить совета у гуру разрабов.
Увидел на JavaRush вот такой пример:
class Vehicle{
public static void kmToMiles(int km){
System.out.println("Внутри родительского класса/статического метода");
}
}
class Car extends Vehicle{
public static void kmToMiles(int km){
System.out.println("Внутри дочернего класса/статического метода ");
}
}
public class Demo{
public static void main(String args[]){
Vehicle v = new Car();
v.kmToMiles(10);
}
}
Вообще не понял зачем мы написали Vehicle v = new Car();
не понял что за конструкция, ибо я всегда создавал объект вот так: Vehicle v = new Vehicle();
.
Далее в этом же примере идёт v.kmToMiles(10);
но зачем вообще было создавать объект и через объект вызывать метод если мы работаем со static и "всё" вызывает класс. Помогите пожалуйста!
Переопределение методов позволяет при вызове метода ориентироваться на его Run-time тип.
В то же время, вызов статических функций определяется в compile-time время.
Например:
class Base{
public void kmToMiles(int km){
System.out.println("Base class");
}
}
class Derive extends Base{
public void kmToMiles(int km){
System.out.println("Derive class");
}
}
public class Demo{
public static void main(String args[]){
Base b = new Derive(); // run-time тип - Derive, compile-time тип - Base
b.kmToMiles(10); // "Derive class"
}
}
пример в работе
В данном случае видно, что несмотря на сохранение ссылки в переменную с базовым классом - функция будет вызвана у наследуемого.
В случае же со статическими методами, в момент компиляции будет проверен тип переменной, и так как она объявлена с типом Base
- метод будет вызван именно этого типа.
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
Base b = new Derive(); // run-time тип - Derive, compile-time тип - Base
b.kmToMiles(10); // "Base class"
}
}
class Base{
public static void kmToMiles(int km){
System.out.println("Base class");
}
}
class Derive extends Base{
public static void kmToMiles(int km){
System.out.println("Derive class");
}
}
пример в работе
Так как определение какой метод будет вызван происходит в момент компиляции, а не в момент выполнения данный случай нельзя назвать переопредением, и в данном случае это перекрытие, так как метод базового класса перекрывается методом наследника
Вот тебе некорректный пример который поможет разобраться:
SubClass subClass = null;
subClass.run()
Тут не будет ошибки NullPointerException как кто-то мог бы подумать, только предупреждение от компилятора. А код выведет "А SubClass и не думает оставать".
SubClass subClass = null;
((SupperClass) subClass).run();
А этот код выведет: "SuperClass бежит"
Все потому, что эти методы так называемы статические методы классов, компилятор превратит код выше в такие однозначные вызовы:
SubClass.run();
SupperClass.run();
А вот методы экземпляров классов можно подменять/переопределять, например подменим метод run() класса Thread на свой собственный:
new Thread() {
@Override public void run() {
System.out.println("Hello new thread: " + Thread.currentThread());
}
}.start();
Thread.sleep(1000);
Логика в классе Thread не знает что мы что-то там подменили, она вызовет вроде свой метод run() а по факту будет исполнен наш.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Я новичек, учу Hibernate и вот столкнулся с проблемойПри первом добавлении в БД, создает три таблицы из которых одна отображает связи - казалось...
Я делаю конвертер и мне нужно, чтобы я выбирал в одном choiceBox одну валюту, в другом другую и курс менялсяСами choiceBox`ы у меня есть