虚函数

程式範例

例如，一個基礎類別 Animal 有一個虛擬函式 eat。子類別 Fish 要實做一個函式 eat()，這個子類別 Fish 與子類別 Wolf 是完全不同的，但是你可以參照類別 Animal 底下的函式 eat() 定義，而使用子類別 Fish 底下函式 eat() 的處理程式。

C++

以下程式碼是 C++ 的程式範例。要注意的是，這個範例沒有異常處理的程式碼。尤其是 new 或是 vector::push_back 丟出一個異常時，程式在執行時有可能會出現崩潰或是錯誤的現象。
# include <iostream># include <vector>using namespace std;class Animal{public:
    virtual void eat() const { cout << "I eat like a generic Animal." << endl; }
    virtual ~Animal() {}};
 
class Wolf : public Animal{public:
    void eat() const { cout << "I eat like a wolf!" << endl; }};
 
class Fish : public Animal{public:
    void eat() const { cout << "I eat like a fish!" << endl; }};
 
class GoldFish : public Fish{public:
    void eat() const { cout << "I eat like a goldfish!" << endl; }};
 
 
class OtherAnimal : public Animal{};
 
int main(){
    std::vector<Animal*> animals;
    animals.push_back( new Animal() );
    animals.push_back( new Wolf() );
    animals.push_back( new Fish() );
    animals.push_back( new GoldFish() );
    animals.push_back( new OtherAnimal() );
 
    for( std::vector<Animal*>::const_iterator it = animals.begin();
       it != animals.end(); ++it) 
    {
        (*it)->eat();
        delete *it;
    }
 
   return 0;}
以下是虛擬函式 Animal::eat() 的輸出：
I eat like a generic Animal.
I eat like a wolf!
I eat like a fish!
I eat like a goldfish!
I eat like a generic Animal.
當 Animal::eat() 不是被宣告為虛擬函式時，輸出如下所示：
I eat like a generic Animal.
I eat like a generic Animal.
I eat like a generic Animal.
I eat like a generic Animal.
I eat like a generic Animal.

Java

在Java語言中, 所有的方法預設都是"虛擬函式". 只有以關鍵字 final 標記的方法才是非虛擬函式. 以下是 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 Wolf());
      animals.add(new Fish());
      animals.add(new OtherAnimal());

      for (Animal currentAnimal : animals) {
         currentAnimal.eat();
      }
   }}
 
public class Wolf extends Animal {
   public void eat() { System.out.println("I eat like a wolf!"); }}
 
public class Fish extends Animal {
   public void eat() { System.out.println("I eat like a fish!"); }}
 
public class OtherAnimal extends Animal {}
 
輸出:
I eat like a generic Animal.
I eat like a wolf!
I eat like a fish!
I eat like a generic Animal.

C#

在 C# 語言中, 對基礎類別中的任何虛擬方法必須用 virtual 修飾, 而衍生類中由基礎類別繼承而來的多載方法必須用 override 修飾. 以下是 C# 的一個程式實體:
using System;using System.Collections.Generic;namespace ConsoleApplication1{
  public class Animal
  {
    public virtual void Eat()
    {
      Console.WriteLine("I eat like a generic Animal.");
    }
  }

  public class Wolf : Animal
  {
    public override void Eat()
    {
      Console.WriteLine("I eat like a wolf!");
    }
  }

  public class Fish : Animal
  {
    public override void Eat()
    {
      Console.WriteLine("I eat like a fish!");
    }
  }

  public class GoldFish : Fish
  {
    public override void Eat()
    {
      Console.WriteLine("I eat like a goldfish!");
    }
  }

  public class OtherAnimal : Animal
  {
    // Eat() method is not overridden, so the base class method will be used.
  }

  public class Program
  {
    public static void Main(string[] args)
    {
      IList<Animal> animals = new List<Animal>();
      
      animals.Add(new Animal());
      animals.Add(new Wolf());
      animals.Add(new Fish());
      animals.Add(new GoldFish());
      animals.Add(new OtherAnimal());

      foreach (Animal currentAnimal in animals)
      {
        currentAnimal.Eat();
      }
    }
  }}
 
輸出:
I eat like a generic Animal.
I eat like a wolf!
I eat like a fish!
I eat like a goldfish!
I eat like a generic Animal.

抽象類和純虛擬函式

純虛擬函式或純虛擬方法是一個需要被非抽象的衍生類別覆蓋（override）的虛擬函式. 包含純虛擬方法的類被稱作抽象類; 抽象類不能被直接實體化。 一個抽象基礎類別的一個子類別只有在所有的純虛擬函式在該類(或其父類別)內給出實現時, 才能直接實體化. 純虛擬方法通常只有聲明(簽章)而沒有定義(實現)，但有特例情形要求純虛擬函式必須給出函式體定義.
作為一個例子, 抽象基礎類別"MathSymbol"可能提供一個純虛擬函式 doOperation(), 和衍生類 "Plus" 和 "Minus" 提供doOperation() 的具體實現. 由於 "MathSymbol" 是一個抽象概念, 為其每個子類別定義了同一的動作, 在 "MathSymbol" 類中執行 doOperation() 沒有任何意義. 類似的, 一個給定的 "MathSymbol" 子類別如果沒有 doOperation() 的具體實現是不完全的.
雖然純虛擬方法通常在定義它的類中沒有實現, 在 C++ 語言中, 允許純虛擬函式在定義它的類中包含其實現, 這為衍生類提供了備用或預設的行為. C++的虛擬基礎類別的虛擬解構函式必須提供函式體定義，否則連結時（linking）在解構該抽象類的衍生實體物件的語句處會報錯。

C++

在C++語言中, 純虛擬函式用一種特別的語法[=0]定義（但 VS 也支援 abstract 關鍵字：virtual ReturnType Function()abstract;）, 見以下範例.
class Abstract {public:
   virtual void pure_virtual() = 0;};
純虛擬函式的定義僅提供方法的原型. 雖然在抽象類中通常不提供純虛擬函式的實現, 但是抽象類中可以包含其實現, 而且可以不在聲明的同時給出定義. 每個非抽象子類別仍然需要多載該方法, 抽象類中實現的呼叫可以採用以下這種形式:
 void Abstract::pure_virtual() {
   // do something
 }
 
 class Child : public Abstract {
   virtual void pure_virtual(); // no longer abstract, this class may be
                                // instantiated.
 };
 
 void Child::pure_virtual() {
   Abstract::pure_virtual(); // the implementation in the abstract class 
                             // is executed
 }

構造與解構時的行為

在物件的建構函式和解構函式中涉及虛擬函式時，不同的語言有不同的規定。在以 C++ 為代表的一些語言中，虛擬函式排程機制在物件的構造和解構時有不同的語意，一般建議儘可能避免在 C++ 的建構函式中呼叫虛擬函式。而在 C#、Java 等另一些語言中，構造時可以呼叫衍生類別中的實現，抽象工廠模式等設計模式也鼓勵在支援這一特性的語言中使用這種用法。