【问题标题】:Access an instance variable from child classes从子类访问实例变量
【发布时间】:2015-06-09 22:35:59
【问题描述】:

我正在尝试从子类访问父类的数据成员。我不知道怎么称呼它。我发现了很多关于访问类变量而不是来自子类的实例变量的信息。这是我的代码:

class Shape

    @var = "woohoo"

    def initialize ()

    end

    def area ()

    end

end


class Rectangle < Shape

    @length
    @width

    def initialize ( l,w )
        @length = l
        @width = w
    end

    def area ()
      print @var
      return @length * @width
    end

end

我在尝试打印 @var 时遇到错误。我尝试了 parent.@var、Shape.@var 以及我期望从其他语言获得的许多其他组合。在子类的实例中打印(并在可能的情况下更改)该变量的正确方法是什么?

编辑:我希望子类的各个实例用他们自己的唯一字符串替换“woohoo”字符串。

谢谢!

【问题讨论】:

    标签: ruby


    【解决方案1】:

    我正在尝试从孩子访问父类的数据成员 班级。我不知道怎么称呼它。我找到了很多关于 从子级访问类变量而不是实例变量 班级。这是我的代码:

    class Shape
      @var = "woohoo"
    

    该变量称为类实例变量,人们使用类实例变量而不是类变量(即@@variable)的原因恰恰是这样子类就无法访问它。因为 类实例变量 是类变量在其他语言中的工作方式,@@variables 在 ruby​​ 中使用不多,因为如果您来自其他具有类变量的语言,它们的行为会令人惊讶。

    您的用例显然要求在子类中可以访问一个类变量,因此请使用@@variable

    编辑:我希望子类的单个实例替换 'woohoo' 字符串具有自己独特的字符串。

    您可以为此使用类实例变量

    class Shape
      @var = "shapehoo"
    
      class <<self
        attr_accessor :var
      end
    
      def display_class_instance_var
        puts Shape.var
      end
    
    end
    
    class Rectangle < Shape
      @var = "recthoo"
    
      def display_class_instance_var
        puts Rectangle.var
      end
    end
    
    class Circle < Shape
      @var = "circlehoo"
    
      def display_class_instance_var
        puts Circle.var
      end
    end
    
    Shape.new.display_class_instance_var
    Rectangle.new.display_class_instance_var
    Circle.new.display_class_instance_var
    Rectangle.new.display_class_instance_var
    Shape.new.display_class_instance_var
    
    --output:--
    shapehoo
    recthoo
    circlehoo
    recthoo
    shapehoo
    

    与常规实例变量一样,类实例变量是私有的,因此如果要访问它们,则必须提供访问器方法。访问器需要在类的单例类中,您可以使用以下语法打开它:

    class <<self
    
    end
    

    添加:

    关于这段代码:

    class Rectangle < Shape
    
        @length
        @width
    
        def initialize ( l,w )
            @length = l
            @width = w
        end
    

    在您的initialize() 方法中,您没有设置您在initialize 方法上方声明的@length、@width 变量。在 ruby​​ 中,@variables 在创建@variables 时将自己附加到self 的任何对象。更详细的代码如下所示:

    class Rectangle < Shape
        #self=Rectangle class
        @length
        @width
    
        def initialize ( l,w )
            #self=a new instance of the Rectangle class created by initialize
            @length = l
            @width = w
        end
    

    因此,在initialize() 中创建的@variables 将自己附加到新实例,而在initialize() 上面声明的@variables 将自己附加到Rectangle 类,这意味着它们是完全不同的变量。

    【讨论】:

    • 为什么要使用 class
    • @Lukas Baliak, 1)why use class &lt;&lt;self insted of just accessor?-- 因为在类级别调用 attr_accessor 会为名为 @var 的实例变量创建访问器——而不是为名为 @var 的类实例变量创建访问器. 2)and why call Rectangle.var insted o self.var -- 因为在一个实例方法内部,self等于调用方法的instance,但是访问器方法是定义在类对象上的,所以需要调用访问器与类对象。你可以写self.class.var
    • @LukasBaliak,不客气。我猜这个操作根本不想使用类变量。
    【解决方案2】:

    您可以使用“super”来调用父类初始化块并定义实例变量“@var”。 在这种情况下,您可以为另一个实例修改此实例变量的值。像这样:

    class Shape
      def initialize ()
        @var = "woohoo"
      end
    end
    
    class Rectangle < Shape
      def initialize(l, w)
        @length = l
        @width = w
        super()
      end
    
      def area()
        print @var
        return @length * @width
      end
    
      def var=(new_value)
        @var = new_value
      end
    end
    
    a = Rectangle.new(1,1)
    a.area
    # => woohoo1
    a.var = "kaboom"
    a.area
    # => kaboom1
    
    b = Rectangle.new(2,2)
    b.area
    # => woohoo4
    

    或者你可以使用 attr_accessor

    class Shape
      def initialize
        @var = "woohoo"
      end
    end
    
    class Rectangle < Shape
    
      attr_accessor :var
      def initialize(l, w)
        @length, @width = l, w
        super()
      end
    
      def area()
        print @var
        return @length * @width
      end
    end
    
    a = Rectangle.new(1,1)
    a.area
    # => woohoo1
    a.var = "kaboom"
    a.area
    # => kaboom1
    
    b = Rectangle.new(2,2)
    b.area
    # => woohoo4
    

    【讨论】:

    • 并定义类变量“@var” 您的代码没有定义任何类型的任何类变量。实例变量的重要特征是它们可以对每个实例具有不同的值,而类(实例)变量对所有实例具有相同的值。
    • 如果 Shape 初始值设定项有一些 Rectangle 初始值设定项中不存在的参数怎么办?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-23
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    • 2022-08-11
    • 2011-02-21
    • 2011-05-11
    相关资源
    最近更新 更多