Java의 가상 함수

Mohammad Irfan 2023년10월12일
  1. Java의 가상 함수
  2. Java Bean의 가상 기능
  3. Java의 비가상 함수
  4. Java 인터페이스의 가상 기능
Java의 가상 함수

이 튜토리얼에서는 Java에서 가상 함수/메서드가 무엇인지, Java에서 가상 함수를 사용하는 방법을 소개합니다.

기본 클래스에서 정의되고 파생 클래스에서 재정의될 수 있는 함수를 가상 함수라고 합니다. 가상 기능의 개념은 기본적으로 C++ 및 Java에서 사용되었습니다. 모든 non-private 및 non-final 메소드는 가상 메소드입니다.

C++에서는 virtual 키워드를 사용하여 가상 함수를 만들지만 Java에는 그런 키워드가 없습니다. 그 외에도 모든 비공개 및 최종이 아닌 메서드는 가상입니다.

가상 함수의 개념은 객체 지향 프로그래밍 개념과 다형성 측면에서 유용합니다. 몇 가지 예를 들어 이해합시다.

Java의 가상 함수

이 예제에서는 가상 eat() 메서드가 포함된 Human 클래스를 만들었습니다. 가상 메서드이기 때문에 아래 예제에서와 같이 파생/자식 클래스에서 재정의할 수 있습니다. 두 메서드 모두 동일한 서명을 가지며 함수를 호출하면 자식 클래스 메서드만 실행됩니다. 아래의 예를 참조하십시오.

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의 비가상 함수

private이거나 final인 함수는 가상이 아니므로 자식 클래스에서 재정의할 수 없습니다. 이 예에서 우리는 두 개의 함수를 만들었습니다. 하나는 final이고 두 번째는 private입니다. 이를 자식 클래스로 재정의하려고 시도했지만 가상이 아닌 기능으로 인해 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