programing

Java로 가상 함수/메서드를 작성할 수 있습니까?

firstcheck 2022. 7. 9. 09:30
반응형

Java로 가상 함수/메서드를 작성할 수 있습니까?

C++와 같이 Java에서도 가상 메서드를 작성할 수 있습니까?

또는 유사한 동작을 발생시키는 적절한 Java 접근법이 있습니까?몇 가지 예를 들어도 될까요?

위키피디아에서

Java에서는 모든 비정적 메서드가 기본적으로 "가상 함수"입니다.private 메서드와 함께 덮어쓸 수 없는 키워드 final로 마크된 메서드비가상입니다.

Java로 가상 함수를 작성할 수 있습니까?

네. 실제로 Java의 모든 인스턴스 메서드는 기본적으로 가상입니다.특정 메서드만 가상이 아닙니다.

  • 클래스 메서드(일반적으로 각 인스턴스는 특정 메서드에 대한 포인터처럼 vtable에 대한 정보를 보유하고 있지만 여기에는 사용할 수 있는 인스턴스가 없습니다).
  • 프라이빗 인스턴스 메서드(다른 클래스가 메서드에 액세스할 수 없기 때문에 콜링 인스턴스는 항상 정의 클래스 자체의 유형을 가지고 있기 때문에 컴파일 시에 명확하게 인식됩니다).

다음은 몇 가지 예입니다.

'통상적인' 가상 기능

다음 예는 다른 답변에서 언급된 이전 버전의 Wikipedia 페이지에서 나온 것입니다.

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 Fish());
      animals.add(new Goldfish());
      animals.add(new OtherAnimal());

      for (Animal currentAnimal : animals) 
      {
         currentAnimal.eat();
      }
   }
}

class Fish extends Animal 
{
   @Override
   public void eat() 
   { 
      System.out.println("I eat like a fish!"); 
   }
}

class Goldfish extends Fish 
{
   @Override
   public void eat() 
   { 
      System.out.println("I eat like a goldfish!"); 
   }
}

class OtherAnimal extends Animal {}

출력:

나는 일반적인 동물처럼 먹는다.
난 물고기처럼 먹어!난 금붕어처럼 먹어!나는 일반적인 동물처럼 먹는다.

인터페이스를 사용한 가상 기능의 예

Java 인터페이스 메서드는 모두 가상입니다.메서드 구현을 제공하기 위해 구현 클래스에 의존하기 때문에 가상이어야 합니다.실행할 코드는 실행 시에만 선택됩니다.

예를 들어 다음과 같습니다.

interface Bicycle {         //the function applyBrakes() is virtual because
    void applyBrakes();     //functions in interfaces are designed to be 
}                           //overridden.

class ACMEBicycle implements Bicycle {
    public void applyBrakes(){               //Here we implement applyBrakes()
       System.out.println("Brakes applied"); //function
    }
}

추상 클래스가 있는 가상 함수의 예제입니다.

인터페이스와 유사하게 추상 클래스는 확장 클래스의 구현에 의존하므로 가상 메서드를 포함해야 합니다.예:

abstract class Dog {                   
    final void bark() {               //bark() is not virtual because it is 
        System.out.println("woof");   //final and if you tried to override it
    }                                 //you would get a compile time error.

    abstract void jump();             //jump() is a "pure" virtual function 
}                                     
class MyDog extends Dog{
    void jump(){
        System.out.println("boing");    //here jump() is being overridden
    }                                  
}
public class Runner {
    public static void main(String[] args) {
        Dog dog = new MyDog();       // Create a MyDog and assign to plain Dog variable
        dog.jump();                  // calling the virtual function.
                                     // MyDog.jump() will be executed 
                                     // although the variable is just a plain Dog.
    }
}

Java의 모든 함수는 기본적으로 가상입니다.

"final" 키워드를 추가하여 비가상 함수를 작성해야 합니다.

이는 C++/C# 기본값과는 반대입니다.클래스 함수는 기본적으로 비가상 함수로, "가상" 수식자를 추가하여 만듭니다.

Java에서는 모든 비프라이빗 인스턴스 메서드가 기본적으로 가상입니다.

C++ 에서는, 프라이빗 메서드를 가상으로 할 수 있습니다.이는 Non-Virtual Interface(NVI; 비가상 인터페이스)의 관용어로 악용될 수 있습니다.Java에서는 NVI를 덮어쓸 수 있는 메서드를 보호해야 합니다.

Java Language Specification(Java 언어 사양, v3):

8.4.8.1 덮어쓰기(인스턴스 메서드에 의한) 클래스 C에서 선언된 인스턴스 메서드 m1은 클래스 A에서 선언된 다른 인스턴스 메서드 m2를 덮어씁니다.다음의 조건이 모두 충족될 경우.

  1. C는 A의 서브 클래스입니다.
  2. m1의 시그니처는 m2의 시그니처의 서브시그니처(「8.4.2」)입니다.
  3. * m2는 C와 같은 패키지로 퍼블릭, 보호 또는 디폴트액세스로 선언됩니다.또는 * m1은 m1, m3와는 다른 메서드m3, m2와는 다른 메서드m3를 덮어쓰고 m3는 m2를 덮어씁니다.

예, Java에서 가상 "함수"를 작성할 수 있습니다.

Java에서는 모든 퍼블릭(비프라이빗) 변수 및 함수가 기본적으로 Virtual입니다.또한 키워드 final을 사용한 변수 및 함수는 가상이 아닙니다.

언급URL : https://stackoverflow.com/questions/4547453/can-you-write-virtual-functions-methods-in-java

반응형