ruby面向對象

Class

  • .new:實例化的關鍵字
  • initialize:當前類實例化的時候會首先被調用,可以不定義
  • class和module可以重新打開
  • 方法可以重定義,前一個會被覆蓋
  • 舉例:
  1. 手動設置讀寫:
class USer
  def initialize name,age
    @name = name
    @age = age
  end

// getter(實例變量不能直接訪問,因此需要getter)
  def name
    @name
  end

  def age
     @age
  end

// setter
  def name= name
    @name = name
  end

  def @age= age
    @age = age
  end

end
  1. ruby內部自帶的讀寫方法:attr_accessor最強大,一行就可以實現讀寫操作
class User
  attr_accessor :name
  attr_accessor :age
  // attr_reader :name, :age
  // attr_reader :age

  // attr_writer :name, :age
  // attr_writer :age

  def initialize name, age
    @name = name
     @age = age
  end

  def say_hi
    // @name 是實例變量,age 相當于返回實例變量@age的方法
    puts "hello,I am #{@name},age is #{age}"
  end
end
  • 類方法和類變量:類方法作用域訪問不到實例變量
class User
    attr_accessor :name
    attr_accessor :age

    @@counter = 0

    def initialize name,age
      @name = name
      @age = age

      @@counter += 1
    end

  // def User.get_counter
  def self.get_counter  
    @@counter
  end
end
  • 訪問控制:
  1. public:實例可以訪問
  2. protected:實例不可以訪問,繼承的子類可以訪問
  3. private:限制繼承的子類也不可訪問
    image.png
  • attr_accessor方法來源:Class
class User
...
end

User.class => Class
  • define_method:動態定義一個方法
define_method :hello do
   p "hello"
end
  • 自己實現attr_accessor
class User

  def self.setup_accessor var
    define_method var do
      instance_variable_get "@#{var}"
    end

    define_method "#{var}=" do |value|
      instance_variable_set "@#{var}", value
    end

  end

  setup_accessor :name  
  setup_accessor :age  

    def initialize name,age
      @name = name
      @age = age
    end

end
  • 繼承:<;查看繼承鏈:Array.ancestors
class User
  def initialize name,age
      @name = name
      @age = age
  end

  def panels
    @panels ||= ['Profile','Product']
  end 
end

class Admin < User
  def panels
    @panels ||= ['Profile','Product','Manage Users','System Setup']
  end
end
  • 查看一個類所屬的父類:Admin.superclass // User,ruby里一個類只能繼承一個類,不能繼承多個類
  • super會調用父類的同名方法
class User
  def initialize name,age
      @name = name
      @age = age
  end

  def panels
    @panels ||= ['Profile','Product']
  end 
end

class Admin < User
  def panels
    super
    @panels.concat ['x','y','z']
  end
end
  • self要看作用域,在實例方法里代指的是當前實例,在類本身里就代指當前類這個Class實例
  • 定義多個類方法:
class User
    def initialize name,age
      @name = name
      @age = age
    end

// fn1,fn2 都是類方法
  class << self
    def fn1
    end

    def fn2
    end
  end
end
  • 方法查找:自內而外,當前類沒有的話,就去父類查找

Modules

  • 作用:
  1. namespace:::來訪問,例如include A::b
  2. mixin:實現類似于多類繼承的功能
  3. storage
  • module關鍵字:
  1. module:聲明一個module
  2. include:把一個module的方法注入當前類的繼承鏈后面,成為實例方法
  3. prepend:把一個module方法注入當前類的繼承鏈前面,成為實例方法
  4. extend:把一個module的方法注入為類方法
  5. included:當模塊被include時會被執行,同時會傳遞當前作用域的self對象
  • demo:
module Management
  def company_notify
    'company_notify'
  end
end

class User 
  def initialize name,age
      @name = name
      @age = age
  end

  def panels
    @panels ||= ['Profile','Product']
  end 
end

class Admin < User
  include Management

  def panels
    super
    @panels.concat ['x','y','z']
  end
end

class Staff < User
  include Management

  def panels
    super
    @panels.concat ['a','b','c']
  end
end
  • Module本質上也是一個class,可以看作去除實例化功能(new)的class
  • module會在引用這個module的類的ancestors查找鏈方法中查找出
  • demo
module M1
  def m
    "M1"
  end
end

module M2
  def m
    "M2"
  end
end

class User
  include M1
  include M2
  
  def m
    p super
    "User"
  end
end

p User.ancestors  // [User,M2,M1,Object,Kernel,BasicObject]
user = User.new
user.m // "M2"  "User"
  • 模塊之間也可以includesuper
  • 模塊也支持類似類方法的定義
module Management
  def self.progress
    'progress'
   end

  def company_notify
    'company_notify'
  end
end

p Management.progress // 'progress'
  • class_eval:只有類才能調用,打開一個類的作用域,進行重定義
class User
end

User.class_eval do
   attr_accesstor :name
  def hello
    'hello'
  end
end

User.new.hello
module Management
// self 綁定成了當前模塊了
  def self.hi
    "hi"
  end
end

class User
  include Management
end

User.hi => error
Management.hi => "hi"
module Management

  def self.included base
    base.extend ClassMethods

    base.class_eval do
      setup_attribute
    end
  end

  module ClassMethods
    def setup_attribute
      p 'setup_attribute'
    end
  end

end

class User
  include Management
end

// 'setup_attribute'
  • instance_eval:是所有實例的方法,打開類的實例作用域
class User
end

User.class_eval do
  def hello
    'hello'
  end
end

User.instance_eval do
  def hi
    'hi'
  end
end

p User.hi
p User.new.hello
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容