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.

《Ruby语言入门教程v1.0》学习笔记-02的更多相关文章

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

    <Ruby语言入门教程v1.0> 编著:张开川 邮箱:kaichuan_zhang@126.com 想要学习ruby是因为公司的自动化测试使用到了ruby语言,但是公司关于ruby只给了一 ...

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

    10.09 第七章 7.1 模块 Ruby标准包里的 Math 模块提供了许多方法,比如:求平方根 sqrt ,使用的时候要这么写:模块名.方法名(参数).如:Math.sqrt( a*5+b ) M ...

  3. mapreduce v1.0学习笔记

    它是什么? 一个用于处理大数据开源的分布式计算框架,它由java实现,原生提供java编程交互接口,其它语言通过hadoop streaming方式和mapreduce框架交互. 可以做什么? 利用框 ...

  4. HDFS v1.0学习笔记

    hdfs是一个用于存储大文件的分布式文件系统,是apache下的一个开源项目,使用java实现.它的设计目标是可以运行在廉价的设备上,运行在大多数的系统平台上,高可用,高容错,易于扩展. 适合场景 存 ...

  5. 《JavaScript语言入门教程》记录整理:运算符、语法和标准库

    目录 运算符 算数运算符 比较运算符 布尔运算符 二进制位运算符 void和逗号运算符 运算顺序 语法 数据类型的转换 错误处理机制 编程风格 console对象和控制台 标准库 Object对象 属 ...

  6. 《JavaScript语言入门教程》记录整理:面向对象

    目录 面向对象编程 实例对象与 new 命令 this关键字 对象的继承 Object对象的方法 严格模式(strict mode) 本系列基于阮一峰老师的<JavaScrip语言入门教程> ...

  7. RxJava2.0学习笔记2 2018年7月3日 周二

    摘记: 1.map -- 转换  有些服务端的接口设计,会在返回的数据外层包裹一些额外信息,这些信息对于调试很有用,但本地显示是用不到的.使用 map() 可以把外层的格式剥掉,只留下本地会用到的核心 ...

  8. 《Angular4从入门到实战》学习笔记

    <Angular4从入门到实战>学习笔记 腾讯课堂:米斯特吴 视频讲座 二〇一九年二月十三日星期三14时14分 What Is Angular?(简介) 前端最流行的主流JavaScrip ...

  9. Go语言入门教程(十)之函数

    Hello 各位小伙伴大家好,我是小栈君,假期一眨眼就过去了.不知道大家玩的是否开心呢? 上次我们讲到了关于Go语言的流程控制,小栈君也希望小伙伴跟着小栈君一步一个脚印的敲一下代码,相互进步.本期我们 ...

随机推荐

  1. 动画Rig设置为Legacy

    The animation state AimUp could not be played because it couldn't be found!Please attach an animatio ...

  2. GDB调试技巧

    1. 查看内存分布 (gdb) info proc mappings 2. 对于类的调试,先通过行号来设断点, 比如:(gdb) b TcpConnection.cc:63 3. 打印数组的内容 (g ...

  3. Android更新UI的几种方式

    之前做过一个Android采集心电图数据的程序,那才是真正的多线程,之前写的小程序:比如下载个文件,从socket接受大一点的数据流然后在ui上更新进度,我都感觉这就叫做多线程了,其实这啥都不算,用个 ...

  4. Java基础知识强化之集合框架笔记08:Collection集合自定义对象并遍历案例(使用迭代器)

    1. Collection集合自定义对象并遍历案例(使用迭代器) (1)首先定义一个Student.java,如下: package com.himi.collectionIterator; publ ...

  5. ACM vim配置

    ACM现场赛时用的,比较简短,但是主要的功能都有了. 直接打开终端输入gedit ~/.vimrc 把下面的东西复制到里面就行了. filetype plugin indent on colo eve ...

  6. Java数字、货币值和百分数等的格式化处理

    如果我们用下列语句输出一个数 System.out.println(123456.789); 将会在Console看到输出 123456.789 那么如何得到123,456.789这种格式化的输出呢? ...

  7. IIS支持APK/ISO文件下载的方法

    默认把安卓手机应用或游戏的apk格式文件上传到服务器空间是不能直接下载的,这是因为IIS的默认MIME类型中没有.apk文件,所以无法下载.@VCOO 既然.apk无法下载是因为没有MIME,那么添加 ...

  8. sqlserver 将多行数据查询合并为一条数据

    有这样一个需求:表T_FUN_TASK为任务表,有字段(TASKID,TASKNAME),表T_FUN_LOGBOOK为日志表,有字段(LOGID,TASKID,LOGDATE),一个任务可持续多天, ...

  9. C# == 和equals()区别

    如以下代码: ? 1 2 3 4 5 int age = 25; short newAge = 25; Console.WriteLine(age == newAge);  //true Consol ...

  10. 在浏览器运行 java applet时遇到的一些问题及其解决方法

    运行 java applet时提示:您的安全设置已阻止本地应用程序运行,如何解决?如下图所示 这时候通过设置java的安全级别就可以了. 控制面板->程序->Java->安全 将安全 ...