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