庄周梦蝶
生活、程序、未来
::
首页
:: :: ::
聚合
::
管理
ruby实现抽象类和抽象方法
Posted on 2007-02-06 13:07
dennis
阅读(1447)
评论(1)
编辑
收藏
所属分类:
动态语言
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中,抽象类和抽象方法是否有用存在怀疑,不过知道这样的办法总是不错的主意
评论
#
re: ruby实现抽象类和抽象方法
回复
更多评论
2007-02-06 20:01 by
rubycainiao
连句柄的类型都没有了,还要多态干什么呢?
新用户注册
刷新评论列表
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
IT新闻
知识库
C++博客
博问
管理
相关文章:
详解Clojure的递归(上)—— 直接递归及优化
Clojure的并发(一) Ref和STM
Clojure的dosync是正则序?
Clojure Hacking Guide
闭包使用的一个陷阱
Ruby Fiber指南(五): 实现Actor,兼谈Erlang的process调度
Actor、Coroutine和Continuation的概念澄清
Ruby Fiber指南(四)迭代器
Ruby Fiber指南(三)过滤器
Ruby Fiber指南(二)参数传递
Powered by:
BlogJava
Copyright © dennis
公告
关于我
随笔分类
Android相关
C#历程(13)
Clojure(43)
erlang(16)
Hadoop与分布式(16)
java(176)
linux & C(25)
my open-source(100)
node.js(5)
unix网络编程(6)
web开发(13)
动态语言(81)
小毅同学二三事(1)
工作流(5)
工作随笔(9)
工具和命令(4)
数据库技术(14)
数据结构与算法(26)
模式与架构(30)
涂鸦(141)
源码解读(28)
移动开发(1)
计算机科学与基础(56)
软件工程(6)
友情链接
About me
Clojure中文技术社区
xmemcached
多背一公斤
梦想风暴
淘宝Java中间件
美味书签
美味书签团队博客
美味爱读
邢红瑞的blog
阿宝的blog
阿欢的blog
最新随笔
1. 博客搬迁
2. Another URL Shortener using NodeJS
3. Clojure中文专业技术社区
4. Ring.velocity:render velocity templates for ring in clojure
5. Clojure笔记:用好type hint
6. Clojure世界:利用HouseMD诊断clojure
7. 分布式消息中间件Metaq发布1.4.3
8. 如何熟悉一个开源项目?
9. Emacs + Clojure配置的几个Tip
10. clj.monitor : monitoring applications in clojure based on SSH
搜索
最新评论
1. vitamind28448
评论内容较长,点击标题查看
--Good post. I learn something totally new and chall
2. re: Aviator——让表达式飞起来
很好用,刚用到最近的一个项目中
--welcomezhang
3. re: Java字符串的最大长度
写得很好
--zzz
4. clashofclanshack1155
Very clean site, thanks for this post.
--Very clean site, thanks for this post.
5. binaryrobot89773
评论内容较长,点击标题查看
--Howdy! I simply wish to offer you a big thumbs up