2009-08-09 16 views
47
 
class A 
    def a 
    puts 'in #a' 
    end 
end 

class B < A 
    def a 
    b() 
    end 
    def b 
    # here i want to call A#a. 
    end 
end 

risposta

79
class B < A 

    alias :super_a :a 

    def a 
    b() 
    end 
    def b 
    super_a() 
    end 
end 
+0

Per creare un alias per un metodo di classe, vedere http://stackoverflow.com/questions/2925016/alias-method-and-class-methods-dont-mix –

+0

È possibile che "alias" sia stato rinominato in ['alias_method'] (http://apidock.com/ruby/Module/alias_method) da quando è stata scritta questa risposta? –

+0

@JaredBeck è stato rinominato. Quindi ora dovrebbe essere: alias_method: super_a: a –

29

Non c'è un modo carino per farlo, ma è possibile fare A.instance_method(:a).bind(self).call, che funzionerà, ma è brutto.

Si potrebbe anche definire il proprio metodo in oggetto per agire come super in Java:

class SuperProxy 
    def initialize(obj) 
    @obj = obj 
    end 

    def method_missing(meth, *args, &blk) 
    @obj.class.superclass.instance_method(meth).bind(@obj).call(*args, &blk) 
    end 
end 

class Object 
    private 
    def sup 
    SuperProxy.new(self) 
    end 
end 

class A 
    def a 
    puts "In A#a" 
    end 
end 

class B<A 
    def a 
    end 

    def b 
    sup.a 
    end 
end 
B.new.b # Prints in A#a 
+8

@klochner Non sono d'accordo, questa soluzione era esattamente quello che mi serviva ... ragione: volevo genericamente chiamata di metodo eccellente di un metodo diverso, ma senza la necessità di alias ogni singolo uno che volevo essere in grado per fare questo, quindi un modo generico per invocare super è abbastanza utile –

+3

Complicato per definire una volta, semplice chiamarlo molte volte. È meglio del contrario. – nertzy

0

Se non esplicitamente necessario chiamare A # uno da B # B, ma piuttosto hanno bisogno per chiamare A # a da B # a, che è effettivamente quello che stai facendo tramite B # b (a meno che tu non sia un esempio sufficiente per dimostrare perché stai chiamando da B # b, puoi semplicemente chiama super da dentro B # a, proprio come a volte viene fatto nei metodi di inizializzazione. So che questo è ovvio, volevo solo chiarire per tutti i nuovi arrivati ​​di Ruby che non devi avere un alias (in particolare a volte viene chiamato un "intorno alias") in ogni cas e.

class A 
    def a 
    # do stuff for A 
    end 
end 

class B < A 
    def a 
    # do some stuff specific to B 
    super 
    # or use super() if you don't want super to pass on any args that method a might have had 
    # super/super() can also be called first 
    # it should be noted that some design patterns call for avoiding this construct 
    # as it creates a tight coupling between the classes. If you control both 
    # classes, it's not as big a deal, but if the superclass is outside your control 
    # it could change, w/o you knowing. This is pretty much composition vs inheritance 
    end 
end 
Problemi correlati