it-swarm.com.ru

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

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

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

139
yonatan

Из Википедия

В Java все нестатические методы являются по умолчанию "virtual functions." Only методы, помеченные ключевым словом final, который нельзя переопределить вместе с private методы, которые не являются наследуются, являются не виртуальными.

262
Klaus Byskov Pedersen

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

Да. Фактически, все методы экземпляра в 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 {}

Результат:

 Я ем как универсальное животное .
 Я ем как рыба! 
 Я ем как золотая рыбка! 
 Я ем как универсальное животное .

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

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
    }
}

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

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

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.
    }
}
86
Eric Leschinski

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

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

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

54
duffymo

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

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

Из спецификации языка Java, версия 3:

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

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

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

2
RepDetec

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

0
Parvej Ahmed