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


165

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

또는 유사한 동작을 생성하는 적절한 Java 접근 방식을 구현할 수 있습니까? 몇 가지 예를 들어 주시겠습니까?

답변:


305

에서 위키 피 디아

에서 자바 , 모든 비 정적 방법이 기본적으로 있습니다 " 가상 함수. "는 표시 만 방법 final 키워드 와 함께 무시 될 수없는, 개인 방법 상속되지이다 비가 상 .


3
다음 중 하나입니다 존 소총 의 대답.
Quazi Irfan

나는 그것 때문에 내가 읽은 무엇을, 자바, 동적 인 방법 파견은 메소드가 호출되는 개체에 대한 일을 위해, 정말 사실이라면 wonded - 같은 설명 여기 그래서 예는 C ++에 대한 가상 함수를 설명 여기에 자바 유효하지 않습니다.
브로콜리

@QuaziIrfan Java와 C #의 차이점입니다.
Sreekanth Karumanaghat

101

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.
    }
}

1
이것은 가장 완전한 대답이어야합니다. java에는 키워드가 없으므로 가상 함수를 구현하는 두 가지 방법을 제공합니다. 감사합니다.
Christopher Bales 1

Wikipedia 인용보다 훨씬 더 나은 답변. c ++에서 나오고 Java 연구에 게으 르면 추상이 내가 찾고있는 것입니다.
David

@David이 답변은 어떻게 더 낫습니까? 위키 백과 인용은 완전하고 간결하며 정확합니다. 대조적으로이 답변은 방 안에있는 코끼리를 언급하지 못합니다. 기본적 으로 Java의 모든 기능 (위키피디아 기사에 나열된 예외)은 가상입니다. 가상 함수에는 추상 클래스 나 인터페이스가 필요하지 않으므로 오해의 소지가있는 노이즈 만 추가 할 수 있습니다. 그리고 이것은 "훌륭한 의사 소통 기술과 근본적인 원리의 숙달이 필요합니다 ..." 그것은 바로 자기 반증적인 진술입니다. 그 디스크를 가진 사람은 소중한 디스크 공간을 낭비하지 않을 것입니다.
피터-모니 티 복원

wikipedia 게시물은 java가 아닌 모든 언어의 가상 함수 개념에 관한 것이기 때문에이 답변에 비해 열등하고 덜 구체적입니다. wikipedia 페이지에 제공된 예제는 C로 작성되었으며, 불완전한 것으로 더 오해의 소지가 있습니다. 가상의 모든 함수에 대한 세부 사항이며 가상 함수가 노이즈가되도록 추상 클래스 나 인터페이스가 필요하지 않습니다. 나는 그들이 요구된다고 결코 말하지 않았다. 마지막 요점을 이해하지 못했습니다.이 질문이 마음에 들지 않기 때문에이 질문을 삭제 하시겠습니까?
Eric Leschinski

1
몇 년 늦었지만 환상적인 답변
Tom O.

55

Java의 모든 기능은 기본적으로 가상입니다.

"final"키워드를 추가하여 비가 상 함수를 작성하는 길을 벗어나야합니다.

이것은 C ++ / C # 기본값과 반대입니다. 클래스 함수는 기본적으로 비 가상적입니다. "가상"수정자를 추가하면됩니다.


4
클라우스의 답변에 명시된 개인 기능도 가상이 아닙니다.
Don Larynx

9

개인이 아닌 모든 인스턴스 메소드는 기본적으로 Java에서 가상입니다.

C ++에서 개인용 메소드는 가상 일 수 있습니다. 이것은 비가 상 인터페이스 (NVI) 관용구에 악용 될 수 있습니다. Java에서는 NVI 재정의 가능한 메소드를 보호해야합니다.

Java 언어 사양 v3에서 :

8.4.8.1 인스턴스 메서드로 재정의 클래스 C에서 선언 된 인스턴스 메서드 m1은 클래스 A에서 선언 된 다른 인스턴스 메서드 m2를 재정의합니다.

  1. C는 A의 서브 클래스입니다.
  2. m1의 서명은 m2 서명의 하위 서명 (§8.4.2)입니다.
  3. * m2는 C와 동일한 패키지에서 기본 액세스로 공개, 보호 또는 선언되어 있거나 * m1은 m3, m3과 m1, m3과 m2와 구별되는 m3 메소드를 대체하여 m3이 m2보다 우선합니다.


1

Java에서 모든 공용 (비공개) 변수 및 함수는 기본적으로 가상 입니다. 또한 final 키워드를 사용하는 변수 및 함수 는 가상 이 아닙니다 .


"가상 변수"는 무엇을 의미합니까?
neoexpert
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.