2007-02-06
ruby实现抽象类和抽象方法
ruby语言本身并没有提供abstract class和abstract method机制。这是ruby的spirit所决定的。但如果我们真的需要定义一个公共抽象类(或者抽象方法)来让子类来实现,又该如何做呢?
我们可以通过在调用方法时抛出NotImplementedError来防止方法被调用。如(来自《ruby cookbook》的例子):
class Shape2D
def area
raise NotImplementedError.new("#{self.class.name}#area是抽象方法")
end
end
class Square < Shape2D
def initialize(length)
@length = length
end
def area
@length ** 2
end
end
父类Shape2D的方法area就是我们所需要的“抽象方法”了。你不能直接调用:
s1=Shape2D.new
s1.area
这样调用将抛出错误:Shape2D#area是抽象方法 (NotImplementedError)
Shape2D的子类Square覆写了此方法。由此我们模拟实现了抽象方法。那么抽象类该如何实现呢?自然而然,我们想到如果把类的initialize方法这样处理,那么这样的类将没办法被new生成,不正是我们所需要的抽象类?说干就干:
class Shape2D
def initialize
raise NotImplementedError.new("#{self.class.name}#area是抽象类")
end
def area
raise NotImplementedError.new("#{self.class.name}#area是抽象方法")
end
end
当你调用Shape2D.new时,解释器将提示你:Shape2D是抽象类(NotImplementedError)
我们已经实现了抽象方法和抽象类,感觉还是不够好,对每一个需要实现抽象类的类来说,我们都需要去写一句:raise NotImplementedError.new...实在不够爽。ruby鼓励我们去修改类的行为,甚至是标准库,那好,我们修改Class类吧,提供类似attr_reader的声明式服务:
class Class
def
abstract(*args)
args.each do |method_name|
define_method(method_name) do |*args|
if method_name == :initialize
msg = "#{self.class.name}是抽象类"
else
msg = "#{self.class.name}##{method_name}是抽象方法"
end
raise NotImplementedError.new(msg)
end
end
end
end
OK,如此一来,我们的Shape2D可以写成:
class Shape2D
abstract:initialize,:area #initialize和area是抽象方法
end
尽管在ruby中,抽象类和抽象方法是否有用存在怀疑,不过知道这样的办法总是不错的主意
我们可以通过在调用方法时抛出NotImplementedError来防止方法被调用。如(来自《ruby cookbook》的例子):
class Shape2D
def area
raise NotImplementedError.new("#{self.class.name}#area是抽象方法")
end
end
class Square < Shape2D
def initialize(length)
@length = length
end
def area
@length ** 2
end
end父类Shape2D的方法area就是我们所需要的“抽象方法”了。你不能直接调用:
s1=Shape2D.new
s1.area这样调用将抛出错误:Shape2D#area是抽象方法 (NotImplementedError)
Shape2D的子类Square覆写了此方法。由此我们模拟实现了抽象方法。那么抽象类该如何实现呢?自然而然,我们想到如果把类的initialize方法这样处理,那么这样的类将没办法被new生成,不正是我们所需要的抽象类?说干就干:
class Shape2D
def initialize
raise NotImplementedError.new("#{self.class.name}#area是抽象类")
end
def area
raise NotImplementedError.new("#{self.class.name}#area是抽象方法")
end
end 当你调用Shape2D.new时,解释器将提示你:Shape2D是抽象类(NotImplementedError)
我们已经实现了抽象方法和抽象类,感觉还是不够好,对每一个需要实现抽象类的类来说,我们都需要去写一句:raise NotImplementedError.new...实在不够爽。ruby鼓励我们去修改类的行为,甚至是标准库,那好,我们修改Class类吧,提供类似attr_reader的声明式服务:
class Class
def
abstract(*args)
args.each do |method_name|
define_method(method_name) do |*args|
if method_name == :initialize
msg = "#{self.class.name}是抽象类"
else
msg = "#{self.class.name}##{method_name}是抽象方法"
end
raise NotImplementedError.new(msg)
end
end
end
endOK,如此一来,我们的Shape2D可以写成:
class Shape2D
abstract:initialize,:area #initialize和area是抽象方法
end尽管在ruby中,抽象类和抽象方法是否有用存在怀疑,不过知道这样的办法总是不错的主意
- 13:07
- 浏览 (589)
- 评论 (0)
- 分类: ruby & rails
- 相关推荐
发表评论
我的留言簿
-
你好,看过你关于自定义classloader的回帖,想问问几个问题:
  ...
-- by llp20_2000
最近加入圈子
最新评论
-
Ruby Tip——读文件
花花公子 写道IO.read("test.log")嗯,这个方法我是知道的,我前 ...
-- by dennis_zane -
Ruby Tip——读文件
IO.read("test.log")
-- by 花花公子 -
一封邮件
咋我没收到呢....
-- by yangzhihuan -
漂亮的代码
说得比较深.看的时候,觉得句句都正中心坎.看完之后,好像没啥收获.还是要自己试过 ...
-- by yangzhihuan -
广州opensource camp小记
貌似你那件open source camp的T-shirt背后很多广告滴说.
-- by yangzhihuan







评论排行榜