欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ruby实现抽象类和抽象方法

程序员文章站 2022-03-11 09:37:52
...
ruby语言本身并没有提供abstract class和abstract method机制。这是ruby的spirit所决定的。但如果我们真的需要定义一个公共抽象类(或者抽象方法)来让子类来实现,又该如何做呢?
    我们可以通过在调用方法时抛出NotImplementedError来防止方法被调用。如(来自《ruby cookbook》的例子):

ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby  class Shape2D
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby   def area
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby     raise NotImplementedError
.new("#{self.class.name}#area是抽象方法")
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby   end
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby end 
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby class Square 
< Shape2D
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby   def initialize(
length)
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby     
@length = length
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby   end
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby   
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby   def area
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby     
@length ** 2
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby   end
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby end


   父类
Shape2D的方法area就是我们所需要的“抽象方法”了。你不能直接调用:

ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby s1=Shape2D.new
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby s1
.area

这样调用将抛出错误:Shape2D#area是抽象方法 (NotImplementedError)
Shape2D的子类Square覆写了此方法。由此我们模拟实现了抽象方法。那么抽象类该如何实现呢?自然而然,我们想到如果把类的initialize方法这样处理,那么这样的类将没办法被new生成,不正是我们所需要的抽象类?说干就干:

ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby  class Shape2D
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby   def initialize
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby     raise NotImplementedError
.new("#{self.class.name}#area是抽象类")
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby   end
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby   def area
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby     raise NotImplementedError
.new("#{self.class.name}#area是抽象方法")
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby   end
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby end 


当你调用Shape2D.new时,解释器将提示你:Shape2D是抽象类(NotImplementedError)

我们已经实现了抽象方法和抽象类,感觉还是不够好,对每一个需要实现抽象类的类来说,我们都需要去写一句:raise NotImplementedError.new...实在不够爽。ruby鼓励我们去修改类的行为,甚至是标准库,那好,我们修改Class类吧,提供类似attr_reader的声明式服务:
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby class Class
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby   def  
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby     abstract(
*args)
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby     args
.each do |method_name|
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby       
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby       define_method(method_name) 
do |*args|
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby         
if method_name == :initialize   
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby           msg 
= "#{self.class.name}是抽象类"
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby         
else
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby           msg 
= "#{self.class.name}##{method_name}是抽象方法"
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby         end
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby         raise NotImplementedError
.new(msg)
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby         
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby       end
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby     end
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby   end
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby end


OK,如此一来,我们的Shape2D可以写成:
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby  class Shape2D
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby     abstract
:initialize,:area  #initialize和area是抽象方法
ruby实现抽象类和抽象方法
            
    
    博客分类: ruby & rails Ruby 
 end


尽管在ruby中,抽象类和抽象方法是否有用存在怀疑,不过知道这样的办法总是不错的主意
相关标签: Ruby