Можно ли писать виртуальные методы в Java, как это было бы в С++?
Или, есть ли подходящий Java-подход, который вы можете реализовать, который производит подобное поведение? Могу ли я привести несколько примеров?
Можно ли писать виртуальные методы в Java, как это было бы в С++?
Или, есть ли подходящий Java-подход, который вы можете реализовать, который производит подобное поведение? Могу ли я привести несколько примеров?
В Java все нестатические методы выполняются по default " виртуальные функции." Только методы, отмеченные ключевым словом ,, которые нельзя переопределить, наряду с частные методы, которые не являются унаследованные, не виртуальные.
Да. Фактически, все методы экземпляра в Java по умолчанию являются виртуальными. Только определенные методы не являются виртуальными:
Вот несколько примеров:
"Обычные" виртуальные функции
В следующем примере из старой версии страницы википедии, упомянутой в другом ответе.
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.
}
}
Все функции в Java по умолчанию являются виртуальными.
Вам нужно уйти с пути, чтобы написать не виртуальные функции, добавив ключевое слово final.
Это противоположность С++/С# по умолчанию. По умолчанию функции класса не являются виртуальными; вы делаете их так, добавляя "виртуальный" модификатор.
Все не частные методы экземпляра по умолчанию виртуальны в 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.
Да, вы можете писать виртуальные "функции" в Java.
В Java все общедоступные (не частные) переменные и функции по умолчанию являются Виртуальными. Более того, переменные и функции с использованием ключевого слова final не являются виртуальными.