Можете ли вы писать виртуальные функции/методы на Java?

Можно ли писать виртуальные методы в Java, как это было бы в С++?

Или, есть ли подходящий Java-подход, который вы можете реализовать, который производит подобное поведение? Могу ли я привести несколько примеров?

Ответ 1

От wikipedia

В Java все нестатические методы выполняются по default " виртуальные функции." Только методы, отмеченные ключевым словом ,, которые нельзя переопределить, наряду с частные методы, которые не являются унаследованные, не виртуальные.

Ответ 2

Можете ли вы писать виртуальные функции в Java?

Да. Фактически, все методы экземпляра в Java по умолчанию являются виртуальными. Только определенные методы не являются виртуальными:

  • Методы класса (поскольку, как правило, каждый экземпляр содержит информацию, подобную указателю на vtable о его конкретных методах, но здесь нет экземпляра).
  • Частные методы экземпляра (поскольку ни один другой класс не может получить доступ к этому методу, вызывающий экземпляр всегда является типом самого определяющего класса и поэтому недвусмысленно известен во время компиляции).

Вот несколько примеров:

"Обычные" виртуальные функции

В следующем примере из старой версии страницы википедии, упомянутой в другом ответе.

import java.util.*;

public class Animal 
{
   public void eat() 
   { 
      System.out.println("I eat like a generic Animal."); 
   }

   public static void main(String[] args) 
   {
      List<Animal> animals = new LinkedList<Animal>();

      animals.add(new Animal());
      animals.add(new Fish());
      animals.add(new Goldfish());
      animals.add(new OtherAnimal());

      for (Animal currentAnimal : animals) 
      {
         currentAnimal.eat();
      }
   }
}

class Fish extends Animal 
{
   @Override
   public void eat() 
   { 
      System.out.println("I eat like a fish!"); 
   }
}

class Goldfish extends Fish 
{
   @Override
   public void eat() 
   { 
      System.out.println("I eat like a goldfish!"); 
   }
}

class OtherAnimal extends Animal {}

Вывод:

I eat like a generic Animal.
I eat like a fish!
I eat like a goldfish!
I eat like a generic Animal.

Пример с интерфейсами

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

Например:

interface Bicycle {         //the function applyBrakes() is virtual because
    void applyBrakes();     //functions in interfaces are designed to be 
}                           //overridden.

class ACMEBicycle implements Bicycle {
    public void applyBrakes(){               //Here we implement applyBrakes()
       System.out.println("Brakes applied"); //function
    }
}

Пример с виртуальными функциями с абстрактными классами.

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

abstract class Dog {                   
    final void bark() {               //bark() is not virtual because it is 
        System.out.println("woof");   //final and if you tried to override it
    }                                 //you would get a compile time error.

    abstract void jump();             //jump() is a "pure" virtual function 
}                                     
class MyDog extends Dog{
    void jump(){
        System.out.println("boing");    //here jump() is being overridden
    }                                  
}
public class Runner {
    public static void main(String[] args) {
        Dog dog = new MyDog();       // Create a MyDog and assign to plain Dog variable
        dog.jump();                  // calling the virtual function.
                                     // MyDog.jump() will be executed 
                                     // although the variable is just a plain Dog.
    }
}

Ответ 3

Все функции в Java по умолчанию являются виртуальными.

Вам нужно уйти с пути, чтобы написать не виртуальные функции, добавив ключевое слово final.

Это противоположность С++/С# по умолчанию. По умолчанию функции класса не являются виртуальными; вы делаете их так, добавляя "виртуальный" модификатор.

Ответ 4

Все не частные методы экземпляра по умолчанию виртуальны в Java.

В С++ частные методы могут быть виртуальными. Это может быть использовано для идиомы не виртуального интерфейса (NVI). В Java вам необходимо сделать защищенные NVI-методы защищенными.

Из спецификации языка Java, v3:

8.4.8.1 Переопределение (по методам экземпляров) Метод экземпляра m1 объявлено в классе C, переопределяет другой метод, м2, объявленный в классе A, если все следующие верны:

  • C является подклассом A.
  • Подпись m1 является подзаконной (§8.4.2) подписи от м2.
  • В любом       * m2 является общедоступным, защищенным или объявленным с доступом по умолчанию в тот же пакет, что и C, или       * m1 переопределяет метод m3, m3, отличный от m1, m3, отличный от m2, так что m3 переопределяет m2.

Ответ 5

Да, вы можете писать виртуальные "функции" в Java.

Ответ 6

В Java все общедоступные (не частные) переменные и функции по умолчанию являются Виртуальными. Более того, переменные и функции с использованием ключевого слова final не являются виртуальными.