Java 中的虚拟函数

Mohammad Irfan 2023年10月12日
  1. Java 中的虚拟函数
  2. Java Bean 中的虚拟函数
  3. Java 中的非虚拟函数
  4. Java 接口中的虚拟函数
Java 中的虚拟函数

本教程介绍了什么是 Java 中的虚拟函数/方法以及如何使用 Java 中的虚拟函数。

在基类中定义并且可以在派生类中覆盖的函数称为虚拟函数。C++ 和 Java 中默认使用了虚拟函数的概念;所有非私有和非最终方法都是虚方法。

在 C++ 中,我们使用 virtual 关键字来创建虚拟函数,但 Java 没有这样的关键字。除此之外,所有非私有和非最终方法都是虚拟的。

虚拟函数的概念在面向对象编程概念和多态性方面很有用。让我们通过一些例子来理解。

Java 中的虚拟函数

在这个例子中,我们创建了一个类 Human,其中包含一个虚拟的 eat() 方法。因为它是一个虚方法,它可以在派生类/子类中被覆盖,就像我们在下面的例子中所做的那样。两个方法具有相同的签名,当我们调用函数时,只执行子类方法。请参阅下面的示例。

class Human {
  void eat(String choice) {
    System.out.println("I would like to eat - " + choice + " now");
  }
}

public class SimpleTesting extends Human {
  void eat(String choice) {
    System.out.println("I would like to eat - " + choice);
  }
  public static void main(String[] args) {
    SimpleTesting simpleTesting = new SimpleTesting();
    simpleTesting.eat("Pizza");
    simpleTesting.eat("Chicken");
  }
}

输出:

I would like to eat - Pizza
I would like to eat - Chicken

Java Bean 中的虚拟函数

bean/POJO 类的 getter 函数也是虚拟的,可以被子类覆盖。请参阅下面的示例。

public class SimpleTesting extends Student {
  public int getId() {
    System.out.println("Id : " + id);
    return id;
  }
  public String getName() {
    System.out.println("Name : " + name);
    return name;
  }
  public int getAge() {
    System.out.println("Age : " + age);
    return age;
  }

  public static void main(String[] args) {
    SimpleTesting student = new SimpleTesting();
    student.setId(101);
    student.setName("Rohan");
    student.setAge(50);
    student.getId();
    student.getName();
    student.getAge();
  }
}
class Student {
  int id;
  String name;
  int age;

  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    this.age = age;
  }
}

输出:

Id : 101
Name : Rohan
Age : 50

Java 中的非虚拟函数

私有或最终的函数是非虚拟的,因此它们不能被子类覆盖。在这个例子中,我们创建了两个函数,一个是最终的,第二个是私有的。我们试图将这些覆盖到子类中,但是由于非虚拟函数,java 编译器引发了错误。请参阅下面的示例和输出。

class Human {
  // non-virtual method
  final void eat(String choice) {
    System.out.println("I would like to eat - " + choice);
  }
  // non-virtual method
  private void buy(String item) {
    System.out.println("Buy me a " + item);
  }
}
public class SimpleTesting extends Human {
  // non-virtual method
  void eat(String choice) {
    System.out.println("I would like to eat - " + choice);
  }
  // non-virtual method
  void buy(String item) {
    System.out.println("Buy me a " + item);
  }
  public static void main(String[] args) {
    SimpleTesting simpleTesting = new SimpleTesting();
    simpleTesting.eat("Pizza");
    simpleTesting.buy("Pizza");
    simpleTesting.eat("Chicken");
    simpleTesting.buy("Chicken");
  }
}

输出:

java.lang.IncompatibleClassChangeError: class SimpleTesting overrides final method Human.eat(Ljava/lang/String;)
---Cannot override the final method from Human---

Java 接口中的虚拟函数

接口的函数/方法默认是虚拟的,因为它们默认是公共的,并且应该被子类覆盖。在下面的例子中,我们在接口中创建了一个方法,在一个类中重写了它,并成功调用了它。请参阅下面的示例。

interface Eatable {
  void eat(String choice);
}
public class SimpleTesting implements Eatable {
  public void eat(String choice) {
    System.out.println("I would like to eat - " + choice);
  }
  void buy(String item) {
    System.out.println("Buy me a " + item);
  }
  public static void main(String[] args) {
    SimpleTesting simpleTesting = new SimpleTesting();
    simpleTesting.eat("Pizza");
    simpleTesting.buy("Pizza");
    simpleTesting.eat("Chicken");
    simpleTesting.buy("Chicken");
  }
}

输出:

I would like to eat - Pizza
Buy me a Pizza
I would like to eat - Chicken
Buy me a Chicken

相关文章 - Java Function