《Ruby语言入门教程v1.0》学习笔记-02

9.18

第四章 一切都是对象

这个章节的例子都举得很浅显易懂,而且作者的语言= =噗,委实生动有趣啊是~~

4.1  两种思维方式

初期的编程思想是:以“如何做”为指导来编写代码。这时期的编程语言叫过程语言,提倡结构化地设计程序代码。代表语言是FORTRAN和C。
现在的编程思想是:以“谁将被影响”为指导来编写代码。叫面向对象的编程语言,以类为模块,以消息来驱动程序的执行。代表语言是C++ 和Java。

4.2  对象

(这里是文摘。。。。摘摘摘摘摘。。。。。)

每个事物都有一些特点,人有身高,体重,在程序中我们称之为属性;还可以有一些行为,人要吃饭,睡觉,在程序中我们称之为方法
学生是人,自然有身高,体重,自然要吃饭,睡觉。如果你把人看作一类事物,把学生看作一类事物;那么,人是父类型,学生是子类型。子类型从父类型自然得到属性、方法,我们称之为继承
学生要考试,工人不要;工人拿工资,学生不拿(一般而言)。同一个父类,不同的子类有不同的行为和状态,我们称之为多态
人们编写程序,也就是在描述一类事物的特点(属性)、行为(方法)。有时候是模拟描述自然界中已有的一类事物,还有时候是创造地描述自然界中没有的一类事物。
当人们决定了代码世界中一类事物的属性、方法,在代码世界中,这类事物的属性、方法只有定义代码的人知道,其它的类是不知道的。这就是封装
封装、继承、多态是面向对象编程的三个本质特征。

4.3  封装

让我们来定义一个类,类名是Person,类名首字母要大写

属性有姓名@name、年龄@age、国籍@motherland,实例变量用@开头

方法有一个,叫talk, 方法名和参数名应该用一个小写字母开头或者用一个下划线开头

举个例子吧~

class Person
  def initialize( name, age=18 )     #initialize是初始化方法,相当于Java的构造器。参数age有一个缺省值18,可以在任何方法内使用缺省参数,而不仅仅是initialize。
    @name = name
    @age = age
    @motherland = "China"
  end #初始化方法结束
  def talk
    puts "my name is "+@name+", age is "+@age.to_s      #@age.to_s的含义是:将数@age转换为字符串。
    if @motherland == "China"
      puts "I am a Chinese."
    else
      puts "I am a foreigner."
    end
  end # talk方法结束
attr_writer :motherland            #相当于def motherland=(value); return @motherland =value; end

end # Person类结束

p1=Person.new("kaichuan",20);p1.talk

p2=Person.new("Ben");p2.motherland="ABC";p2.talk

#my name is kaichuan, age is 20
I am a Chinese.
my name is Ben, age is 18
I am a foreigner.

4.4   继承

class Student < Person             #用“ < ”表示Student类是 Person类的子类。
  def talk                                #Student类继承Person类的一切,而这里Student类重写了talk方法。
    puts "I am a student. my name is "+@name+", age is "+@age.to_s  #子类继承父类的时候,除了重写方法;也可以添加一些新的方法;或是增强父类的方法(用关键字super指明)。
  end # talk方法结束
end # Student类结束
p3=Student.new("kaichuan",25); p3.talk
p4=Student.new("Ben"); p4.talk
#I am a student. my name is kaichuan, age is 25
I am a student. my name is Ben, age is 18

注意:如果子类不重新定义方法的话,会默认该子类使用父类的方法。另,所有新增的类都是属于Ruby语言中已经定义了的Object类,如果你在定义新类的时候,没有指明新类的父类,那么,Ruby解释器认为,新类的父类是Object类。类Object含有new方法、initialize方法…只要你不重写这些方法,你就自然在使用类Object的方法。

说个好玩儿的,在这一节的后面有这样一段话,实在是有趣啊~哈哈哈哈哈~~~

一个实例生成了,又一个实例生成了…他们或许是同类型的,或许不是同类型的,或许是有亲缘关系的。无数的实例在代码世界中交互、缠结,忽生忽死,无休无止…

4.5  多态

多态在这里就不多说了,其实就是不同子类的多样性,基本来说,我的理解就是,他们定义的方法不同,或者是数目不同,或者是同一名称的方法的内容不同。

这里要注意的是,“Ruby语言,只有重写(override),没有其它语言具有的严格意义上的重载(overload)”。

 

9.26

第五章

5.3 详解变量—— 动态类型

在ruby当中,变量和方法区分的并不明显。变量要有的特性:#只抽出了需要的两点

1). 变量有名字;
2).变量代表的那个事物应该有一个可以用数学度量的值;长度,面积,速度大小,磁场强度…

 在 Java 中,编译的时候,就完成了类型匹配的检测,这属于前期绑定; Ruby 是在运行中检测,检测类型匹配吗?不是检测类型匹配,而是检测语法,只要与语法定义不矛盾,就能通过。这样成就了方便,也造就了麻烦,如果变量的命名不清晰明了,就容易出现错误。“如何避免常常出错呢?有一个下口之处,就是死盯住变量的命名。用一些有意义的名字,不必太长,但是应该少用单字符,除非是循环指针变量。你也许认为我自己能看懂就行了,这是十分有害的想法。在一个项目组中,程序员是要彼此相互沟通合作的。当坏习惯养成后,要改是很难的。

Ruby中“方法”的增删改#举例删除,修改也是同样,重新在类里定义方法就好

class Person
  def talk
    puts "Today is Saturday. "
  end
end

p1=Person.new
p1.talk   # Today is Saturday.

class Person

   undef :talk

end   #p1.talk talk方法已经不存在

5.5 一些编码建议

# 题外话,果然有txt就是好啊,清除格式什么的最好用了,从别的地方复制过来的文档总有些奇奇怪怪的格式,更坑爹的是还有可能影响到其它文本,所以粘贴过来前先放txt里面净化一遍真是太好了啊~~

一. 命名
常量全用大写的字母,用下划线分割单词。例如:MAX, ARRAY_LENGTH。
类名和模块名大写字母开头的单词组合而成。例如:MyClass, Person。
方法名全用小写的字母,用下划线分割单词。例如:talk, is_prime?。在Ruby里,有时将“!”和“?”附于某些方法名后面。

    惊叹号“!”暗示这个方法具有破坏性, 有可能会改变传入的参数。问号“?”表示这个方法是一个布尔方法,只会返回 true 或 false。

变量和参数小写字母开头的单词组合而成。例如:name, currentValue。
类名、模块名、变量名、参数名最好使用“名词”或者“形容词+名词”。

方法名最好使用“动词”或者“动词+名词”。例如:aStudent.talk 。

二. 空格和圆括号
关键字之后要留空格。
逗号“,”、 分号“;”之后要留空格。 “,”、 “;”向前紧跟,紧跟处不留空格。
赋值操作符、比较操作符、算术操作符、逻辑操作符,如“=”、“+=” “>=”、“<=”、“+”、“*”、“%”、“&&”、“||”等二元操作符的前后应当加空格。
一元操作符如“!”、“~”等之后不加空格。
“[]”、“.”、“::”这类操作符前后不加空格。
函数名之后不要留空格,紧跟左圆括号“(”,以与关键字区别。左圆括号“(”向后紧跟,右圆括号“)”向前紧跟,紧跟处不留空格。

#只要不会造成逻辑错误神马的,圆括号()基本可以省略。

三. 使用 return
你在定义方法的时候,在最后一行可以显式地 return 某个值或几个值,但却不是必须的。 Ruby 方法的最后一行语句如果是表达式,表达式的值会被自动返回;最后一行语句如果不是表达式,就什么也不返回。

 

第六章 深入面象对象

6.1 重载?重写

重载      4.5节说到:“ Ruby语言,只有重写,没有其它语言具有的严格意义上的重载。” 下面仔细分析 Ruby 为何没有重载,只有重写。

Ruby支持缺省参数,我们看程序 E6.1-1.rb :
def sum( a, b=5 )
    a+b
end
puts sum(3,6)    #9   
puts sum(3)       #8   二者在Java中是调用不同方法,但在Ruby中是调用同一个。

Ruby还支持可变参数,我们看程序 E6.1-2.rb :
def sum( *num )
    numSum = 0
    num.each { |i| numSum+=i }
    return numSum
end
puts sum()                             #0
puts sum(3,6)                        #9
puts sum(1,2,3,4,5,6,7,8,9)   #45

#由于缺省参数和可变参数,参数个数不同而产生的重载,在Ruby中不再有效。

重写

在子类和父类中,如果子类里不写该方法,那么就是直接集成父类;如果是子类重新写了该方法,那就是执行子类当中的方法。

写在同一个类中的不同方法,总是写在后面的方法被实现。

 

 

 

 

 

 

 

 

 

 

 

 

 

6.2 增强父类方法

之前一直搞不懂增强父类的方法是什么(喂喂,提前暴露自己学校没好好学了吧= =||),咳咳,原来意思是说,以子类身份执行方法时,除了执行父类方法,还会执行子类中该方法添加的部分。

class Person
  def talk(name)
    print "my name is #{name}."
  end
end
class Student < Person
  def talk(name)
    super
    print "and I'm a student.\n"   
  end
end
aPerson=Person.new             #只执行父类中输出姓名
aPerson.talk("kaichuan")        #my name is kaichuan.
aStudent=Student.new         #除了执行父类中的输出姓名,还执行子类中的super增强部分。
aStudent.talk("kaichuan")      #my name is kaichuan.and I'm a student.

# 之前有想过,其实在子类中重写方法也是一样的嘛,而且更清晰。但是再一想,如果量啊逻辑啊神马的比较麻烦,那还是这样好了,更简单一些~~

6.3 实例变量、类变量、类方法

如果一个变量,其作用域遍及在程序的任何位置,这样的变量称之为全局变量;与之相对,作用域仅限于在程序的某一单元的变量,称之为局部变量

如果一个变量,只能被某个实例对象使用,这样的变量称之为实例变量;如果一个变量,能被某个类的所有实例对象共享,这样的变量称之为类变量

常量可以定义在类和模块中,不能定义在方法中(方法中只能对变量进行赋值,或者设置变量的缺省值。)。如果在外部访问类或模块中的常量,要使用域作用符::

全局变量$ 开头。

实例变量,变量名用@ 开头;类变量,变量名用@@ 开头.

Ruby中所说的局部变量,可以是存在于类中、方法中、模块中、一个循环中、一个过程对象中。局部变量名用小写字母开头。

 

 

 

 

 

实例变量:譬如类Student,学生Jmy是一个实例,那么@name、@age、@motherland,都是实例变量,被每个实例独享。

类变量:譬如类Class0901,学生Jmy是一个实例,@@count(班级人数)是类变量,被class0901类里所有实例共享。

class StudentClass
    @@count=0
    def initialize( name )
        @name = name
        @@count+=1
    end
    def talk
        puts "I am #@name, This class have #@@count students."
    end
end
p1=StudentClass.new("Student 1 ")
p2=StudentClass.new("Student 2 ")
p3=StudentClass.new("Student 3 ")
p4=StudentClass.new("Student 4 ")
p3.talk # I am Student 3 , This class have 4 students.
p4.talk # I am Student 4 , This class have 4 students.

class StudentClass 

    @@count=0
    def initialize
        @@count+=1
    end
    def StudentClass.student_count
        puts "This class have #@@count students."
    end
end
p1=StudentClass.new
p2=StudentClass.new
StudentClass.student_count     # This class have 2 students.
p3=StudentClass.new
p4=StudentClass.new
StudentClass.student_count     # This class have 2 students.

#调用一个类方法,与定义类方法一样,要在方法名前加上类名和一个点号“.”。类方法提供了一个途径,在类的外部访问类变量,无须通过类的实例方法。

#调用类方法,不需要依赖于任何实例的方法

 

 

 

 

 

 

 

 

 

 

 

 

 

 

10.08

6.4 单例方法

class Person
    def talk
        puts "Hi! "
    end
end


p1=Person.new
p2=Person.new


def p2.talk           #定义单例方法p2.talk
    puts "Here is p2. "
end
def p2.laugh       #定义单例方法p2. laugh
    puts "ha,ha,ha... "
end


p1.talk                # Hi!
p2.talk                # Here is p2.
p2.laugh             # ha,ha,ha...

  在Ruby里,可以给具体的实例对象添加实例方法,这个方法只属于这个实例对象,我们把这样的方法称之为单例方法

 

  定义单例方法,首先要生成一个实例对象;

  其次,要在方法名前加上对象名和一个点号“.”。

 

  左图程序中,对象p1不可以laugh , laugh方法只属于p2对象。

 

 

 

 

 

 

 

 

 

 

6.5 访问控制

控制对方法的访问,有三种方式:

Public        可以被任何实例对象调用,不存在访问控制;

Protected  可以被定义它的类和其子类访问,可以在类中或子类中指定给实例对象;

Private      可以被定义它的类和其子类访问,不能被实例对象调用。

Public 方法默认都是公有的( initialize方法除外,它永远是私有的)。

class Person
    def talk
        puts " public :talk, 将调用speak"
        speak
    end
    def speak
        puts "protected :speak,将调用laugh"
        laugh
    end
    def laugh
        puts " private:laugh"
    end
    protected :speak #实例对象不能调用protected方法
    private :laugh      #实例对象不能调用private方法
end

p1=Person.new
p1.talk      #public :talk, 将调用speak

                   protected:speak,将调用laugh

                   private:laugh

p1.speak #protected method 'speak’ 

p1.laugh  #prrivate method 'laugh’

class Person
    def speak
        "protected:speak "
    end
    def laugh
        " private:laugh"
    end
    protected :speak
    private :laugh
end


class Student < Person
    def useLaugh
        puts laugh
    end
    def useSpeak
        puts speak
    end
end


p2=Student.new
p2. useLaugh       # private:laugh
p2. useSpeak       # protected:speak

class Person
    def speak
        "protected:speak "
    end
    def laugh
        " private:laugh"
    end
    protected :speak
    private :laugh
    def useLaugh(another)
        puts another.laugh   
    end
    def useSpeak(another)
        puts another.speak
    end
end

p1=Person.new
p2=Person.new

def p1.speak

    puts"I am p1."

end

p2.useSpeak(p1)     # I am p1.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2013-09-16 16:23  小泠哦  阅读(298)  评论(0编辑  收藏  举报