192

Is it possible to write virtual methods in Java, as one would do in C++?

Or, is there a proper Java approach which you can implement that produces similar behavior? Could I please have some examples?

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
yonatan
  • 2,133
  • 3
  • 15
  • 8

6 Answers6

343

From wikipedia

In Java, all non-static methods are by default "virtual functions." Only methods marked with the keyword final, which cannot be overridden, along with private methods, which are not inherited, are non-virtual.

Aditya
  • 4,453
  • 3
  • 28
  • 39
Klaus Byskov Pedersen
  • 117,245
  • 29
  • 183
  • 222
  • 5
    [Here](http://stackoverflow.com/a/295248/689991) is one of [Jon Skeet](http://stackoverflow.com/users/22656/jon-skeet)'s answer. – Quazi Irfan Apr 20 '15 at 08:49
  • I wonded if it's really true, because for what I've read, in Java, dynamic method dispatch happens only for the object the method is called on - as explained [here](http://stackoverflow.com/questions/1572322/overloaded-method-selection-based-on-the-parameters-real-type) so the example explaining virtual functions for C++ [here](http://stackoverflow.com/questions/2391679/why-do-we-need-virtual-functions-in-c) is not valid for java. – Broccoli Dec 07 '16 at 16:42
  • @QuaziIrfan That is difference between Java and C# though. – Sreekanth Karumanaghat Dec 24 '19 at 06:09
  • A final method in Java still can be virtual. For example, we have a `Base` class with `some` method, and `Derived` class that extends `Base` and has its own implementation of `some` method marked by `final` reserved word. The `some` method is still virtual. – Andrey Feb 01 '23 at 19:38
110

Can you write virtual functions in Java?

Yes. In fact, all instance methods in Java are virtual by default. Only certain methods are not virtual:

  • Class methods (because typically each instance holds information like a pointer to a vtable about its specific methods, but no instance is available here).
  • Private instance methods (because no other class can access the method, the calling instance has always the type of the defining class itself and is therefore unambiguously known at compile time).

Here are some examples:

"Normal" virtual functions

The following example is from an old version of the wikipedia page mentioned in another answer.

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

Output:

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

Example with virtual functions with interfaces

Java interface methods are all virtual. They must be virtual because they rely on the implementing classes to provide the method implementations. The code to execute will only be selected at run time.

For example:

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

Example with virtual functions with abstract classes.

Similar to interfaces Abstract classes must contain virtual methods because they rely on the extending classes' implementation. For Example:

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.
    }
}
Avi
  • 2,611
  • 1
  • 14
  • 26
Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
  • 2
    This has got to be the most complete answer. It provides 2 ways to implement a virtual function since java does not have the keyword. Thank you. – Christopher Bales Aug 31 '14 at 01:12
  • Much better answer than the Wikipedia citation. Coming from c++ and being lazy with my Java studies, abstract was what I was looking for. – David Jan 06 '15 at 03:25
  • @David How is this answer better? The wikipedia citation is complete, concise and correct. This answer, by contrast, fails to mention the elephant in the room: By default *all* functions in Java (with the exceptions listed in the wikipedia article) are virtual. Neither abstract classes nor interfaces are necessary for virtual functions, so that's only adding misleading noise. And then this "requires great communication skills and a deep mastery of underlying principles"... jeez. That is a self-falsifying statement right there: Nobody who had that would waste valuable disk space with it. – Peter - Reinstate Monica Nov 05 '15 at 11:08
  • The wikipedia post is inferior and less specific to this answer because it is about the concept of virtual functions in any language, rather than just java. The example given in the wikipedia page is written in C, and it's an incomplete one at best, and it's more misleading. The detail about all functions being virtual, and that you don't need abstract classes or interfaces to have virtual functions being noise. I never said they are required, you misread that. I'm not understanding your final point, do you want me to delete this question because you don't like it? – Eric Leschinski Nov 05 '15 at 12:21
  • **1.** The wikipedia citation in the post *starts with "In Java".* One can't get any more specific than that. (The wikipedia article has since changed and doesn't contain that sentence any longer.) I'm fairly sure that the examples didn't include C, by the way. (C++ though, yes.) **2.** The examples are misleading because they have no relation to Java having virtual functions by default. **3.** I meant: No person who has great communication skills and deep mastery of the underlying principles would write that. I was not refering to the entire article. – Peter - Reinstate Monica Nov 05 '15 at 14:27
  • The entire discussion underneath this question is not what the stackoverflow comment system was designed for. The first comment boils down to: "thanks", the second comment basically says: "It's better than something else... thanks!" and the 3rd 4th and 5th is just quibbling over whether or not this question is in fact different from some other resource on some totally unrelated site. If I could remove all six of these comments I would, because we are missing the point, which is how do I improve this post further? The upvotes have spoken, the answer is fine, the answer stays. – Eric Leschinski Nov 05 '15 at 14:33
  • And how is `myJavaFoobarClass` generic in any sense that the word carries in the realm of programming? – Peter - Reinstate Monica Nov 05 '15 at 14:34
  • OK the class is not technically generic. I fixed that. – Eric Leschinski Nov 05 '15 at 14:37
  • I'm not quibbling. I have pointed out the following specific deficiencies of this answer. I'll repeat: **1.** The answer doesn't state the most important fact which any suitable answer must provide in order to be useful. **2.** It introduces two concepts (abstract classes and interfaces) which are special applications of Java polymorphism. This is misleading because the general concept (all functions are virtual anyway) is never mentioned. The reader could think that he *needs* an abstract class or an interface for virtual functions. [t.b.c] – Peter - Reinstate Monica Nov 05 '15 at 14:41
  • [ctd] **3.** I criticised, somewhat polemically, the pretentious style which is in conspicuous contrast to the poor quality of the post.-- The problem is that the post at best adds two example applications /specific constructs for Java virtual functions. These specific examples, but also much of the general explanations in the second paragraph are unnecessary if a basic programming and Java knowledge is supposed, which we can if we consider the question. – Peter - Reinstate Monica Nov 05 '15 at 14:43
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/94348/discussion-between-eric-leschinski-and-peter-schneider). – Eric Leschinski Nov 05 '15 at 15:16
  • I have edited the answer instead, making the central statement stand out, adding a plain example and eliminating the `final` example. (That a class or method is final does not prevent them from taking part in dynamic dispatch!). – Peter - Reinstate Monica Nov 05 '15 at 16:56
  • Perhaps I phrased my comment badly. I should have prefixed it with 'For me, '. The Wikipedia post answered the question, but this post offered more detail. I was looking for the keyword 'abstract', which is what I would imagine a lot of C++ users will be looking for. – David Nov 07 '15 at 04:26
  • 1
    Few years late here but fantastic answer – Tom O. Jan 18 '19 at 21:54
  • This was way back, when non-technical hiring managers were the primary deciders on who was a programmer and who wasn't. The fancy MBA's somehow got it into their tiny heads that object-oriented programming was the best thing since sliced bread, and so in order to be a good programmer, you had to just know the answer to this question and regurgitate it when he gives the signal. Even when you answered the question perfectly and timelessly, you'd still get a scowl, because that was part of their their test to make sure you were sure that you knew and you could put up with the office politics. – Eric Leschinski Jan 18 '19 at 22:03
59

All functions in Java are virtual by default.

You have to go out of your way to write non-virtual functions by adding the "final" keyword.

This is the opposite of the C++/C# default. Class functions are non-virtual by default; you make them so by adding the "virtual" modifier.

duffymo
  • 305,152
  • 44
  • 369
  • 561
9

All non-private instance methods are virtual by default in Java.

In C++, private methods can be virtual. This can be exploited for the non-virtual-interface (NVI) idiom. In Java, you'd need to make the NVI overridable methods protected.

From the Java Language Specification, v3:

8.4.8.1 Overriding (by Instance Methods) An instance method m1 declared in a class C overrides another instance method, m2, declared in class A iff all of the following are true:

  1. C is a subclass of A.
  2. The signature of m1 is a subsignature (§8.4.2) of the signature of m2.
  3. Either * m2 is public, protected or declared with default access in the same package as C, or * m1 overrides a method m3, m3 distinct from m1, m3 distinct from m2, such that m3 overrides m2.
Andy Thomas
  • 84,978
  • 11
  • 107
  • 151
4

Yes, you can write virtual "functions" in Java.

RepDetec
  • 741
  • 13
  • 29
1

In Java, all public (non-private) variables & functions are Virtual by default. Moreover variables & functions using keyword final are not virtual.