2013-08-26 4 views
31

Я использовал super для инициализации родительского класса, но я не вижу способа вызова родительского класса из методов подкласса.Метод вызова в родительском классе из методов подкласса в Ruby

Я знаю, что PHP и другие языки имеют эту функцию, но не могут найти хороший способ сделать это в Ruby.

Что бы вы сделали в этой ситуации?

ответ

62

Если метод имеет то же имя, то есть вы переопределяете метод, вы можете просто использовать super. В противном случае вы можете использовать alias_method или привязку.

class Parent 
    def method 
    end 
end 

class Child < Parent 
    alias_method :parent_method, :method 
    def method 
     super 
    end 

    def other_method 
     parent_method 
     #OR 
     Parent.instance_method(:method).bind(self).call 
    end 
end 
+0

Это не работает. 'Child.new.other_method' возвращает' NoMethodError: super: no superclass method 'other_method' для # '. Вызов 'super.method()' будет вызывать 'метод' только при вызове' super' (который в этом случае не существует). 'super' не является ссылкой на« суперкласс »экземпляра. – Cade

+0

@ Признайте, что вы абсолютно правы. Я сделал редактирование для этого –

+1

Также вызов 'super' вызовет супер с точными аргументами, которые были переданы дочернему методу. Если вы хотите указать заданные аргументы, вы можете вызвать супер с ними: EG: 'def child (a, b); супер; end' vs 'def child (a, b); супер (somevar); end' – Adam

11

super ключевое слово в Ruby, на самом деле вызывает метод того же имени в родительском классе. (source)

class Foo 
    def foo 
    # Do something 
    end 
end 

class Bar < Foo 
    def foo 
    super # Calls foo() method in parent class 
    end 
end 
+11

Полагая пример в Java, не самая лучшая идея, если реквестер явно упоминает PHP как другой язык, который он знает ... –

+1

этот ответ был полезен для меня, и он говорит, что знает, что PHP и другие языки имеют эту функцию (не это он знает только PHP). –

15

super keyword вызывает метод с тем же именем в супер класс:

class Foo 
    def foo 
    "#{self.class}#foo" 
    end 
end 

class Bar < Foo 
    def foo 
    "Super says: #{super}" 
    end 
end 

Foo.new.foo # => "Foo#foo" 
Bar.new.foo # => "Super says: Bar#foo" 
5

Другие говорили, это уже хорошо. Только один дополнительный предостережение:

Синтаксис super.foo для вызова метода foo в супер классе не поддерживается. Скорее это вызовет метод super и по возвращенному результату попробуйте позвонить foo.

class A 
    def a 
     "A::a" 
    end 
    end 

    class B < A 
    def a 
     "B::a is calling #{super.a}" # -> undefined method `a` for StringClass 
    end 
    end 
+0

Это важное различие, о котором люди должны знать, поэтому спасибо, что указали это! – Magne

0
class Parent 
    def self.parent_method 
    "#{self} called parent method" 
    end 

    def parent_method 
    "#{self} called parent method" 
    end 
end 

class Child < Parent 

    def parent_method 
    # call parent_method as 
    Parent.parent_method    # self.parent_method gets invoked 
    # call parent_method as 
    self.class.superclass.parent_method # self.parent_method gets invoked 
    super        # parent_method gets invoked 
    "#{self} called parent method"  # returns "#<Child:0x00556c435773f8> called parent method" 
    end 

end 

Child.new.parent_method #This will produce following output 
Parent called parent method 
Parent called parent method 
#<Child:0x00556c435773f8> called parent method 
#=> "#<Child:0x00556c435773f8> called parent method" 

self.class.superclass == Parent #=> true

Parent.parent_method и self.class.superclass будет вызывать self.parent_method (метод класс) Parent в то время как super вызывает (метод экземпляра) parent_method из Parent.