2012-11-02 12 views
1

所以这里是一个比较Java的彼岸方法(我想)......我在这的Ruby代码怎么办多态性在Ruby中

class Human 
    def move 
    p 'Human move: X' 
    end 
end 


class Computer 
    def move 
    p'Computer move: O' 
    end 
end 

class Player 
    def initialize(letter) 
    if letter == 'X' 
     return Human.new 
    else 
     return Computer.new 
    end 
    end 
end 

bob = Player.new('X') 
bob.move 

我期待尽快回到CLI“招人:X” 我得到以下...

undefined method `move' for #<Player:0x007f8d930895a8> (NoMethodError) 

任何人可以帮助这个红宝石小白的错误?

-------------------------讨论-------------------- ----

现在我已经想通过继承和重写来实现这一点,我猜想,'经典'Ruby风格是这样做的。现在,这对我脑海中的子处理器是没有意义的。我的意思是,如果我这样做......我可以在其他类文件中只需要类文件并实例化一个新对象。它并不真正感到多态性它的方式,当你做到这一点在Java中....这里是代码....

class Player 
    def move 
    return "" 
    end 
end 

class Human < Player 
    def move 
    return 'Human move: X' 
    end 
end 


class Computer < Player 
    def move 
    return'Computer move: O' 
    end 
end 



players = [Human.new, Computer.new] 
players.each {|player| 
    print player.move 
} 

回答

4

你几乎做到:)在Ruby中,你不能从构造函数返回的任意对象。那么,你可以,但那个返回值被忽略。而是使用Factory Method(在OOP中说)。

class Human 
    def move 
    p 'Human move: X' 
    end 
end 


class Computer 
    def move 
    p 'Computer move: O' 
    end 
end 

class Player 
    def self.get_player(letter) 
    if letter == 'X' 
     return Human.new 
    else 
     return Computer.new 
    end 
    end 
end 

bob = Player.get_player('X') 
bob.move 
# >> "Human move: X" 
+0

难道他不能只是重写'Player.new'吗?我相信我曾经这样做过,但我必须回去找到它。 –

+1

@phoffer:是的,我认为他可以,但他不应该。 –

+0

雅有可能,我只是自己做了。与你的一样,但将self.get_player改为self.new,然后将第二行改为最后一行。你介意解释为什么这是不好的做法吗? –

1

你打电话Player.new,所以你会得到一个Player对象返回,不管你在initialize函数中返回什么。如果由于某种原因,你不想直接实例HumanComputer,做这样的事情:

class Player 
    def self.new_player(letter) 
    if letter == 'X' 
     return Human.new 
    else 
     return Computer.new 
    end 
    end 
end 

bob = Player.new_player('X') 
bob.move #Prints your output