类是面向对象中一个重要的术语。我们可以把类看作是对象的抽象,
所有的这类对象都有这些特征。而对象则是类的具体实现,按照类的要求创建的
对象就是该类的对象。类就像对象的雏形一样,决定了对象的行为。
eg:用数组类创建数组对象
arr=Array.new #[]
用class方法查看对象属于那个类
arr=[1,2,3]p arr.class #Arrayp Array.class #Class
所有的类都是Class类的对象。
当判断某个对象是否属于某个类,我们可以使用instance_of?方法。
arr=[1,2,3]p arr.instance_of? Array #truep arr.instance_of? Object #false
继承
通过扩展已经创建的类来创建新的类成为继承。继承后创建的新类被称为子类。
被继承的类称为父类。
BasicObject类是ruby中所有类的父类。他定义了作为ruby对象最基本的功能。
Object是BasicObject的子类。定义一般类所需要的功能。
根据类的反向继承关系追查对象是否属于某个类,则可以使用is_a?方法。
arr=[1,2,3]p arr.is_a? Array #truep arr.is_a? Object #true
创建类
class 类名 类的定义end
类名的首字母必须大写.eg:
class Sayhello def initialize(myname="ruby") puts "调用我实例化对象" @name=myname end def hello puts "hello,I am #{@name}!" endend#实例化对象java=Sayhello.new("java")ruby=Sayhello.new
调用new方法创建对象时会默认调用initialize方法。
@name时实例变量。hello方法时实例方法。实例方法中可以直接引用实例变量。
引用未定义的实例变量会返回nil.
存取器
ruby中不能直接访问实例变量或对实例变量赋值。需要通过方法来操作。
class Sayhello def initialize(myname="ruby") puts "调用我实例化对象" @name=myname end def hello puts "hello,I am #{@name}!" end #获取实例变量的方法 def name puts "获取实例变量@name" @name end #修改实例变量的方法 def name=(value) puts "修改实例变量@name" @name=value endend#实例化对象java=Sayhello.new("java") #调用initialize方法p java.name #调用name方法java.name="python" #调用name=方法p java.name #调用name方法java.hello #调用hello方法
Ruby提供了更简便的实现方法
定义 | 意义 |
---|---|
attr_reader :name | 只读(定义name方法) |
attr_writer :name | 只写(定义name=方法) |
attr_accessor :name | 读写(定义上面的两个方法) |
eg:
class Sayhello #name和name= attr_accessor :name def initialize(myname="ruby") puts "调用我实例化对象" @name=myname end def hello puts "hello,I am #{@name}!" endend#实例化对象java=Sayhello.new("java") #调用initialize方法p java.name #"java"java.name="python"p java.name #"python"java.hello #hell0,I am python
特殊变量self
在类内部self指向类自身,在实例方法内部,self指向调用方法的实例。
class Sayhello #name和name= attr_accessor :name def initialize(myname="ruby") puts "调用我实例化对象" @name=myname end def hello puts "hello,I am #{self.name}!" endend#实例化对象java=Sayhello.new("java") #调用initialize方法java.hello #hell0,I am java
等价于
class Sayhello #name和name= attr_accessor :name def initialize(myname="ruby") puts "调用我实例化对象" @name=myname end def hello puts "hello,I am #{@name}!" endend#实例化对象java=Sayhello.new("java") #调用initialize方法java.hello #hell0,I am java
类方法
class Sayhello class << Sayhello def hello(name) puts "#{name} said hello." end end def initialize(myname="ruby") puts "调用我实例化对象" @name=myname end def hello puts "hello,I am #{@name}!" endend#实例化对象java=Sayhello.new("java") #调用initialize方法java.hello #hell0,I am java#调用类方法Sayhello.hello "ruby" #ruby said hello;
在类内部定义类方法
class Sayhello class << self def hello(name) puts "#{name} said hello" end end def initialize(myname="ruby") puts "调用我实例化对象" @name=myname end def hello puts "hello,I am #{@name}!" endend#调用类方法Sayhello.hello "ruby" #ruby said hello
或者
class Sayhello def Sayhello.hello(name) puts "#{name} said hello" end def initialize(myname="ruby") puts "调用我实例化对象" @name=myname end def hello puts "hello,I am #{@name}!" endend#调用类方法Sayhello.hello "ruby" #ruby said hello
或者
class Sayhello def self.hello(name) puts "#{name} said hello" end def initialize(myname="ruby") puts "调用我实例化对象" @name=myname end def hello puts "hello,I am #{@name}!" endend#调用类方法Sayhello.hello "ruby" #ruby said hello
使用class <<类名 ~ end 这种写法的类定义称为单例类定义。
单例类定义中定义的方法称为单例类方法。
常量
class语句中可以定义常量
class Sayhello Version="1.0" def initialize(myname="ruby") puts "调用我实例化对象" @name=myname end def hello puts "hello,I am #{@name}!" endend#实例化对象p Sayhello::Version #"1.0"
类变量
类变量为所有类的实例所共享,从类的外部访问类变量时需要存储器,不能使用
attr_accessor等,需要直接定义。
class Sayhello @@count=0 def Sayhello.count @@count end def initialize(myname="ruby") puts "调用我实例化对象" @name=myname end def hello @@count+=1 puts "hello,I am #{@name}!" endend#实例化对象p Sayhello.count #0ruby=Sayhello.newruby.hellojava=Sayhello.new "java"java.hellop Sayhello.count #2
限制方法的调用
Ruby提供了三种方法的访问级别:
关键字 | 访问级别 |
---|---|
public | 以实例方法的形式向外公开该方法 |
private | 只在类内部可以用 |
protected | 类内部及子类中可以使用 |
eg:
class AccTest def pub puts "hello" end #设置方法的访问权限 public :pub def priv puts "private" end #设置方法的访问权限 private :privendacc=AccTest.newacc.pubacc.priv #NoMethodError
希望统一定义多个方法的访问级别时。可以使用下面的语法。
eg:
class AccTest public #以下的方法都被定义为public def pub puts "hello" end private #以下方法都被定义为private def priv puts "private" endendacc=AccTest.newacc.pubacc.priv #NoMethodError
没有定义访问访问级别方法默认为public,但是initialize方法是个例外,
他通常被定义为private.
扩展类
eg:在原有的类的基础上添加方法
class String def count_word #用空格分割self ary=self.split(/\s+/) #返回分解后的数组的长度 return ary.size endendstr="I am ruby"p str.count_word #3
继承
class 类名 < 父类名 类定义end
eg:RingArray继承Array
class RingArray < Array #重定义运算符[] def[](i) ind=i%self.size super(ind) endendarr=RingArray["金","木","水","火","土"]p arr[6] #"木"p arr[12] #"水"
定义类的时候没有指定父类的情况下,ruby会默认该类为Object类的子类。
有时候我们希望继承更轻量级的类,就会使用BasicObject类
eg:查看类的实例方法
p Object.instance_methodsp BasicObject.instance_methods #[:!, :==, :!=, :__send__, :equal?, :instance_eval, :instance_exec, :__id__]
需要继承BasicObject类,需要显式的继承。
alias与undef
使用alias给方法设置别名.或者在重定义已经存在的方法时,为了使用别名调用
原来的方法,也需要用到alias.
alias 别名 原名alias :别名 :原名
class Sayhello def hello "hello" end alias sayhello helloendh=Sayhello.newp h.sayhello #"hello"
eg:
class Sayhello def hello "hello" end alias sayhello helloendclass Child < Sayhello alias old_hello hello def hello "#{old_hello},again." endendchild=Child.newp child.old_hello #"hello"p child.hello #"hello,again."
undef
undef用于删除已定义的方法。
undef 方法名undef :方法名
eg:子类中删除父类定义的方法
class Sayhello def hello "hello" end alias sayhello hello def del "delete" endendclass Child < Sayhello alias old_hello hello def hello "#{old_hello},again." end undef delendchild=Child.newp child.old_hello #"hello"p child.hello #"hello,again."p child.del #NoMethodError
单例类
利用单例类给对象添加方法
str1="Ruby"str2="Ruby"class << str1 def hello "hello,#{self}!" endendp str1.hello #"hello,Ruby!"p str2.hello #(NoMethodError)
Ruby中所有的类都是Class类的对象,因此,Class对象的实例方法以及
类对象的单例方法都是类方法。
联系客服