ruby学习之初探类、方法

前看了一些基本的操作,比如字符串、数组,但这些只是一些最最基础的,如果写的太久了就会无味,从而失去对这门语言的耐心(个人观点)。所以我也只是先过一遍,让自己有个初始的认识,然后继续往后学习,这样也可以保持自己的兴趣,也能不让自己学的那么累。这是我最近玩游戏的一点心得,如果你一直纠结于哪一关,想把这关过的完美,那会让自己更累,还不如过了这关后继续往后闯,等自己的实力更进一层楼的时候,再来过这关,就会轻松拿下,还能走的更远。

进入正题,这次学习的是任何一门面向对象语言的关键--类/方法

在ruby的世界里,真正做到了一切皆对象的思想,比如. 1234.to_s。这样的整数型也可以用点的方式来调出一个方法,这就是最好的证明,虽然java也是叫着一切皆对象,但做不到int型的基础数据类型可以调用一个方法。这也正是ruby吸引我的地方.

类是具有共同特征的物体的统称,在ruby里也是用class来表示,类中可以定义属性、方法来表示这个类的状态或行为。比如人类,可以定义属性:名称、年龄、身高、性别等,这是表示这个类所具有的一些特征或状态,还可以定义方法:走路、吃饭,这是表示这个类能够做什么事。如果把这些做具体了,比如有一个叫张三的人很高,可以吃饭,这就变成了这个类的具体化,在程序的世界里称之为实例。

ruby称之为动态的解析性语言,也就是在程序执行的时候可以动态改变某些状态或行为,这充分的体现了ruby的灵活性

class Counter
  def add(n, m)
    n + m
  end
  
  def sub(n, m)
   n - m
  end
end

#追加新的方法
class Counter
  def rid(n, m)
    n * m
  end
  def div(n, m)
    n / m
  end
end

#追加新的方法
c = Counter.new
def c.mod(n, m)
  n % m
end

puts "3+2=#{c.add(3, 2)}"
puts "3-2=#{c.sub(3, 2)}"
puts "3*2=#{c.rid(3, 2)}"
puts "3/2=#{c.div(3, 2)}"
puts "3%2=#{c.mod(3, 2)}"

3+2=5
3-2=1
3*2=6
3/2=1
3%2=1

这些代码也非常的简洁,而且很易懂,符合ruby设计之初的思维性语言

面向对象的类还有更多的特性,比如封装,继承,多态,这也是oo思想的关键实现。另外在ruby的对象里,能够使用self来表示本身,使用super来表示父类。

类既然是一个封装,那么在这个封装中肯定还可以有另外的封装,称之为内部类,使用Animal::Head来引用。head = Animal::Head.new这样可以获取这个Head的实例

另一个就是ruby的特殊类,也相当于上面的追加,只不过这里用的是继承实例的方式来实现的

class << c
  def put
    puts "这是一个特殊追加的类"
  end
end

使用c.put来调用里面的方法.

理解方法是比较简单的,但需要注意的是ruby中,方法和各变量之间的关系,任何语言的变量是有一些使用范围,这对方法中数据的访问有一定的限制

puts "两个模块之间共享数据需要用到实例变量或类变量"
@name = "wicky" #顶层实例变量
class Person
  @age = 23 #类实例变量
  def init
    @weight = "60KG"
  end
  def show
    puts "我的名字叫#{@name},今年#{@age},体重#{@weight}"
  end
end

p = Person.new
p.init
puts p.show
两个模块之间共享数据需要用到实例变量或类变量
我的名字叫,今年,体重60KG

可以看出,顶层的实例变量和类实例变量在类的方法中是无法访问到的,只能访问到已初始化的实例变量。

@@name = "Wicky" #类变量
class Cat
  def say
    puts "我是一只猫,我的主人是#{@@name}"
  end
end
class Dog
  def say
    puts "我是一只狗,我是主人是#{@@name}"
  end
end

c = Cat.new
d = Dat.new
c.say
d.say
我是一只猫,我的主人是Wicky
我是一只狗,我是主人是Wicky

类变量是全局性的。一般用来存放应用级的数据,因为它在各个类之间是可以访问的

另个一个重点是实例的描述了,实例是一个类的具体化,可以对一个类做一些特殊的表示

class Person
  def setName(name)
    @name = name
  end
  
  def setAge(age)
    @age = age
  end
  
  def SetIsMale(isMale)
    @isMale = isMale
  end
  
  def say
    gender = @isMale ? "小男孩" : "小女孩"
    puts "大家好,我是#{@name},今年#{@age}岁,我是一个#{gender}"
  end
  
end
p = Person.new
p.setName("Wicky")
p.setAge(22)
p.SetIsMale(false)
p.say
大家好,我是Wicky,今年22岁,我是一个小女孩

方法和属性要了解的东西还挺多,除了统筹的学习一番,还在实际应用中多总结。

ruby面向对象编程还有一个重点就是类的属性,没有属性的类好比没有特殊的人,如果全人类全部长一个样,那情景……我不敢想。

puts "属性的定义和个修饰符"
class Car
  def initialize(brand, weight)
    @brand = brand
    @weight = weight
  end

  def init
    @color = "黄色"
    @weight = "128KG"
    @brand = "BYD"
    @f_zero = "120KM/H"
  end
  attr :brand, false
  attr_reader :weight, :f_zero
  attr_accessor :color
  
  def showCar(obj)
    puts "==========="
    puts "这是一辆#{obj.brand}"
    puts "颜色是#{obj.color}"
    puts "总重达#{obj.weight}"
    puts "时速高达#{obj.f_zero}"
  end
end
c = Car.new("BMW", 110)
#如果不调用init,只会显示构造函数里面的值 
c.init
c.color = "红色"
#c.brand = "BMW"
c.showCar(c)
属性的定义和个修饰符
===========
这是一辆BYD
颜色是红色
总重达128KG
时速高达120KM/H

首先类里有一个方法initialize,这相当于java的构造方法,会根据参数列表被自动调用,所以在这里初始化的变量可以不用再显式调用,属性被不同的访问限制修饰,attr :attr1, key这里的key如果用false,则表示attr1只读,这个内建方法只能标识一个。而attr_reader/atter_writer/attr_accessor看到字面就知道是表示属性的只读,只写,可访问。

些外有一个听说很有用的代码块,但之前没用过,所以也得花点时间去熟悉

代码块有一个不太理解的规定,必须是同级的使用,这可能得以后理解后再回来看看了

uts "代码块的实现"
class Cat
  
  def self.say
    puts "I`m s method in Cat"
    yield
  end
end
class CatB

  def testb
    puts "called from class B"
  end
  def test
    Cat.say{testb}
  end  
end
  
c = CatB.new
c.test
<pre class="ruby" name="code">代码块的实现
I`m s method in Cat
called from class B
 

代码块用yield[参数列表]来调用,在一个调用的方法中,会被暂定转向代码块中的代码,执行完代码块中的代码后才会继续执行当前方法的代码。如上,当Cat中的say方法执行到yield后,会调用CatB中的test的Cat.say{}这个代码块,而且传入的参数是testb方法,所以又会执行testb。感觉挺绕,但也能理解,所以又写了一个实例

class Student
  attr_accessor :code, :name
  def initialize(code, name)
    @code = code
    @name = name
  end
end
  
def each(ss)
  for stud in ss
    yield(stud)
    puts "code:" + stud.code + "\tname:" + stud.name 
  end
end

students = Array.new
students[0] = Student.new("001", "张三")
students[1] = Student.new("002", "李四")
students[2] = Student.new("003", "王五")

each (students) {|stu| 
  stu.code = "stu" + stu.code
}
code:stu001	name:张三
code:stu002	name:李四
code:stu003	name:王五

代码块在一个迭代器执行的时候来修改里面的内容,实例化Student后,开始迭代这个数组,调用了类里面的重载方法,使用for对当前的数组遍历,但在遍历的时候执行yield代码块中的内容,改变一个内容,然后再执行后面的内容。
感觉越学越好玩了,但难理解的问题也越来越多了,看来除了平时的学习外,还得找一些另外的资料来看看了,把前面的内容再细化一遍了。也相当于过了后面的关,再返回之前一些比较难过的关去闯闯。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值