Ruby学习(二)------类与对象
在Ruby中,操作的都是对象,结果也都是对象。
类定义
Ruby中,类的定义要在class...end之间,类名必须以大写字母开始。
若某个类已经被定义过,此时又用相同的类名进行类定义的话,是对原有的类的定义进行追加.
?
class ClassName def method1 puts 'method1' endendclass ClassName def method2 puts 'method2' end?end
?
对象,属性和方法
1、类在实例化后生成对象。
2、方法是对对象进行的操作。操作对象(被调)以self来表示。对象的性质由其内部定义的方法所决定 。
?
class Person def initialize(name,gender,age) ###构造实例对象时被自动调用 @name = name ###以@开头的是实例变量,只能在类在方法内部使用它 @gender = gender @age = age endendpeople = Person.new('Jarvi','female','26') ###创建一个Person对象
?
?3、在Ruby中,一个对象的内部属性都是私有的。实例变量可以用只读控制符attr_reader来表示变量为可读,
类似地,也可以用成员变量写控制符attr_writer来表示可写。表示可读、可写用attr_accessor
?
class Person def initialize(name,gender,age) @name = name @gender = gender @age = age end attr_reader :name #可读 attr_writer :gender #可写 attr_accessor :age #可读、可写 ### attr_accessor :name, :gender,:age #多个表示end?
?
也可以用attr控制符来表示变量是否可读写,它可有二个参数,一个符号参数,第二个是一个bool参数,表示为符号参数,用于指示是否为符号参数产生写方法。默认是false,只产生读方法,不产生写方法。
?
class Person attr :name, true #可读写 attr :gender,false #只读end
?
?PS:attr_reader,attr_writer,attr_accessor 和 attr不是语言的关键字,而是Module模块方法。
?
class Test attr_accessor :valueendputs Test.instance_methods -Test.supperclass.public_methods结果为:valuevalue =
?
?Test.instance_methods 得到Test类所有的实例方法。
Test.supperclass.public_methods得到Test父类所有的实例方法。
相减就得到Test类不包括父类的所有的实例方法。
?
4、重定义方法
重定义一个方法时,新的定义会覆盖原有的方法。
5、重定义类
重定义一个类时,表示对原有定义的追加,不会覆盖原来的方法。
6、self
self和Java中的this有些类似,代表当前的对象。
?
?
继承
1、Ruby使用 < 来表示继承。
class Te < Person
def initialize(name,gender,age,company) @name = name @gender = gender @age = age @company = company endend
PS: Ruby只支持单继承,但提供mixin的机制来实现多继承。
?
2、super?
a、可以使用super 关键字调用对象父类的方法。当super省略参数时,将使用当前方法的参数来进行调用。
b、如果传入的参数被修改再调用super的话,那么将会使用修改后的值
?
class Base def meth(info) puts "This is Base #{info}" endendclass Derived < Base def meth(info) puts "This is derived #{info}" info = 'test2' super endendobj1 = Derived.newobj1.meth("test")结果:This is derived testThis is derived test2?
?
特殊方法和特殊类
?
特殊方法
特殊方法是指只从属于某个特定对象的方法。
1、定义一个特殊方法
?
class SingletonTest def info puts "This is This is SingletonTest method" endend
obj1 = SingletonTest.newobj2 = SingletonTest.newdef obj2.info puts "This is obj2"end
obj1.infoobj2.info执行结果为:This is This is SingletonTest methodThis is obj2
?
?2、定义多个特殊方法,使用<<
?
class SingletonTest def meth1 puts "This is meth1" end def meth2 puts "This is meth2" endendobj1 = SingletonTest.newobj2 = SingletonTest.newclass << obj2 def meth1 puts "This is obj2's meth1" end def meth2 puts "This is obj2's meth2" endendobj1.meth1obj1.meth2obj2.meth1obj2.meth2执行结果为:This is meth1This is meth2This is obj2's meth1This is obj2's meth2?
?
类变量与类方法
?
类变量
1、类变量被一个类的所有实例对象共享,类变量名以'@@'开始,使用前必须初始化。 类似与java里面的static修饰的变量。
?
class Person @@number = 0 #使用前必须有初值 def initialize(name, gender, age) @name = name @gender = gender @age = age @@number += 1 endend
?
?2、类变量是私有的,只能通过实例方法和类方法进行访问。相当于java里面的static修饰的方法
?
class Test @@number = 0 def initialize(name,age) @name = name @age = age @@number +=1 end def Test.getNumber() return @@number end def getNumber() return @@number endendtest1 = Test.new('jim',20)test2 = Test.new('tom',30)puts Test.getNumber()puts test1.getNumber()
?
?存取控制
Ruby中,只能通过方法改变一个类的属性,不能直接改变。
方法的存取控制有三种:
?
公有方法? ? ? ? ? ? ?方法在任何地方都可以被调用,这是方法的默认存取控制。 除了initialize和initialize_cpoy方法,他们永远是私有方法。保护方法? ? ? ? ? ?方法只能被定义这个方法的类自己的对象和这个类的子类的对象所访问。私有方法? ? ? ? ? ?方法只能被定义这个方法的类的对象自己访问,即使是这个类的其他对象也不能访问。#前式class Test def method1 #默认为公有方法 … end protected #保护方法 def method2 … end private #私有方法 def method3 … end public def test_protected(arg) #arg是Test类的对象 arg.method2 #正确,可以访问同类其他对象的保护方法 end def test_private(arg) #arg是Test类的对象 arg.method3 #错误,不能访问同类其他对象的私有方法 endendobj1 = Test.newobj2 = Test.newobj1.test_protected(obj2)obj1.test_private(obj2)
#后式class Test def method1 ... end def method2 ... end def method3 ... end def methdo4 ... endpublic :method1protected :method2private :method3, :method4end?元类在Ruby中,一切都是对象,类和实例对象都是对象。所有类对象的类是Class类,Oject类是所有类的基类。
class Test #定义类方法方式1 def Test.meth1 # ... end #定义类方法方式2 def self.meth2 # ... end #定义类方法方式3 class << Test def meth3 # ... end end #定义类方法方式4 class << self def meth4 # ... end endend?Ruby的动态性1、可以重新定义同一个方法2、可以使用undef_method取消一个方法的定义
class UndefTest def meth puts "This is meth" endendobj1 = UndefTest.newobj1.methclass UndefTest undef_method(:meth)endobj1.meth执行结果为:This is methtest.rb:14: undefined method `meth' for #<UndefTest:0x2ac8240> (NoMethodError)?变量
?