W Javie wszystkie metody niestatyczne, niefinalne i nieprywatne są wirtualne, ale JVM jest dość sprytna i się może domyśleć, że istnieje tylko jedna implementacja metody i użyć wczesnego wiązania.
JAVA:
public class Animal {
private String name;
public Animal(String name){
this.name = name;
}
public void walk(int distance) {
System.out.println(name + " idzie " + distance);
}
}
public class Dog extends Animal {
public Dog(String name) {
super(name);
}
@Override
public void walk(int distance) {
System.out.printon("Pies " + name + " idzie " + distance);
}
}
public class main {
public static void main(String[] args) {
Animal an = new Animal("cos");
an.walk(10); //cos idzie 10
Animal d = new Dog("doggy");
d.walk(10): //Pies doggy idzie 10
}
}
Jak widzisz przy polimorfiźmie w Javie występuje przed nazwą metody @Override sugerujące, że jest to wersja metody odziedziczonej.
W Javie wszystkie obiekty dziedziczą z klasy Object, dzięki czemu łatwo jest zrobić niektóre rzeczy(jak np. wypisywanie wystarczy utworzyć metodę public String toString(), a nie przeładowywać operator << jak w C++ co dla początkujących bywa dość trudne).
Interfejs w Javie jest porównywalna do deklaracji klasy w C++, z tym, że nie może mieć swojej własnej implementacji(nie licząc metod domyślnych), musi mieć klasy implementujące. Klasa abstrakcyjna musi mieć implementację metod, chyba że też są abstrakcyjne.
C++ (ten sam przykład):
class Animal {
string name;
public:
Animal(std::string name){
this->name = name;
}
virtual void walk(int distance) {
std::cout << name + std::string(" idzie ") + std::to_string(distance) << std::endl;
}
}
class Dog : public Animal {
public:
Dog(std::string name) : Animal(name) {}
void walk(int distance) {
std::cout << std::string("Pies ") + name + std::string(" idzie ") + std::to_string(distance) << std::endl;
}
}
int main(int argc, char** argv)
{
Animal* an = new Animal("cos");
an->walk(10); //cos idzie 10
Animal* d = new Dog("doggy");
d->walk(10): //Pies doggy idzie 10
}
W C++ musisz jawnie zadeklarować, że metoda jest wirtualna, żeby kompilator przygotował odpowiednią tablicę vtable. Musisz jawnie sprecyzować po to, aby program był wydajniejszy. Jeśliby każda metoda była wirtualna jak w Javie to C++ byłby znacznie mniej wydajny przez co miałby mniej zastosowań.
W C++ operator new zwraca wskaźnik, a nie jak w Javie referencję, więc musisz nieco inaczej obsługiwać takie obiekty(właśnie używając operatora ->).