2012-02-26 18 views
13

Widziałem następny paragraf w pewnym teście informatycznym i mam nadzieję, że dostanę tutaj dobre wyjaśnienie, co to znaczy, ponieważ googlełem przez godzinę i nie mogę znaleźć nic ..Co to jest wywoływanie metod wirtualnych w języku Java?

"Kiedy Mówiąc językiem Java ma wirtualne wywoływanie metody mamy na myśli, że w aplikacjach java wykonywana metoda jest określona przez typ obiektu w czasie wykonywania "

Co to znaczy? czy ktoś może to lepiej wyjaśnić?

+0

[Metoda wirtualna] (http://en.wikipedia.org/wiki/Virtual_method) –

+0

również http://pl.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming – stryba

+0

Dziękujemy za referencje. – Popokoko

Odpowiedz

31

Autor tych słów użył C++ terminologia virtual.

Lepszą terminologią jest dynamic binding/dynamic dispatch.

Oznacza to, że dynamiczny obiekt type "wybiera", która metoda zostanie wywołana, a nie typ statyczny.

Na przykład: [pseudokod]

class A { 
    public void foo() { } 
} 
class B extends A { 
    public void foo() { } 
} 

przy wywołaniu:

A obj = new B(); 
obj.foo(); 

B.foo() będzie wywoływane, a nie A.foo(), ponieważ dynamiczny typu obj jest B.

12

mamy na myśli, że w aplikacji Java wykonywany metoda zależy od typu obiektu w czasie wykonywania

interface Animal{ 
    public void eat(); 
} 


class Person implements Animal{ 
    public void eat(){ System.out.println("Eating Food");} 
} 



class Eagle implements Animal{ 
    public void eat(){ System.out.println("Eating Snake");} 
} 

w głównym

Animal animal = new Person(); 
animal.eat(); //it will print eating food 
animal = new Eagle(); 
animal.eat(); //it will print eating snake 
+0

Dzięki! Wydaje mi się, że znam go, ale popraw mnie, jeśli jestem zły: tak o tym powiedziano "w aplikacjach java wykonywana metoda jest określana przez typ obiektu w czasie wykonywania" oznacza to, że java określa obiekt tylko podczas wykonywania? w twoim przykładzie animal.eat (1) wykona metodę Osoby, a na 2. wykona metodę Orła, czy to było to, do czego? – Popokoko

+0

Dokładnie, a obiekt otrzyma utworzony czas działania, więc jest to decyzja o uruchomieniu –

4

Załóżmy, że masz klasę Owoc, z dwiema podklasami: Pomarańczową i Bananową. Załóżmy, że Fruit ma metodę String getColor().

Orange może zastąpić metodę getColor(), aby powrócić "pomarańczowy". To samo dotyczy bananów, które mogą przywrócić "żółty" kolor.

Gdy jakaś metoda używa obiektu typu Fruit i wywołuje metodę getColor(), metoda, która zostanie nazwana, brzmi: Banana.getColor(), jeśli typ Owocu to w rzeczywistości Banan.

private void printColor(Fruit f) { 
    System.out.println(f.getColor()); 
} 

... 

Fruit fruit1 = new Banana(); 
Fruit fruit2 = new Orange(); 
printColor(fruit1); // prints yellow 
printColor(fruit2); // prints orange  
+0

Dziękuję :) Mam odpowiedź na poprzednie posty powyżej, ale to również świetne wyjaśnienie. – Popokoko

1

Employee.java

public class Employee 
{ 
    private String name; 
    private String address; 
    private int number; 
    public Employee(String name, String address, int number) 
    { 
     System.out.println("Constructing an Employee"); 
     this.name = name; 
     this.address = address; 
     this.number = number; 
    } 
    public void mailCheck() 
    { 
     System.out.println("Mailing a check to " + this.name 
     + " " + this.address); 
    } 
} 

VirtualMethod.java

class Salary extends Employee 
{ 
    private double salary; //Annual salary 
    public Salary(String name, String address, int number, double 
     salary) 
    { 
     super(name, address, number); 
     this.salary=salary; 
    } 
    public void mailCheck() 
    { 
     System.out.println("Within mailCheck of Salary class "); 
     System.out.println("Mailing check to " 
     + " with salary " + salary); 
    } 

} 

public class VirtualMethod 
{ 
    public static void main(String [] args) 
    { 
     Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00); 
     Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00); 
     System.out.println("Call mailCheck using Salary reference --"); 
     s.mailCheck(); 
     System.out.println("\n Call mailCheck using Employee reference--"); 
     e.mailCheck(); 
    } 
} 

Wyjście

Constructing an Employee 
Constructing an Employee 
Call mailCheck using Salary reference -- 
Within mailCheck of Salary class 
Mailing check to with salary 3600.0 

Call mailCheck using Employee reference-- 
Within mailCheck of Salary class 
Mailing check to with salary 2400.0 

Wyjaśnienie

tutaj, my wystąpienia dwóch Salary obiektów. Jeden używający Salary odniesienie s, a drugi używający odniesienie e.

Podczas wywoływania s.mailCheck() kompilator widzi mailCheck() w klasie Salary w czasie kompilacji, a JVM wywołuje mailCheck() w klasie Salary w czasie wykonywania.

Wywołanie mailCheck() na e jest zupełnie inne, ponieważ e jest numerem referencyjnym Employee. Gdy kompilator zobaczy e.mailCheck(), kompilator zobaczy metodę mailCheck() w klasie Employee.

Tutaj, podczas kompilacji, kompilator użył mailCheck() w Employee do sprawdzenia poprawności tej instrukcji. Jednak w czasie wykonywania JVM wywołuje mailCheck() w klasie Salary.

+2

Wiem, że to tylko przykład, ale "Wynagrodzenie klasy przedłuża pracownika" nie jest modelowaniem. Wynagrodzenie nie jest pracownikiem. – user3711421