Nei linguaggi orientati agli oggetti tradizionali (ad esempio Java), è possibile "estendere" la funzionalità di un metodo in una classe ereditata chiamando il metodo originale dalla super classe nella versione sostituita, ad esempio:È possibile estendere un'implementazione di metodo predefinita di un tratto in una struttura?
class A {
public void method() {
System.out.println("I am doing some serious stuff!");
}
}
class B extends A {
@Override
public void method() {
super.method(); // here we call the original version
System.out.println("And I'm doing something more!");
}
}
Come potete vedere, in Java, sono in grado di chiamare la versione originale della super classe usando la parola chiave super
. Sono stato in grado di ottenere il comportamento equivalente per i tratti ereditati, ma non quando si implementano i tratti per le strutture.
trait Foo {
fn method(&self) {
println!("default implementation");
}
}
trait Boo: Foo {
fn method(&self) {
// this is overriding the default implementation
Foo::method(self); // here, we successfully call the original
// this is tested to work properly
println!("I am doing something more.");
}
}
struct Bar;
impl Foo for Bar {
fn method(&self) {
// this is overriding the default implementation as well
Foo::method(self); // this apparently calls this overridden
// version, because it overflows the stack
println!("Hey, I'm doing something entirely different!");
println!("Actually, I never get to this point, 'cause I crash.");
}
}
fn main() {
let b = Bar;
b.method(); // results in "thread '<main>' has overflowed its stack"
}
Così, in caso di tratti ereditari, chiamando l'implementazione di default originale non è un problema, tuttavia, utilizzando la stessa sintassi in sede di attuazione struct presenta un comportamento diverso. È un problema all'interno di Rust? C'è un modo per aggirarlo? O mi manca qualcosa?
Ok, penso di aver capito, quello che ancora mi infastidisce è perché funziona per i tratti ereditari? La stessa sintassi 'Foo :: method (self)' che chiama il metodo sul tipo specifico quando chiamato all'interno dell'implementazione del tratto per una struttura richiama l'implementazione originale quando viene chiamata all'interno di una caratteristica ereditata. Perchè è questo? – faiface
Non sta facendo quello che ti aspetti. Stai definendo un nuovo metodo 'Boo :: method' diverso da quello' Foo :: method'. Sta ancora chiamando il metodo specifico sul tipo; Immagino che il tuo codice di test non abbia sovrascritto 'method' su' Foo', solo su 'Bar'. – huon
Sì, grazie, hai ragione, ora lo capisco molto meglio. – faiface