学习Ruby。我接受了这个代码挑战:
创建表示方形,矩形和圆形的类。您应该能够计算每个形状的面积。 (还有一部分关于能够设置颜色以及继承默认颜色,但这不是我难以理解的部分,因此我不会在此处包含规范。)
这些类还应该能够调用一个can_fit?
方法来评估两个形状,并根据另一个形状内部的一个形状返回true或false。
所以我已经很好地创建了形状类,我正在计算方形,矩形和圆形的区域。
但我完全被can_fit?
方法所困扰。我应该将它包含在Shape
类中,但是如果我们使用区域进行比较,我如何比较Shape
类中的一个形状是否适合另一个形状,Shape
不会无法访问区域?
class Shape
attr_accessor :color
def initialize(color="Red")
@color = color
end
def can_fit?(shape)
DEFINE METHOD
end
end
class Rectangle < Shape
attr_accessor :color, :shape, :width, :height
def initialize(width, height, color="Red")
super(color)
@width = width
@height = height
end
def area
@width * @height
end
end
class Square < Rectangle
def initialize(width, color= "Red")
super(width, width, color)
end
end
class Circle < Shape
attr_accessor :color, :shape, :radius
def initialize(radius, color= "Red")
super(color)
@radius = radius
end
def area
Math::PI * (radius ** 2)
end
end
RSpec测试:
describe "Shape" do
describe "can_fit?" do
it "should tell if a shape can fit inside another shape" do
class A < Shape
def area
5
end
end
class B < Shape
def area
10
end
end
a = A.new
b = B.new
b.can_fit?(a).should eq(true)
a.can_fit?(b).should eq(false)
end
end
答案 0 :(得分:1)
Ruby并不介意Shape
没有区域方法。它只关心对象在评估瞬间的行为方式。对于下面的can_fit?
方法,self
是Square的实例,other_shape
是圆的实例。两者都有面积法。很好!如果other_shape
完全是其他对象,只要它具有area
方法,它仍然可以正常工作。
E.g。 (在这里忽略'计算'!)
2.0.0-p195 :001 > class Shape
2.0.0-p195 :002?> def can_fit? other_shape
2.0.0-p195 :003?> area > other_shape.area
2.0.0-p195 :004?> end
2.0.0-p195 :005?> end
=> nil
2.0.0-p195 :006 > class Square < Shape
2.0.0-p195 :007?> def area
2.0.0-p195 :008?> 2
2.0.0-p195 :009?> end
2.0.0-p195 :010?> end
=> nil
2.0.0-p195 :011 > class Circle < Shape
2.0.0-p195 :012?> def area
2.0.0-p195 :013?> 1
2.0.0-p195 :014?> end
2.0.0-p195 :015?> end
=> nil
2.0.0-p195 :016 > Square.new.can_fit? Circle.new
=> true
然后......
2.0.0-p195 :017 > class Cat # doesn't inherit from anything
2.0.0-p195 :018?> def area
2.0.0-p195 :019?> 1.5
2.0.0-p195 :020?> end
2.0.0-p195 :021?> end
=> nil
2.0.0-p195 :022 > Square.new.can_fit? Cat.new
=> true
答案 1 :(得分:0)
一个天真的解决方案是看一个形状的高度和宽度是否小于或等于你试图将第一个形状放入的形状的高度和宽度。
对于圆圈,宽度和高度都是圆的直径。
我说“天真”,因为我不知道你是否可以旋转这些形状或不适合它们。(4x6矩形 适合7x5矩形,但只有你'能够旋转矩形。)如果是这样,那么你可能需要计算其他尺寸,比如矩形的对角线。
我知道你在做Ruby,但你可能需要注意看看Ruby中的继承意味着什么。 Scott Meyers关于C ++的一本书使用了这个确切的例子来说明数学模型(“正方形也是一个矩形”)如何在C ++继承面前崩溃。来自类Rectangle的派生类Square不能用与数学定义相同的优雅来表达。我不知道Ruby的那个答案,但你会想看看它(只要你正在学习)。
答案 2 :(得分:0)
是否可以使用已定义的方法创建一个新类Area并将Shape调用到该区域?只是一个想法
答案 3 :(得分:0)
假设我们有
c = Circle.new(2)
r = Rectangle.new(2,3)
现在让我们将以下方法添加到class Shape
:
def self_check
puts self
end
将此方法发送到c
和r
,我们会收到以下信息:
c.self_check # => #<Circle:0x007fd71927fc98 @color="Red", @radius=1>
r.self_check # => #<Rectangle:0x007fd71925e368 @color="Red", @width=2, @height=3>
因此即使self_check
在父类中,self
也是调用它的子类的实例。这意味着can_fit?(other_shape)
可以访问形状实例self
以及参数other_shape
。因此,我们可以做以下1:
def can_fit?(other_shape)
case self
when Circle
case other_shape
when Circle
self.radius <= other_shape.radius
when Rectancle, Square
self.radius <= [other_shape.width, other_shape.height].min
end
when Rectangle
case other_shape
when Circle
...
...
要查看特定实例实例c
是否适合特定的矩形实例r
,我们将执行:
c.can_fit?(r)
1请注意,case语句使用===
运算符,而不是==
构造使用的if/then
运算符。这就是case
可以评估self === Circle
是否为真的原因。
答案 4 :(得分:0)
你需要定义一个can_fit吗?类形状中使用self.area与other_shape.area相比的方法
因为每个班级都有一个区域:
def can_fit?(other_shape)
self.area > other_shape.area
end