Terry七月Ruby读书笔记(比较详细)第2/4页
Page 40
面向对象
2008/7/13
1. 消息机制:对象通过消息影响对象,对象即类的实例。谁,将被影响?
2. Object:东西,物体,客体。
3. Class:种类,等级,阶级;
4 动态语言:人们可以决定代码世界中一类事物的属性、方法,当然可以修改代码世界中一类事物的属性、方法,而且可以委托其它的类来修改,甚至删除。这是动态语言超越静态语言之处。由于代码是一直运行着,与其它代码一直交互着,修改、删除应该慎重,避免产生副作用。
5 封装
注意:
类名首字母要大写;
实例变量用@开头;
方法名或者参数名用小写字母或者下划线开头。
6 initialize是初始化方法
p2.motherland="ABC" #以赋值,因为有对应的setter方法。
setter: |
getter: |
attr_writer:motherland相当于 |
attr_reader:motherland相当于 |
def motherland=(value) return @motherland=value end |
def motherland return @motherland end |
attr_accessor :motherland
相当于 attr_reader:motherland; attr_writer :motherland
7.继承
class 子类<父类
子类继承父类:
重写方法;
添加方法;
增强父类方法(super)。
Ruby语言已经定义了一个类Object,如果你在定义新类的时候,没有指明新类的父类,那么,Ruby解释器认为,新类的父类是 Object 类。类Object 含有new方法、initialize 方法…只要你不重写这些方法,你就自然在使用类Object 的方法。
你写一个类的时候,是在创造一类事物的蓝图;当你new的时候,一个实例就按照蓝图生成了。
Ruby没有析构函数,使用垃圾收集器自动回收实例占用的资源。
8.多态
父类子类的行为差异,不同子类的行为差异,就是多态
Ruby语言,只有重写(override),没有其它语言具有的严格意义上的重载(overload)。Ruby语言有自己的单例方法,还有模块插入(Mix-in)。
插曲
http://liubin.itpub.net/post/325/15623
覆盖 override:
Overriding 也许叫做overwriting更合适,
OVERLOAD覆盖是指在子类(c++中的派生类) 中重新定义父类的函数,其函数名、参数列、返回值类型必须同父类中的相对应被覆盖的函数严格一致,覆盖函数和被覆盖函数只有函数体(花括号中的部分)不同,当派生类对象调用子类中该同名函数时会自动调用子类中的覆盖版本,而不是父类中的被覆盖函数版本。
重载(overload):
在同一个类中,出现多个同名的方法的现象就是Overload重载事发生在同一个类中,不同方法之间的现象。
在c++或者java中,方法一般为
返回类型 方法名(参数1,参数2)
判断2个方法是不是overload,主要指方法名一样,参数不一样,参数不一样指的是参数的个数,相同位置的参数的类型是否一样,而与参数(型参)的名称无关(参数类型/个数/顺序,不同),与返回类型也无关。程序会根据不同的参数列来确定需要调用的函数比如c++或者java中,这都是overload ruby中,不存在这样的overload
多态(polymorphism)
至于多态,我还没有见过一个看一眼就能明白的定义。
有的说是允许将子类类型的指针赋值给父类类型的指针,当然java中没有指针的概念。
多态有时候也被称为动态绑定或者晚绑定或运行时绑定,意思是编译的时候不必关心,运行的时候才决定调用哪个对象的哪个方法。
我觉得多态的用途之一就是在父类提供一个接口(服务),然后调用的时候用的却是子类的具体实现。
page 49
Ruby前前后后
1.动态语言
编程语言将向动态回归;
命令式语言和函数式语言将融合。
Ruby在语法层次实现了冗余。
Ruby语言的冗余性、缺陷性和动态性正是现实世界的真实写照。
page51
2.动态变量类型
命令式语言 |
将操作数演化成现在我们熟悉的变量,将操作码演化成方法(或叫函数),对变量执行各种操作。 |
面向对象编程又将基本变量和方法封装在一起,成为一个更复杂的变量——对象。但是,在一个类中仍然区分基本变量和方法。 | |
函数式语言 |
一开始的函数式语言不区分变量和方法,一切都是表(list),表就是能够不断分解成单个元素的数学符号。表可以是变量,可以是方法。 |
后来的有些函数式语言,吸取了命令式语言的语法,也区分变量和方法。 |
Ruby: 命令式语言,融合了函数式语言的语法,变量和方法区分得不很明显。
变量名,变量值,变量类型,变量的作用域;“变量名,变量值”,必要的。
动态类型语言:由编译内核(或解释内核)在运行时刻来判断变量类型的语言。
弱类型语言:弱化了类型的概念,变量在运行中能够随时代表不同的事物,而不管事物是什么类型。
Ruby语言有基本类型。
纯粹的函数式语言中没有变量作用域的概念。
Ruby中有变量作用域概念,如变量名前缀字符。
实际应用中,有时会比较复杂,在使用闭包时会显现出来。
Ruby语言中,一切都是对象,变量不是对象,变量只是引用某个对象的时候的一个代号。
Ruby是动态类型语言,不用给任何变量指定数据类型,解释器会在你第一次赋值给变量时,在内部将数据类型记录下来。
Ruby语言中,一个变量被赋予了某个数据类型的值,在程序中你可以随时再赋予这个变量其它数据类型的值。
Ruby 是在运行中检测语法,只要与语法定义不矛盾,就能通过。
Ruby 的动态类型特点是一把双刃剑,
死盯住变量的命名。用一些有意义的名字,不必太长,但是应该少用单字符,除非是循环指针变量。在一个项目组中,程序员是要彼此相互沟通合作的。
3.改变蓝图——类
Ruby是动态语言,你可以改变Ruby程序的结构,功能。
在Ruby程序运行中,方法、属性可以被加入或去除,新的类或对象可以被建立,新的模块可以出现。
除了修改方法,添加方法,还可以除去方法。
Ruby是动态语言:灵活,强大,初学者容易犯错误;
4.编码建议
(1) 命名
常量 |
大写,下划线分隔 |
MAX |
类名/模块名 |
大写字母开头 |
MyClass |
方法名 |
小写,下划线分隔 |
is_prime? |
变量/参数名 |
小写字母开头单词组合 |
currentValue |
注意:
类名、模块名、变量名、参数名最好使用“名词”或者“形容词+名词”。
方法名最好使用“动词”或者“动词+名词”。例如:aStudent.talk。
在Ruby里,有时将“!”和“?”附于某些方法名后面。惊叹号“!”暗示这个方法具有破坏性,有可能会改变传入的参数。问号“?”表示这个方法是一个布尔方法,只会返回true或false。
(2) 空格
关键字之后要留空格。
逗号“,”、分号“;”之后要留空格。
“,”、“;”向前紧跟,紧跟处不留空格。
赋值操作符、比较操作符、算术操作符、逻辑操作符,如“=”、“+=”“>=”、“<=”、“+”、“*”、“%”、“&&”、“||”等二元操作符的前后应当加空格。
一元操作符如“!”、“~”等之后不加空格。
象“[]”、“.”、“::”这类操作符前后不加空格。
函数名之后不要留空格,紧跟左圆括号“(”,以与关键字区别。左圆括号“(”向后紧跟,右圆括号“)”向前紧跟,紧跟处不留空格。
(3) 圆括号
Ruby中圆括号常常被省略
优先规则会自动确定哪个参数被哪个方法使用。
建议除了极简单的情况,还是使用圆括号为好。
圆括号还可以把几个语句约束成一个语句集合。
(4) return
在定义方法的时候,在最后一行可以显式地return某个值或几个值,但不是必须的。
Ruby方法的最后一行语句如果是表达式,表达式的值会被自动返回;最后一行语句如果不是表达式,就什么也不返回。
return不仅仅用在方法的最后一行。使用break能够跳出本层循环,如果要从多重循环体中跳出,可以使用return,结束这个方法;return还能够从方法的某个执行点立即退出,而不理会方法的其余代码。
(5) 注释
注释表明了一段代码块的功能、意图或是代码块的解释,应该简洁明了,错误的注释不如没有注释。一般地,注释的位置应与被描述的代码相邻,可以放在代码的上方或右方,不要放在代码的下方。
page 61
面向对象
1. 重载&重写
多态性:重写/覆盖/覆写(override) 重载(overload)
重载(overload) |
重写(override) |
一个类中,方法名相同、参数列表不同的几个方法,调用时根据不同的参数调用不同的方法。方法重载与返回类型无关。 |
子类有一个方法,方法名、参数列表、返回类型与父类的某个方法完全一致。调用时会调用子类的方法,而屏蔽掉父类的同名方法。需要注意的是,子类覆写的方法,其可访问性一定要强于或等同于,父类被覆写的同名方法。 |
重载不仅仅是发生在子类和父类之间,大多数时候,发生在同一个类中。 |
覆写发生在子类和父类之间,当然也可以是子类和父类的父类之间。 |
成员函数被重载的特征:
URL:http://blog.csdn.net/zgbsoap/archive/2005/12/30/566120.aspx |
Ruby语言,只有重写,没有其它语言具有的严格意义上的重载。
分析:重载,参数不同,参数列表对应位置参数类型不同。而ruby支持缺省参数、可变参数,因此,参数不同不会发生重载。所以,ruby没有严格意义上的重载。
父类和子类中的同名方法,子类重写父类。子类对象执行子类中的方法。
在同一个类中写两个同名方法,总是执行写在后面的方法。
ruby支持缺省参数,和C++相同。
在 Ruby中,我们说覆写是指重写,我们说重载也是指重写。
Ruby是动态语言,可以随时改变类的属性、方法,所以覆写和重载的重要性就降低了。
2. 增强父类方法
如果我们只是想增强父类的方法,而不是完全地替代它,就可以用关键字super指明。
在子类定义和父类同名的函数时,加入super关键字。
3. 变量
(1) 稳定性
constant :Unchanging in nature, value, or extent; invariable.稳定的,不变的。
常变量(常量)。常量名用大写字母开头。
变量:作用域,可以改变值。
Ruby中的常量,可以在类和模块中定义,不能在方法中定义。
如果在外部访问类或模块中的常量,要使用域作用符::。
(2) 作用域
全局变量——作用域程序任何位置,全局变量用$开头。
局部变量——作用域程序某个单元,用小写字母开头。
全局变量和实例变量如果没有初始化,其默认值为 nil 。
Ruby中的局部变量,可以是存在于类、方法、模块、循环、过程对象中。
(3) 共享性
实例变量——只能被某个实例对象使用的变量,变量名用@开头;
类变量——能被某个类的所有实例对象共享的变量,变量名用@@开头。
类变量在使用前必须要初始化。
(4) 类方法
类方法——不依赖于任何特定实例对象的方法。
类方法与实例方法的定义方式不同,定义类方法要在方法名前加上类名和点号“.”。
调用一个类方法,与定义类方法一样,要在方法名前加上类名和点号“.”。
类方法提供了一个途径,在类的外部访问类变量,无需通过类的实例方法。
对象是类的实例,说明类是对于对象的一个抽象,那么,如果把类继续抽象,把类看做实例,那它会是谁的实例? ——元类! 元数据,描述数据的数据。 |
疑问:类方法可否操作实例变量,而不仅仅是类变量?
4. 单例方法
Ruby如何反映相同的类,不同实例,之间的不同的行为特征?
(1)单例方法:在Ruby里,可以给具体的实例对象添加实例方法,这个方法只属于这个实例对象,我们把这样的方法称之为单例方法,单例方法也叫作单件方法。
(2)定义单例方法:
首先要生成一个实例对象,
其次,要在方法名前加上对象名和一个点号“.”。
(3)实例方法,属于类的每个实例对象。单例方法只出现在单个实例对象中。用单例方法可以极大地丰富多态性在Ruby中的表现力。
Ruby对于类和对象的扩展,就像数学中的多维,原来只是类和对象两个层次,这里,看成任意的层次,只不过,类和对象是其中的两个不同的层次。所以,有了类的类——类的进一步抽象,有了单例方法,在对象这个层面上设计方法。
5. 访问控制
在Ruby里,要读取或是改变对象的属性,唯一的途径是调用对象的方法。
控制了对方法的访问,也就控制了对对象属性的访问。
控制对方法的访问,有三种方式:
访问控制 |
意义 |
public |
可以被任何实例对象调用,不存在访问控制; |
protected |
可以被定义它的类和其子类访问, 可以在类中或子类中指定给实例对象; |
private |
可以被定义它的类和其子类访问, 不能被实例对象调用。 |
方法默认都是公有的(initialize方法除外,它永远是私有的)。
public方法 |
可以被定义它的类和其子类访问, 可以被类和子类的实例对象调用; |
protected方法 |
可以被定义它的类和其子类访问, 不能被类和子类的实例对象直接调用, 但是可以在类和子类中指定给实例对象; |
private方法 |
可以被定义它的类和其子类访问, 私有方法不能指定对象。 | 它的类和其子类访问,
Ruby语言的访问控制是动态的,是在程序运行时刻确立的。
你可以根据自己的需要,在程序的不同位置,改变某个方法的访问控制级别,让你的程序更加富于变化。
page 79
模块化程序设计
1. 模块
在程序中,相关的、不相关的代码的组合,叫作模块。一般情况下,我们总是把功能相关的代码放在一个模块里。
把功能相关的程序代码放在一个模块里,体现了模块的第一个作用:可以被其它程序代码重复使用。
Ruby标准包里的 Math 模块提供了许多方法
模块名.方法名(参数) |
Math 模块还提供了两个常量,圆周率π 和自然对数底 e,
模块名::常量名 |
定义模块用 module...end 。模块与类非常相似,但是:
A) 模块不可以有实例对象;
B) 模块不可以有子类。
2. 命名空间
模块的第二个作用:提供了一个命名空间(namespace),防止命名冲突。
include 模块名
定义一个模块方法,在方法名前加上模块名和一个点号“.”。
调用一个模块方法,与定义模块方法一样,要在方法名前加上模块名和一个点号“.”。模块方法提供了一个途径,在模块的外部访问模块内部方法,无须 include模块。定义模块常量不需要如此。
3. 糅和(Mix-in)与多重继承
柔和/混合插入/Mix-in
Ruby是单继承,通过Mix-in模块,实现多重继承的优点。
模块的第三个作用:实现了类似多重继承的功能。
通过“<父类名”,一个子类可以得到父类的属性和方法;
通过“include模块名”,一个子类可以得到某个模块的常量和方法。
类不能被include。
include方法为一个类的所有对象包含某个模块;
extend方法为一个类的某个对象包含某个模块(联系单例方法)。
4. require和load
require方法包含另一个文件,另一个文件名需要是一个字符串。
load方法与require方法相对应,也用来包含另一个文件。
require包含文件,只加载一次,遇到同一文件时自动忽略;不同路径下的同名文件会多次加载。
load包含文件,加载多次,即使是相同路径下同一文件。
总结一下:
require,load |
包含文件 |
include,extend |
包含模块 |
require |
加载文件一次 |
加载文件时可以不加后缀名 |
一般情况下用于加载库文件 |
load |
加载文件多次 |
加载文件时必须加后缀名 |
用于加载配置文件 |
利用load多次加载文件的特性,可以用来实现程序的无缝升级和系统的热部署。程序功能改变了,你只需要重新load一次,其它代码与它再次交互的时候,这个程序实际上已经不是原来的程序了。
page 88
相关文章
mac os gem安装json出现error failed的解决办法
这篇文章主要介绍了mac os gem安装json出现error failed的解决办法,系统是mac os Mavericks,失败提示Failed to build gem native extension,需要的朋友可以参考下2014-06-06Ruby on rails安装后去掉DL is deprecated,please use Fiddle警告信息的方法【
这篇文章主要介绍了Ruby on rails安装后去掉DL is deprecated,please use Fiddle警告信息的方法,通过针对Ruby on rails安装文件中的警告部分源码进行注释来达到消除警告的目的,需要的朋友可以参考下2017-02-02
最新评论