【问题标题】:Inheritance initialize parameters继承初始化参数
【发布时间】:2015-05-29 01:17:21
【问题描述】:

我想知道如何正确初始化子类“计算机”。我希望它继承Game类中initialize中的属性,除了#start,它是一个方法。在这种情况下,我也不确定如何处理初始化方法中的参数。有谁知道一个优雅的方式来改写它?谢谢。

class Game
    attr_reader :input, :clues

    def initialize
        colors = %w(R O Y G I V)
        code = []
        all = ''
        count = 0
        start
    end

    def start
        ...
    end

    def ask_input
        ...
    end

class Computer < Game
    attr_reader :input, :clues
    def initialize
        colors = %w(R O Y G I V)
        code = []
        all = ''
        count = 0
        ask_input
        computer_turn
    end
 .....
 end

【问题讨论】:

  • 一种方法——甚至不要在initialize 中这样做,而是定义一个自定义设置器,例如def colors; @colors ||= %w(R O Y G I V); endGame 上,然后将在Computer 中提供。
  • 虽然我通常建议将您的变量重组为自定义 setter 方法以便更清晰地继承,但请参阅this question 以获取问题的答案。

标签: ruby inheritance initialization subclass super


【解决方案1】:

我希望它继承Game类中initialize中的属性,除了#start,它是一个方法。

所有属性和方法都将被继承。你这样做是正确的:

class Computer < Game

您不需要 attr_reader,因为它是从 Game 继承的。

我也不确定在这种情况下如何处理初始化方法中的参数。

您可以执行以下操作。它接受一个输入作为参数。考虑:

computer = Computer.new( :foo )

计算机初始化后,input等于:foo

class Computer < Game
  def initialize input
    @input = input
    ...

见:

computer.input
=> :foo

【讨论】:

  • 我不希望计算机继承#start。我希望它以 ask_input 开头。上面写的不行。
  • 您可以将start标记为私有,这样就不会被继承了。
【解决方案2】:

我也不确定在这种情况下如何处理initialize方法中的参数

你只是

  • 在子类的initializer中添加super,调用其超类的initializer
  • 当然,所有实例变量都应该在开头有 @ 字符,以使它们在所有实例方法中都可用。
  • 还要从Computer 类中删除attr_reader,因为它将继承自Game

我希望它继承Game类中initialize中的属性,除了#start是一个方法

  • 最后,为了避免调用Game类的方法#start,我认为你只需要在Computer类中重写它

结果代码

    class Game
      attr_reader :input, :clues

      def initialize
        @colors = %w(R O Y G I V)
        @code = []
        @all = ''
        @count = 0
        start
      end

      def ask_input
        # sample value for @input 
        @input = 'sample input'
      end

      def start
        puts "start"
      end
    end

    class Computer < Game
      #attr_reader :input, :clues

      def initialize
        super
        ask_input
        computer_turn
      end

      def start
        # Do nothing
      end

      def computer_turn
        puts "computer_turn"
        p @colors
      end
    end


    comp = Computer.new
    # The string "start" is not puts here because Game#start is not called
    => computer_turn
    => ["R", "O", "Y", "G", "I", "V"]

    comp.input
    => "sample input"

【讨论】:

    【解决方案3】:

    由于您不想要 start 方法,只需将其从您的 Game 类中删除,这样它就不会出现在您的子类中。类似的东西:

    class Game
        attr_reader :input, :clues
    
        def initialize
            colors = %w(R O Y G I V)
            code = []
            all = ''
            count = 0
            (Insert what start does here)
        end
    
    
        def ask_input
            ... 
        end
    

    然后,只需重写 Computer 子类的初始化:

    def initialize
        colors = %w(R O Y G I V)
        code = []
        all = ''
        count = 0
        (insert other functionalities)
    end
    

    你也可以去掉多余的attr_reader,因为它继承自Game

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多