2009-08-09 19 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 

Odpowiedz

79
class B < A 

    alias :super_a :a 

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

Aby aliasować metodę klasy, zobacz http://stackoverflow.com/questions/2925016/alias-method-and-class-methods-dont-mix –

+0

Czy możliwe jest, że 'alias' został przemianowany na [' alias_method'] (http://apidock.com/ruby/Module/alias_method) od czasu napisania tej odpowiedzi? –

+0

@JaredBeck to naprawdę zostało przemianowane. Teraz powinno być: alias_method: super_a: a –

29

Nie ma dobry sposób, aby to zrobić, ale można to zrobić A.instance_method(:a).bind(self).call, która będzie działać, ale jest brzydki.

Można nawet zdefiniować własne metody w obiekcie działać jak Super w 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 nie zgadzam, rozwiązanie to było dokładnie to, co potrzebne ... powód: chciałem rodzajowo wywołanie super metody innej metody, ale bez konieczności alias każdziuteńki, że chciałem, aby móc aby to zrobić, więc ogólny sposób wywoływania superużyteczności jest całkiem użyteczny. –

+3

Skomplikowany do zdefiniowania raz, prosty do wywołania go wiele razy. To lepsze niż na odwrót. – nertzy

0

Jeśli wyraźnie nie trzeba zadzwonić A # B # A z B, ale raczej trzeba aby zadzwonić do A # a z B # a, co jest faktycznie tym, co robisz, za pomocą B # b (chyba, że ​​przykład nie jest wystarczająco kompletny, aby pokazać, dlaczego dzwonisz z B # b, możesz po prostu zadzwoń super z poziomu B # a, tak jak to czasami robimy w metodach inicjalizacji. Wiem, że to jest trochę oczywiste, chciałem tylko wyjaśnić każdemu nowemu użytkownikowi Ruby, że nie masz do aliasu (konkretnie jest to czasami nazywane "alias") w każdym cas mi.

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 
Powiązane problemy