2016-06-06 5 views
2

Ich versuche, die folgenden Funktionen ausführen:Kann man Polymorphie durch Überladung machen?

class SUM 
    def make_sum (number) 
    return number+number 
    end 

    def make_sum (number_a, number_b) 
    return number_a+number_b 
    end 
end 

operation = SUM.new 
operation.make_sum(5) # returns 10 
operation.make_sum(2, 3) # returns 5 

make_sum Verfahren nach einem Eingang neu definiert durch den ein mit zwei Eingängen.

+2

Ich stimme Jonny zu. Es handelt sich zwar nicht streng um ein Duplikat in Bezug auf die Frage, aber es berührt die Art des Problems: "Anzahl der Argumente", "Arten von Argumenten" usw. wird eigentlich eher als "Überladung" denn als "Polymorphismus" bezeichnet. Polymorphismus ist eine etwas andere Sache, und Multiple-Dispatch ist auch eine andere Sache als "Anzahl der Eingaben". Die Frage "Warum nicht Rubin (..)" zeigt, dass das Überladen nicht unterstützt wird und warum und das fasst diese Frage auch zusammen. – quetzalcoatl

+1

Wie jedoch Keith und Marcus in ihren Antworten zeigen, können Sie, auch wenn das 'Überladen' nicht möglich ist, mit '* args' Trick simulieren - Argumente als Array nehmen, die Länge dieses Arrays untersuchen und dann etwas anderes machen auf dieser Länge. Aber das ist weder Polymorphismus, noch Überlastung. Das ist nur manuelle Codierung ohne objektorientierten Namen (da es nichts mit OO zu tun hat :)). Ein gebräuchlicher Name dafür ist nur "splat args" oder "splat operator". [Siehe hier für einige Beispiele] (http://jacopretorius.net/2012/01/splat-operator-in-ruby.html) – quetzalcoatl

+0

Nein, Sie können nicht zwei Methoden mit demselben Namen, aber verschiedenen Argumenten in Ruby definieren. Der letzte hat gewonnen, die erste Methodendefinition ist nicht mehr da. – jrochkind

Antwort

2

Wenn der Zusatz ist, was Sie wollen, können Sie es tun einfacher als:

def add(*numbers) 
    numbers.inject(&:+) 
end 

add(1) # => 1 
add(1, 3, 5) # => 9 

Wenn Sie sich für eine allgemeine Lösung für das Problem zu suchen, wie Verhalten auf die abhängige bereitzustellen Anzahl der Argumente, Sie dann *args in der Signatur verwenden und dann auf args.size Basis Zweig:

def foo(*args) 
    case args.size 
    when 1 
     # do something 
    when 2 
     # do something else 
    when (3..5) 
     # do another thing 
    end 
end 
0

ich hatte die gleiche Reaktion auf dieses als @keith-bennett. Aber ich wusste nicht, dass es so einfach war wie seine Antwort. Hier war meine Lösung:

class Foo 
    def self.add(*args) 
     r = 0 
     if args.length > 1 
      args.each { |a| r += a.to_i } 
     else 
      r += (args[0].to_i + args[0].to_i) 
     end 
     return r 
    end 
end 

f = Foo 
puts f.add(1, 2) 
# => 3 
puts f.add(1) 
# => 2