如何在ruby中实现抽象类?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (9)

我知道在ruby中没有抽象类的概念。但是,如果非得要的话,该如何去做呢?我试过这样:

class A
  def self.new
    raise 'Doh! You are trying to write Java in Ruby!'
  end
end

class B < A
  ...
  ...
end

但是,当我尝试实例化B时,它将在内部调用A.new这将引发bug。

提问于
用户回答回答于

我不喜欢在Ruby中使用抽象类(几乎总是有更好的方法)。但是,如果你真的认为这是解决这种情况的最佳方法,那么可以使用下面的代码片段来声明哪些方法是抽象的:

module Abstract
  def abstract_methods(*args)
    args.each do |name|
      class_eval(<<-END, __FILE__, __LINE__)
        def #{name}(*args)
          raise NotImplementedError.new("You must implement #{name}.")
        end
      END
      # important that this END is capitalized, since it marks the end of <<-END
    end
  end
end

require 'rubygems'
require 'rspec'

describe "abstract methods" do
  before(:each) do
    @klass = Class.new do
      extend Abstract

      abstract_methods :foo, :bar
    end
  end

  it "raises NoMethodError" do
    proc {
      @klass.new.foo
    }.should raise_error(NoMethodError)
  end

  it "can be overridden" do
    subclass = Class.new(@klass) do
      def foo
        :overridden
      end
    end

    subclass.new.foo.should == :overridden
  end
end

用户回答回答于

Ruby在运行时使用方法的存在/缺位或行为来确定是否应该调用它们。因此,你的问题,因为它适用于抽象方法,有意义:

def get_db_name
   raise 'this method should be overriden and return the db name'
end

这应该是故事的结尾。在Java中使用抽象类的唯一原因是坚持某些方法被“填充”。

在你的问题中,你基本上是在重新创建来自Java的abstract,这是在Ruby中执行Java的代码嗅觉。

扫码关注云+社区