为几何形状(点,线,正方形,三角形等)创建类(红宝石)

时间:2016-06-02 00:00:54

标签: ruby class geometry shape

我现在正在代码学校学习,导师会给我们一份家庭作业,但我并没有真正得到它。你能救我吗?

因此,我们被要求通过类创建几何形状:

  1. 首先我们必须创建一个Point类
  2. 然后我们必须创建类Line(行 - 连接两个点时)
  3. 和下一步,例如我们要创建一个正方形
  4. 我已经开始编码,并创建了一个类Point,可访问坐标(2d):

    class Point
      attr_accessor :x, :y
      def initialize
        @x = 10
        @y = 10
      end
      def x=(value)
        @x = value
      end
      def x()
        @x
      end
      def y=(value)
        @y = value
      end
      def y()
        @y
      end
    end
    

    例如,我想创建一个新的点类。所以:

    p = Point.new
      p.x = 1
      p.y = 5
      print p # -> #<Point:0x007f9463089cc0>
    

    结果我有这样的事情:

    #<Point:0x007f9463089cc0>
    

    这是什么意思?

    但如果我要求打印p.x和p.y - 那么我将得到一个可以理解的结果:

    print p.x, ", ", p.y # -> 1, 5
    

    我做错了什么或者如何在屏幕上理解这个结果?

    拜托,我真的需要帮助来理解这个...

    感谢您的帮助!

    出现了另一个问题,在实际编程工作中是否有用于创建点,线和几何形状的东西?

4 个答案:

答案 0 :(得分:1)

首先,你不需要设置者和吸气剂。我的意思是你不需要写这些方法:

  def x=(value)
    @x = value
  end
  def x()
    @x
  end
  def y=(value)
    @y = value
  end
  def y()
    @y
  end

您不需要这些方法的原因是您有这个电话:

attr_accessor :x, :y

并且该方法(attr_accessor)完全适合您。

其次,您可能希望在构造函数中允许一些灵活性,即,您的initialize方法允许传递x和y的值,并且如果没有传递则将它们默认为10。所以你可以这样做

def initialize(x = 10, y = 10)
  @x = x
  @y = y
end

这样,你就会得到这个:

p1 = Point.new 
puts p.x # => 10
puts p.y # => 10

p2 = Point.new(15, 20)
puts p.x # => 15
puts p.y # => 20

注意p1的方法我没有传递任何参数,但x和y都按预期设置,这是因为我们在方法定义中为它们设置了默认值,这里:

def initialize(x = 10, y = 10)

现在,关于你为什么看到这个的问题:

p = Point.new
p.x = 1
p.y = 5
print p # -> #<Point:0x007f9463089cc0>

什么点:0x007fa003885bf8意味着你有一个Point类的实例(这是你在变量p中所拥有的)。默认情况下,当您尝试打印对象时,ruby将在对象上调用to_s方法,因为在您的情况下,您没有定义该方法,它将通过继承链来查看谁定义该方法。事实证明,该方法可以在Object类中找到(所有ruby对象都隐式继承自Object类),该方法的默认行为是打印类的名称,后跟实例在内存中的id,格式为:#(check :http://ruby-doc.org/core-2.3.1/Object.html#method-i-to_s

如果要更改它,则可以将to_s方法覆盖为以下内容:

def to_s
  "Point #{x},#{y}"
end

你会得到:

puts Point.new # => Point 10,10

希望有所帮助。

答案 1 :(得分:1)

没有错。 #<Point:0x007f9463089cc0>仅表示它是对象标识为#<>的类Point的实例(0x007f9463089cc0部分)。对象id是Ruby运行时用于查找每个对象的标识符,非常类似于内存地址。

虽然一切都很好,但Ruby中始终有一种方法可以减少代码。例如

class Point
  attr_accessor :x, :y

  def initialize(x = 10, y = 10)
    @x, @y = x, y
  end
end

甚至

Point = Struct.new(:x, :y)

答案 2 :(得分:0)

因为您宣布attr_accessor :x, :y 实际上你不需要为x和y定义getter和setter。 所以你的课程可以简化为

class Point
  attr_accessor :x, :y
  def initialize
    @x = 10
    @y = 10
  end
end

您还可以向Point

添加方法to_s
class Point
  attr_accessor :x, :y
  def initialize
    @x = 10
    @y = 10
  end

  def to_s
     "(#{x}, #{y})"
  end
end

这样您就可以使用puts p并在执行时获得ouptut (10, 10)

p = Point.new
puts p
(10, 10)  

在这里,我更喜欢使用puts而不是print,因为它在输出后插入一个新的行字符,并且看起来更具可读性。 在to_s方法中,我使用ruby的字符串插值"#{}"为你的点实例构建一个很好的输出。

答案 3 :(得分:0)

方法selectprint输出puts的结果,to_s输出p的结果。除非您覆盖这些方法,否则默认情况下,继承inspect的自定义类会返回您获得的Object形式。如果您想要其他输出,请覆盖这些方法,例如

#<class_name:object_id>