我知道抽象类不是 Ruby 中的一个特性,当然这背后有一个哲学原因,但我想知道是否有办法解决通常在其他语言(如 C++ 和 Java)中使用抽象类解决的问题。
例如: 我需要三个课程
Triangle
、Square
和Circle
。因为这些都是几何图形,所以我正在考虑用抽象方法 AbstractFigure
编写一个名为 get_area
的抽象类,该方法将由具体类 Triangle
、Square
和 Circle
实现。
我怎样才能遵循 Ruby 哲学来做到这一点?
你是对的,它在 ruby 中并不作为一个明确定义的概念存在,不像 Java 等其他语言,它被大量使用。
但你也说得对,有很多情况都值得这样做。
以下是我的做法,以您为例 -
class AbstractShape
attr_accessor :edges
def initialize
# ...
end
def get_area
raise NoMethodError("Override this implementation")
end
end
class Square < AbstractShape
def initialize
# square-specific stuff
super
end
def get_area
self.edges * foo * bar
end
end
关键是在顶层定义所有可用的方法,以提高可读性和一致性,但要确保它们在使用时会引发错误。
如果有一种方法您绝对确定会在所有形状中以相同的方式一致使用,则在
AbstractShape
中定义它
attr_accessor
也将继承,因此每个形状的每个实例都可以使用 @edges
。但是您仍然可以在 AbstractShape
类中拥有引用 @edges
的方法,因为它们只会使用正确的本地实例变量。
使用仅引发
AbstractFigure
的方法 get_area
定义普通类 NotImplementedError
。然后每个派生类用它自己的实现重写 get_area
方法。
class AbstractFigure
def get_area
raise NotImplementedError.new( 'appropriate error message' )
end
end
class Square < AbstractFigure
def get_area
# implementation here
end
end