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

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

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

6 ответов


с Википедия

на Java, все нестатические методы по по умолчанию "виртуальные функции." только методы, отмеченные ключевое слово final, который нельзя отменить, вместе с частные методы, которые не в наследство, являются non-virtual.


можете ли вы писать виртуальные функции на 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 методы интерфейса все виртуальный. Они!--33-->должны быть виртуальными, потому что они полагаются на классы реализации для предоставления реализаций метода. Код для выполнения будет выбран только во время выполнения.

например:

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".

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


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

В C++, частные методы могут быть виртуальными. Это можно использовать для идиомы non-virtual-interface (NVI). В Java вам нужно будет защитить переопределяемые методы NVI.

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

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

  1. C является подклассом А.
  2. подпись M1 подподписью (§8.4.2) подписи м2.
  3. либо * m2 является общедоступным, защищенным или объявленным с доступом по умолчанию в пакет C или * m1 переопределяет метод m3, M3, отличный от M1, m3, отличный от m2, таким образом, что m3 переопределяет m2.

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


в Java все открытые (не частные) переменные и функции являются виртуальный по умолчанию. Кроме того, переменные и функции с помощью ключевого слова финал не виртуальный.