ruby中的类/静态方法有什么用途?

ruby中的类/静态方法有什么用途?,ruby,class,oop,methods,Ruby,Class,Oop,Methods,一般来说,在学习ruby和oop时,我遇到了类方法,据我所知,类方法类似于实例方法,但可以从类而不是从对象访问,并且只能同时运行一个 然而,我不明白为什么你会使用一个类方法而不是一个普通的方法(在一个类之外),甚至它们的用途是什么 例如: #Why would you use: class Foo def self.bar puts "Class method" end end #Versus simply: def bar puts "Normal method" end

一般来说,在学习ruby和oop时,我遇到了类方法,据我所知,类方法类似于实例方法,但可以从类而不是从对象访问,并且只能同时运行一个

然而,我不明白为什么你会使用一个类方法而不是一个普通的方法(在一个类之外),甚至它们的用途是什么

例如:

#Why would you use:
class Foo
  def self.bar
    puts "Class method"
  end
end

#Versus simply:
def bar
  puts "Normal method"
end

Foo.bar # => Class method
bar # => Normal method
class Foo
  def self.bar
    puts 'class method'
  end

  def baz
    puts 'instance method'
  end
end

Foo.bar # => "class method"
Foo.baz # => NoMethodError: undefined method ‘baz’ for Foo:Class

Foo.new.baz # => instance method
Foo.new.bar # => NoMethodError: undefined method ‘bar
因为它们都产生相同的结果?
我对它们很困惑,所以如果我误解了这里的任何内容,请纠正。

正如你所说,它们是:

  • “从类而不是从对象访问,并且”
  • “一次只能运行一个。”

还请记住,该类是可移植的

最重要的是它使代码保持条理化。当你有数十万行代码时,让它们随意地在同一个名称空间中乱扔东西可能会成为一场噩梦。组织非常重要,名称空间是在语言支持下获得模块化的一种简单方法


稍微不那么重要的是,类/模块方法可以共享状态而不会到处泄漏(例如,类可以有实例变量),它们可以有私有支持方法以允许更好的分解,而全局方法不能有效地私有化。

您有很多误解

在ruby中,我们可以定义类和实例方法

类方法用于提供类级别的处理,即仅在类级别可用或与所有对象相关的数据。例如,要计算属于类的对象数,需要使用类方法。像

Foo.count  
同样,要处理单个对象,您需要object方法来处理单个对象,如

obj.save

所以,类方法是单音设计模式的一个例子,对象可以有相同方法的自己的实现。

你的例子不是一个好例子

类方法可能处理管理一个类中存在的所有实例,而实例方法一次处理一个实例

class Book
  def self.all_by_author(author)
    # made up database call
    database.find_all(:books, where: { author: author }).map do |book_data|
      new book_data # Same as: Book.new(book_data)
    end
  end

  def title
    @title
  end
end


books = Book.all_by_author('Jules Vern')
books[0].title #=> 'Journey to the Center of the Earth'
在本例中,我们有一个名为
Book
的类。它有一个class方法
all\u by\u author
。它查询一些虚拟数据库并返回
Book
实例数组。实例方法
title
获取单个
Book
实例的标题

因此,类方法管理实例集合,而实例方法只管理该实例



一般来说,如果一个方法将在一组实例上运行,或者是与该类相关的代码,但不直接读取或更新单个实例,那么它可能应该是一个类方法。

这更像是一个OOP问题,而不是ruby问题。ruby中的类方法与其他OO编程语言中使用的方法相同。这意味着:

  • 类方法在类的上下文中运行(并且只能访问类变量)
  • 实例方法在对象的上下文中运行(并且可以访问对象或实例变量)
下面是一个更好的例子:

#Why would you use:
class Foo
  def self.bar
    puts "Class method"
  end
end

#Versus simply:
def bar
  puts "Normal method"
end

Foo.bar # => Class method
bar # => Normal method
class Foo
  def self.bar
    puts 'class method'
  end

  def baz
    puts 'instance method'
  end
end

Foo.bar # => "class method"
Foo.baz # => NoMethodError: undefined method ‘baz’ for Foo:Class

Foo.new.baz # => instance method
Foo.new.bar # => NoMethodError: undefined method ‘bar
在这里,您可以看到类方法是通过类访问的,而实例方法是通过类的实例或对象访问的(
Foo.new

示例是从中复制的,您还可以从中找到有关此主题的更多信息


请记住:尽管任何代码都可以放入类或实例方法中,但每种代码都有自己的用例和优缺点。在OOP中,我们致力于实现可重用、灵活和可读的代码,这意味着我们通常希望将大多数代码以实例方法的形式放在合理的域模型中。

您应该阅读一些基本的OOP书籍。这将有助于更多地理解这些基本概念。@maximus您能推荐一些(或者更好地推荐免费在线的!)要学习基本的OOP概念,我建议您阅读o'reilly系列书籍,并使用ruby学习相同的内容。ruby之书是最好的,所以它更像是一个组织的东西,而不是一个普通方法和一个类之间的不同功能method@user2521439是的,只是organizational@user2521439没有“普通方法”-您只是在klass中调用当前范围内的方法。通过在ruby中的“普通”作用域中调用
self.class
,您可以在对象中动态添加/修改方法来证明这一点。正如在obj.define_singleton_method(:new_method)do“do some things”end中一样,可以通过下面这样的简单赋值来修改对象中的现有方法