Concept of Virtual function
Concept of Virtual function
Virtual function
A virtual function, also known as a virtual method in object-oriented programming (OOP) languages, is a function or method designed to allow the overriding of its behavior in an inherited class with the same signature, thereby achieving polymorphism.
When transitioning from C++ to Java, programmers often wonder about the equivalent of virtual functions in Java. In C++, virtual functions are denoted using the 'virtual' keyword, but in Java, this functionality is achieved through different techniques.
Java is an object-oriented programming language that supports various OOP features, including polymorphism, abstraction, inheritance, and more. These concepts are built around objects, classes, and their member functions.
In Java, by default, all instance methods are considered virtual functions, with the exception of final, static, and private methods. Final, static, and private methods cannot be used to achieve polymorphism.
Java Virtual Functions aren't explicitly designated with the 'virtual' keyword, yet Java offers alternative approaches to achieve virtual function-like behavior.
Below, we outline key characteristics of virtual functions in Java.
A derived class can replace a virtual function with the same name and input parameters. Generally, virtual functions from the parent class get replaced in the child class.
To use virtual functions in Java, you must define them in the child class. You can then invoke this virtual function by referencing the object in the child class, using a pointer or reference from the base class.
It's crucial that the virtual function's name and arguments match those in both the base and derived classes.
In Java, virtual functions require an IS-A relationship to define class hierarchies through inheritance.
Private functions are not eligible for overriding, so virtual functions cannot be private.
Similarly, the 'final' keyword prevents function overriding, so virtual functions can't be marked as 'final.'
Static functions in Java don't support overriding either, making virtual functions non-static.
All non-static functions in Java can be considered virtual functions.
Virtual functions play a vital role in achieving runtime polymorphism, making them instrumental in implementing polymorphism in Java.
through some examples in Java to illustrate the concept of virtual methods and how they work with method overriding and polymorphism.
Example 1: Basic Method Override
Parent.Java:
class Parent {
void v1() { // Declaring function
System.out.println("Inside the Parent Class");
}
}
Child.java
class Parent {
void v1() { // Parent class method
System.out.println("Inside the Parent Class");
}
}
class Child extends Parent {
void v1() { // Overriding the method from the Parent class
System.out.println("Inside the Child Class");
}
public static void main(String[] args) {
Parent ob1 = new Child(); // Referring to the Child class object using the Parent class reference
ob1.v1(); // Calls the overridden method in the Child class
}
}
Output:
Inside the Child Class
In the provided example, we've utilized the v1() method as a virtual function by overriding it in the Child class.
In Java, any method that is non-static, non-final, and public is considered a virtual function. These methods can be employed to achieve polymorphism, a fundamental concept in object-oriented programming. Methods that are ineligible for achieving polymorphism are not considered virtual functions.
Specifically, methods that are declared as static, final, or private cannot serve as virtual functions. They cannot be invoked using an object's name or the class name itself. Even if an attempt is made to do so, they will not contribute to achieving polymorphism.
In Java, an interface acts as a model for a class, outlining a set of static constants and abstract methods. These interfaces can be likened to containers for virtual functions, as they necessitate that any class implementing them must furnish the specific method implementations. To better grasp this concept, let's consider the following example.
// Define an interface named "Car" with an abstract method "print"
interface Car {
void print();
}
// Create a class named "BMW" that implements the "Car" interface
class BMW implements Car {
// Implement the "print" method as required by the "Car" interface
public void print() {
System.out.println("BMW X7");
}
public static void main(String args[]) {
// Create an object of the "BMW" class
BMW obj = new BMW();
// Call the "print" method on the "obj" object
obj.print(); // Outputs "BMW X7"
}
}
Output:
BMW X7
In this code:
We define an interface named "Car" with a single abstract method called "print."
We create a class named "BMW" that implements the "Car" interface. As per the interface contract, we provide an implementation for the "print" method in the "BMW" class.
In the "main" method, we create an instance of the "BMW" class called "obj" and then call the "print" method on this object.
When we call "obj.print()," it invokes the "print" method implemented in the "BMW" class, which prints "BMW X7" to the console.
A pure virtual function is one that is defined in a class but does not have an implementation within that class. In Java, this concept is represented by abstract methods. Let's illustrate this with an example:
// Abstract class with a pure virtual function
abstract class Shape {
// Abstract method (pure virtual function)
public abstract void draw();
}
// Concrete subclass Circle
class Circle extends Shape {
@Override
public void draw() {
System.out.println("Drawing a Circle");
}
}
// Concrete subclass Rectangle
class Rectangle extends Shape {
@Override
public void draw() {
System.out.println("Drawing a Rectangle");
}
}
public class Main {
public static void main(String[] args) {
// Create instances of Circle and Rectangle
Shape circle = new Circle();
Shape rectangle = new Rectangle();
// Call the draw method on both objects
circle.draw();
rectangle.draw();
}
}
In this program:
We have an abstract class Shape with a pure virtual method draw().
We create two concrete subclasses, Circle and Rectangle, which extend the Shape class and implement the draw() method.
In the main method, we create instances of Circle and Rectangle and call the draw() method on them to demonstrate polymorphism. Each object calls its own implementation of the draw() method.
When you run this program, you'll get the following output:
Drawing a Circle
Drawing a Rectangle
Here are some key points to remember regarding virtual functions in Java:
Virtual functions in Java are regular functions.
There is no need to provide an explicit modifier to designate a function as virtual.
Unlike some other programming languages, Java doesn't require the use of a "virtual" keyword to indicate a virtual function.
You can use a parent class reference to point to a child class object and call its virtual functions.
To create a virtual function, you must define a function with the same name in the child class as it exists in the parent class.
In Java, nearly all instance methods are considered virtual functions, with exceptions being final, static, and private methods.