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

cevap

79
class B < A 

    alias :super_a :a 

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

bu alias' olarak değiştirilmiş 'mümkün mi http://stackoverflow.com/questions/2925016/alias-method-and-class-methods-dont-mix –

+0

bkz sınıf yöntemi diğer adına [' alias_method'] Bu cevap yazıldığı için (http://apidock.com/ruby/Module/alias_method)? –

+0

@JaredBeck gerçekten yeniden adlandırıldı. Yani şimdi olmalı: alias_method: super_a: –

29

Yapmanın iyi bir yolu yok, ancak işe yarayacak olan A.instance_method(:a).bind(self).call'u yapabilirsiniz, ancak çirkin.

Hatta java süper gibi davranmak Nesne kendi yöntemini tanımlayabilirsiniz: Açıkça yerine B # b A # a diyorsunuz, ama gerek yoksa

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, bu çözüm ben ... gerekli nedeni tam olarak ne oldu: Ben farklı bir yöntemin jenerik çağrı süper yönteme istedi ama takma gerek kalmadan istediğim her biri muktedir Bunu yapmak için, süper çağırmak için genel bir yol oldukça yararlıdır –

+3

Bir kez tanımlamak için karmaşık, bir çok kez çağırmak için basit. Bu tam tersi daha iyidir. – nertzy

0

gerek B # b üzerinden yaptığınız A # a kelimesini çağırmak için (örneğin siz B # b'den neden çektiğinizi göstermek için yeterli değilseniz) B/a'nın içinden süper arama, tıpkı kimi zaman başlatma metotlarında yapıldığı gibi, biliyorum ki bu açık bir şey, ben sadece takma adlara sahip olmadığınız herhangi bir Ruby yeni üyesi için açıklığa kavuşturmak istedim (özellikle buna bazen denir) her kutuda "takma ad") e. Ben katılmıyorum

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 
İlgili konular