Wikipedia definisce virtual methods come:I metodi nei paradigmi orientati agli oggetti possono essere sovrascritti dai metodi con la stessa firma nelle classi ereditanti. Le variabili tuttavia non possono. Perché?
Nella programmazione orientata agli oggetti, una funzione virtuale o un metodo virtuale è una funzione o metodo cui comportamento può essere ignorato all'interno di una sottoclasse da una funzione con la stessa firma [prestazione un comportamento polimorfico].
Secondo la definizione, ogni metodo non statico in Java è di default virtuale tranne metodi finali e privati. Il metodo che non può essere ereditato per il comportamento polimorfico è non un metodo virtuale.
I metodi statici in Java non possono mai essere sovrascritti; quindi, non ha senso dichiarare un metodo statico come finale in Java perché i metodi statici stessi si comportano proprio come i metodi finali. Possono semplicemente essere nascosti nelle sottoclassi con i metodi con la stessa firma. Evidentemente è così perché i metodi statici non possono mai avere un comportamento polimorfico: un metodo che viene sovrascritto deve ottenere il polimorfismo, che non è il caso dei metodi statici.
Dal paragrafo precedente, una conclusione importante può essere guidata. Tutti i metodi in C++ sono di default statici perché nessun metodo in C++ può comportarsi in modo polimorfico finché e a meno che non siano esplicitamente dichiarati virtuali nella super classe. Al contrario, tutti i metodi in Java tranne i metodi definitivi, statici e privati sono di default virtuali perché hanno un comportamento polimorfico di default (non è necessario dichiarare esplicitamente metodi come virtuali in Java e, di conseguenza, Java non ha parole chiave come "virtuale").
Ora, dimostriamo che le variabili di istanza (anche statiche) non possono comportarsi in modo polimorfico dal seguente semplice esempio in Java.
class Super
{
public int a=5;
public int show()
{
System.out.print("Super method called a = ");
return a;
}
}
final class Child extends Super
{
public int a=6;
@Override
public int show()
{
System.out.print("Child method called a = ");
return a;
}
}
final public class Main
{
public static void main(String...args)
{
Super s = new Child();
Child c = new Child();
System.out.println("s.a = "+s.a);
System.out.println("c.a = "+c.a);
System.out.println(s.show());
System.out.println(c.show());
}
}
L'uscita prodotto dal frammento di codice sopra è il seguente.
s.a = 5 c.a = 6 Child method called a = 6 Child method called a = 6
In questo esempio, entrambe le chiamate s.show()
e c.show()
pervenute al metodo show()
attraverso le variabili di tipo Super
e di tipo Child
, rispettivamente, richiamare il metodo show()
nella classe Child
. Ciò significa che il metodo show()
nella classe Child
sovrascrive il metodo show()
nella classe Super
poiché entrambi hanno la stessa firma.
Questo, tuttavia, non può essere applicato alla variabile di istanza a
dichiarata in entrambe le classi.In questo caso, sarebbe s.a
consultare a
nella classe Super
e visualizzazione 5
e c.a
rammenta le a
nella classe Child
e potrai 6
significa che a
nelle Child
classe soli pelli (e non ridefinisce come è accaduto a non statico metodi) a
nella classe Super
.
Dopo questa lunga discussione, c'è solo una domanda. Perché le variabili di istanza (e anche il resto) non sono sovrascritte? Quali erano le ragioni speciali per attuare un tale meccanismo? Ci sarebbero stati vantaggi o svantaggi se fossero stati ignorati?
I metodi non virtuali C++ non sono statici. sono metodi di istanza che non possono essere sovrascritti. Sono simili ai metodi finali in Java: metodi di istanza che non possono essere sovrascritti. –
'Secondo il paragrafo precedente, una conclusione importante può essere guidata. Tutti i metodi in C++ (anche in C) sono di default statici perché nessun metodo in C++ può comportarsi in modo polimorfico fino a quando non sono esplicitamente dichiarati virtuali nella base': un metodo statico non può accedere all'oggetto [no 'this' per questi metodi ] mentre una funzione non predefinita [predefinita] in C++ può – amit
I cosa la parola "sovrascritta" non è applicabile alle variabili. Esegui l'override del comportamento, ma non lo stato. È possibile accedere alle variabili dalla sottoclasse, quindi non è necessario "eseguire l'override" (è possibile modificarne il valore e ha lo stesso nome). Inoltre c'è qualcosa chiamato shadowing, quindi se si dichiara nuovamente un'altra variabile con lo stesso nome è un'altra variabile diversa in fase di esecuzione. –