`

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中,抽象类和抽象方法是否有用存在怀疑,不过知道这样的办法总是不错的主意
分享到:
评论

相关推荐

    abstract_class:Ruby 中的抽象类

    Ruby 中的抽象类。 像模块一样,抽象类不能被实例化。 与模块不同,抽象类可以被继承,并且它们的派生类可以被实例化。 查看或实现以获取其他示例。 安装 gem install abstract_class 要求 Ruby 1.8.7+ 用法 要...

    Ruby类继承、抽象类、类拓展混入、代理类实例

    总结一下工作中遇到的类扩展: 1、类继承: 当多个类公用很多方法的时候...2、抽象类 当多个类要继承一个类时,用第一种方法,会遇到一个问题。 (引用一个别人的注解来描述抽象类的运用吧https://ihower.tw/rails4/

    将Zoho的API抽象为一组Ruby类,使用更熟悉的ActiveRe.zip

    将Zoho的API抽象为一组Ruby类,使用更熟悉的ActiveRe

    Ruby On Rail最新开发软件版本

    对于初学者来说,我觉得首先入门类书籍应该选择《programming ruby中文版 第2版》书里写的内容相当仔细,详细。而且这么书应该一直放在你的床头随手可取到的地方,即使在你看完以后它可以作为你的参考书。目前我还...

    RLTK:Ruby语言工具包

    欢迎使用Ruby语言工具包RLTK是旨在帮助程序员以易于使用和直接的方式使用语言的类和方法的集合。 该工具包提供以下功能: Lexer发生器解析器生成器AST节点基类表示上下文无关文法的类用于代码生成的(LLVM)绑定此外...

    使用C++来编写Ruby程序扩展的教程

    Ruby 提供了 C 头文件 ruby.h,它随附提供了许多功能,可使用这些功能创建 Ruby 类、模块和更多内容。除了头文件,Ruby 还提供了其他几个高层抽象来扩展基于本地 ruby.h 构建的 Ruby,本文要介绍的是 Ruby Interface...

    gloss:光泽是基于Ruby和水晶的高级语言,可编译为Ruby

    约路线图: 改善错误处理和日志记录(当前几乎不存在) 解决Linux兼容性(当前或多或少不存在) 实施不同的类型检查严格性元编程助手/安全性:* 抽象类和方法编译时的方法查找/存在检查方法重载相关项目: Rails助手...

    ruby-changelog:RubyCHANGELOG

    :NEW_button: RBS-一种描述Ruby类结构的语言 :NEW_button: TypeProf-类型分析工具,生成RBS类型签名 :test_tube: :NEW_button: Hash#except :counterclockwise_arrows_button: 关键字参数与其他参数分开 :...

    疯狂JAVA讲义

    第1章 Java概述 1 1.1 Java语言的发展简史 2 1.2 Java的竞争对手及各自优势 4 ...11.8.1 Image抽象类和BufferedImage实现类 425 11.8.2 使用ImageIO输入/输出位图 427 11.9 剪贴板 432 11.9.1 数据传递的类...

    ast.explorer:探索Java 8,EcmaScript 3,Ruby 2.0和嵌入式Ruby抽象语法树的工具

    #AST Explorer这个工具可以直观地浏览抽象语法树。 我将其写为我在慕尼黑路德维希马克西米利安大学的关于跨语言链接的自动检测的学士学位论文的一部分( )。 需要ast分析器项目进行编译。 可能还需要在类路径上使用...

    easyhttp:用于 ruby​​ http 类的微型 http 客户端包装器

    Easyhttp 为用户提供了一个简单易用的类方法,用于从 Web 服务器发送和接收数据。 目前它支持 get、post、put、delete http 方法并支持 ssl 和非 ssl 连接。 安装 将此行添加到应用程序的 Gemfile 中: gem '...

    discordrb:Ruby的Discord API

    如果您喜欢使用图书馆,请考虑与社区互动,以帮助我们改善和实现这些目标! 在以下情况下,您应该考虑使用discordrb : 您需要一个针对中小型社区的机器人(而且速度很快),并且不想被“低级”细节所困扰。 入门...

    sparkey:Spotify 的 Sparkey 的 Ruby 绑定

    如果您要添加 Ruby 类和方法来公开新的 Sparkey 功能,请使用此接口。 需要对 API 有深入的了解。 Sparkey::Native应该包装来自所有可用函数。 如果您发现缺少一个,请提交请求请求。中级这个 gem 公开

    ruby:我通过Ruby课程,进修和整体技能改进而取得的进步

    对象可以抽象,具有属性,类的实例 变量不是对象,但存储对对象的引用并具有值(例如first_name = "Kevin" ) 变量可以具有范围指示器,这些指示器具有不同的特征,请参见下表 范围 指标 全球的 $variable 班级 @@...

    ruby-ast-explorer:用于 ruby​​ 的 AST Explorer

    AST Explorer 可让您将 ruby​​ 代码可视化为 AST(抽象语法树)。 这使用gem 将源代码转换为 AST,并使用 gem 的类在 AST 节点上应用转换并将它们转换回源代码。 我们可以把转换逻辑并投入像Ruby文件transform....

    java采购系统软件源码-antlr3:使用ANTLR版本3生成功能齐全的ruby​​解析器

    java采购系统软件源码 用于 Ruby 的 ANTLR 3 作者:凯尔·耶特 ...虽然它确实提供了基本词法分析器和解析器类的实现,但目标没有为抽象语法树构造、树解析器类生成、输入转换或许多其他使程序优于传统代码的 ANTLR

    polyphony:Ruby的细粒度并发

    用于控制并发代码执行的抽象和构造:主管,取消作用域,限制,资源池等。 代码可以使用本机网络类和库,从而增加了对pg和redis等第三方gem的支持。 使用stdlib类,例如TCPServer , TCPSocket和OpenSSL::SSL::SSL...

    faye-websocket-ruby:符合标准的WebSocket客户端和服务器

    它提供了用于在Ruby中轻松构建WebSocket服务器和客户端的类。 它不提供服务器本身,而是使在现有应用程序中处理WebSocket连接变得容易。 除了标准的之外,它不提供任何抽象。 它还提供了用于处理连接的抽象, 连接...

    Viewpoint:用于Microsoft Exchange Web服务(EWS)的Ruby客户端访问库

    它还包括一堆模型类,这些模型类在EWS之上添加了额外的抽象层,可用于通过Viewpoint实现程序。 博客: : 在LinkedIn中添加我: : 在#ruby-lang(zenChild)的irc.freenode.net上找到我特征1.0的新功能SOAP后端...

    stupid-machines:抽象机实验

    愚蠢的机器 该存储库包含许多我们最喜欢的抽象机的无用实现,其中包括图灵机,Rule 110细胞自动机和循环... 诸如Ruby和Python之类的语言不使用分号,那么我的Java为什么要使用分号呢? TuringMachineWithNoSyntax.jav

Global site tag (gtag.js) - Google Analytics