# 【【面向对象】】
#【实例变量】
=begin
实例变量是类属性,它们在使用类创建对象时就编程对象的属性。每个对象的属性是单独赋值的,和其他对象之间不共享。
在类的内部,使用@运算符访问这些属性,在类的外部,使用访问器方法的公共方法进行访问。
=end #例子
class Box
#构造函数
def initialize(w,h)
@width,@height = w,h
end #访问器方法
def printWidth
@width
end def printHeight
@height
end
end # 创建对象,初始化盒子的高度与宽度
box = Box.new(10,20) #使用访问器方法
x = box.printWidth
y = box.printHeight puts "盒子宽度:#{x}"
puts "盒子高度:#{y}"
=begin
盒子宽度:10
盒子高度:20
=end # 例子 设置器
class Box
def initialize(w,h)
@width ,@height = w,h
end def getWidth
@width
end def getHeight
@height
end #设置器
def setWidth=(value)
@width = value
end def setHeight=(value)
@height = value
end
end #创建对象
box = Box.new(10,20) #使用设置器方法
box.setWidth = 30
box.setHeight = 50 #使用访问器方法
x = box.getWidth
y = box.getHeight
puts "盒子宽度:#{x}"
puts "盒子高度:#{y}"
=begin
盒子宽度:30
盒子高度:50
=end # 【实例方法】
class Box
def initialize(w,h)
@width,@height = w,h
end #实例方法
def getArea
@width * @height
end
end box = Box.new(10,20) a = box.getArea()
puts "Area of box is : #{a}" #Area of box is : 200 #【类方法& 类变量】
# =begin
# 类变量是在类的所有实例中共享的变量。换句话说,类变量的实例可以被所有的对象实例访问。类变量以两个 @ 字符(@@)作为前缀,类变量必须在类定义中被初始化,如下面实例所示。
# 类方法使用 def self.methodname() 定义,类方法以 end 分隔符结尾。类方法可使用带有类名称的 classname.methodname 形式调用
# =end
class Box
@@count = 0 def initialize(w,h)
@width,@height = w,h @@count += 1
end def self.printCount()
puts "Box count is #@@count"
end
end #创建两个对象
box1 = Box.new(10,20)
box2 = Box.new(30,100) #调用类方法输出盒子计数
Box.printCount() #Box count is 2 # 【to_s方法】返回对象的字符串表示形式。
class Box
def initialize(w,h)
@width,@height = w,h
end def to_s
"(w:#@width,h:#@height)"
end
end box = Box.new(10,20) puts "String representation of box is : #{box}" #String representation of box is : (w:10,h:20) # 【访问控制】
=begin
不在实例和类变量上应用任何访问控制。
三种,public private protected
public: 可被任意对象调用。默认情况下,方法都是public的,处理initialize总是private的。
private:不能被类外部访问或查看。只有类方法可以访问私有成员。
protected:只能被类及子类的对象调用。访问也只能在类及其子类内部进行。
=end class Box
def initialize(w,h)
@width,@height = w,h
end #实例方法默认是public的
def getArea
getWidth * getHeight
end #定义私有的访问器方法
def getWidth
@width
end def getHeight
@height
end #make them private
private :getHeight,:getWidth # 输出面积的实例方法
def printArea
@area = getWidth * getHeight
puts "box area is :#@area"
end #让实例方法是受保护的
protected :printArea
end box = Box.new(10,20) #调用实例方法
a = box.getArea
#puts "area of box is : #{a}" #尝试调用protected的实例方法
#box.printArea()
=begin
Area of the box is : 200
test.rb:42: protected method `printArea' called for #
<Box:0xb7f11280 @height=20, @width=10> (NoMethodError)
=end
# 【备注】因为此时既不在类的内部也不在子类的内部访问的。 # 【类的继承】
=begin
Ruby 不支持多继承,但是 Ruby 支持 mixins。mixin 就像是多继承的一个特定实现,在多继承中,只有接口部分是可继承的。
当创建类时,程序员可以直接指定新类继承自某个已有类的成员,这样就不用从头编写新的数据成员和成员函数。这个已有类被称为基类或父类,新类被称为派生类或子类。
=end class Box
#构造期方法
def initialize(w,h)
@width,@height = w,h
end #实例方法
def getArea
@width * @height
end
end # 定义子类
class BigBox < Box
#添加一个新的实例方法
def printArea
@area = @width * @height
puts "Big box area is :#@area"
end
end box = BigBox.new(10,20) box.printArea() #Big box area is :200 # 【方法重载】 #定义父类
class Box
def initialize(w,h)
@width,@height = w,h
end #实例方法
def getArea
@width * @height
end
end #定义子类
class BigBox < Box
# 改变已有的getArea方法
def getArea
@area = @height * @width
puts "Big box area is : #@area"
end
end box = BigBox.new(10,30) box.getArea() #Big box area is : 300 # 【运算符重载】 class Box
def initialize(w,h)
@width,@height = w,h
end def +(other) #定义+ 来执行 向量加法
Box.new(@width + other.width,@height + other.height)
end def -@ #定义一元运算符 - 来对width height 取反
Box.new(-@width,-@height)
end def *(scalar) #执行标量乘法
Box.new(@width*scalar,@height*scalar)
end
end # 【冻结对象】
=begin
有时候,我们想要防止对象被改变。在 Object 中,freeze 方法可实现这点,它能有效地把一个对象变成一个常量。任何对象都可以通过调用 Object.freeze 进行冻结。冻结对象不能被修改,也就是说,您不能改变它的实例变量。
您可以使用 Object.frozen? 方法检查一个给定的对象是否已经被冻结。如果对象已被冻结,该方法将返回 true,否则返回一个 false 值
=end =begin
class Box
def initialize(w,h)
@width,@height = w,h
end def getWidth
@width
end def getHeight
@height
end def setWidth=(value)
@width = value
end def setHeight=(value)
@height = value
end
end box = Box.new(10,20) box.freeze if(box.frozen?)
puts "box obj is frozen obj"
else
puts "box obj is normal obj"
end #尝试使用设置器方法
box.setWidth = 30
box.setHeight = 50 #使用访问器方法
x = box.getWidth
y = box.getHeight puts "width of box is :#{x}"
puts "height of box is :#{y}"
=end =begin
Box object is frozen object
test.rb:20:in `setWidth=': can't modify frozen object (TypeError)
from test.rb:39
=end #【类常量】 class Box
BOX_COMPANY = "TATA Inc"
BOXWEIGHT = 10 def initialize(w,h)
@width,@height = w,h
end def getArea
@width * @height
end
end box = Box.new(10,20) a = box.getArea()
puts "area of box is :#{a}"
puts Box::BOX_COMPANY
puts "Box weight is : #{Box::BOXWEIGHT}"
=begin
area of box is :200
TATA Inc
Box weight is : 10
=end #【使用 allocate 创建对象】
=begin
可能有一种情况,您想要在不调用对象构造器 initialize 的情况下创建对象,即,使用 new 方法创建对象,在这种情况下,您可以调用 allocate 来创建一个未初始化的对象,如下面实例所示:
实例
#!/usr/bin/ruby -w # 定义类
class Box
attr_accessor :width, :height # 构造器方法
def initialize(w,h)
@width, @height = w, h
end # 实例方法
def getArea
@width * @height
end
end # 使用 new 创建对象
box1 = Box.new(10, 20) # 使用 allocate 创建两一个对象
box2 = Box.allocate # 使用 box1 调用实例方法
a = box1.getArea()
puts "Area of the box is : #{a}" # 使用 box2 调用实例方法
a = box2.getArea()
puts "Area of the box is : #{a}" 尝试一下 »
当上面的代码执行时,它会产生以下结果:
Area of the box is : 200
test.rb:14: warning: instance variable @width not initialized
test.rb:14: warning: instance variable @height not initialized
test.rb:14:in `getArea': undefined method `*'
for nil:NilClass (NoMethodError) from test.rb:29
=end #【类信息】
#
=begin Ruby的 self 和 Java 的 this 有相似之处,但又大不相同。Java的方法都是在实例方法中引用,所以this一般都是指向当前对象的。而Ruby的代码逐行执行,所以在不同的上下文(context)self就有了不同的含义。让我们来看看下面的实例:.
实例
#!/usr/bin/ruby -w class Box
# 输出类信息
puts "Class of self = #{self.class}"
puts "Name of self = #{self.name}"
end 尝试一下 »
当上面的代码执行时,它会产生以下结果:
Class of self = Class
Name of self = Box
这意味着类定义可通过把该类作为当前对象来执行,同时也意味着元类和父类中的该方法在方法定义执行期间是可用的。
=end
# coding=utf-8

# 【【面向对象】】
#方法、类、模块
=begin
1 方法返回值不需要声明,默认最后一行为返回值。但若有条件判断返回的情况,需要用return声明
2 方法中可使用别名“alias”方法生成的拷贝,即使元方法变化,别名拷贝也不会变化
3 当方法定义在类的外部,默认是private。当方法啊定义在类的内部,默认是public
=end
def show_alias
puts "before alias"
end alias alias_foo show_alias def show_alias
puts "after alias"
end puts show_alias #after alias
puts alias_foo #before alias #例子 类
class Person
def initialize(age,sex)
@age = age
@sex = sex
end def age
@age
end def sex
@sex
end end tom = Person.new(20,"boy")
puts tom.age #20
puts tom.sex #boy
# 【【方法、类、模块】】  【类】
class Person
def initialize(age,sex)
@age = age
@sex = sex
end def age
@age
end def sex
@sex
end def say
puts "hello world"
end #重定义方法
def say
puts "How are you?"
end end tom = Person.new(20,'boy')
#特定对象的方法
def tom.bye
puts "Goodbye"
end puts tom.age #只有一个对应的方法会按照这个方法来,如果有多个重定义的,则按照最新的来。所以此时输出"How are you?"
puts tom.sex
puts tom.say #hello world
puts tom.bye #Goodbye #重新打开类
class PersonOne
def say
puts "Hi!"
end
end class PersonOne
def bye
puts "Bye!"
end
end wxue = PersonOne.new
wxue.say #Hi!
wxue.bye #Bye! # 更好的属性读写,=号的威力
#可用很多种方法对属性进行读写,但最方便的,对属性直接赋值
class PersonTwo
def age=(age)
@age = age
end def age
@age
end
end tom = PersonTwo.new
tom.age=(20)
puts tom.age #20 class PersonThree
def age=(age)
@age = age
end def age
@age
end end wxue = PersonThree.new
wxue.age = 20
print "wxue.age=",wxue.age,"\n" # 自动生成属性的读写操作attr_*
=begin
方法名 效果 例子 等价的代码
attr_reader 读方法 attr_reader :age def age
@age
end
attr_writer 写方法 attr_writer :price def age = (age)
@age = age
end
attr_accessor 读写方法 attr_accessor :age def age = (age)
@age = age
end
def age
@age
end
attr 读方法和
可选的写方法
(如果第二个参数是true)1.attr :age 1. 参见attr_reader
2.attr :age,true 2. 参见attr_accessor
=end #例子
class Car
attr_accessor :wheel
end class Bus < Car
attr_accessor :chaircount
end bus22 = Bus.new
bus22.wheel = 4
bus22.chaircount = 25 puts bus22.wheel #4
puts bus22.chaircount #25 #【【方法、类、模块】】【模块】
#module没有实例,使用时把module混合到类中来使用 module FirstModule
def say
puts "Hello"
end
end class ModuleTest
include FirstModule
end test = ModuleTest.new
puts test.say #"Hello" # 模块和类可以相互嵌套
module Human
class Boy
def say
puts "cool"
end
end
end test = Human::Boy.new
test.say #cool


【Ruby】【高级编程】面向对象的更多相关文章

  1. C++面向对象高级编程(九)Reference与重载operator new和operator delete

    摘要: 技术在于交流.沟通,转载请注明出处并保持作品的完整性. 一 Reference 引用:之前提及过,他的主要作用就是取别名,与指针很相似,实现也是基于指针. 1.引用必须有初值,且不能引用nul ...

  2. C++面向对象高级编程(八)模板

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 这节课主要讲模板的使用,之前我们谈到过函数模板与类模板 (C++面向对象高级编程(四)基础篇)这里不再说明 1.成员模板 成员模板:参数为tem ...

  3. C++面向对象高级编程(七)point-like classes和function-like classes

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 1.pointer-like class 类设计成指针那样,可以当做指针来用,指针有两个常用操作符(*和->),所以我们必须重载这两个操作 ...

  4. C++面向对象高级编程(六)转换函数与non-explicit one argument ctor

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 1.conversion function 转换函数 //1.转换函数 //conversion function //只要你认为合理 你可以任 ...

  5. C++面向对象高级编程(五)类与类之间的关系

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 本节主要介绍一下类与类之间的关系,也就是面向对象编程先介绍两个术语 Object Oriented Programming   OOP面向对象编 ...

  6. C++面向对象高级编程(四)基础篇

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 一.Static 二.模板类和模板函数 三.namespace 一.Static 静态成员是“类级别”的,也就是它和类的地位等同,而普通成员是“ ...

  7. C++面向对象高级编程(三)基础篇

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 概要 一.拷贝构造 二.拷贝赋值 三.重写操作符 四.生命周期 本节主要介绍 Big Three 即析构函数,拷贝构造函数,赋值拷贝函数,前面主 ...

  8. C++面向对象高级编程(二)基础篇

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 概要 知识点1.重载成员函数 知识点2 . return by value, return by reference 知识点3 重载非成员函数 ...

  9. C++面向对象高级编程(一)基础篇

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 概要: 知识点1 构造函数与析构函数 知识点2 参数与返回值 知识点3 const 知识点4 函数重载(要与重写区分开) 知识点5 友元 先以C ...

  10. Python 面向对象之高级编程

    7.面向对象高级编程 7.1使用__slots__ python动态语言,new 对象后绑定属性和方法 Tip:给一个实例绑定的方法,对其他对象无效.可以通过对class绑定后,所有对象可以调用该方法 ...

随机推荐

  1. ORM some

    1 -- 增 models.表名(类).objects.create(字段1=值,字段2=值) 查 models.表名(类).objects.get(pk = 3) models.表名(类).obje ...

  2. 算法提高 c++_ch02_01 (强制类型转换)

    编写一个程序,利用强制类型转换打印元音字母大小写10种形式的ASCII码. 输出的顺序为:大写的字母A,E,I,O,U的ASCII码,小写的字母a,e,i,o,u的ASCII码.所有的ASCII码都用 ...

  3. Symfony2 学习笔记之服务容器

    现在的PHP应用程序都是面向对象开发,所以主要是由对象构成.有的对象可以方便的分发邮件信息而有的可能帮你把信息写入到数据库中.在你的应用程序中,你可能创建一个对象用于管理你的产品库存,或者另外一个对象 ...

  4. Linux 安装 mysql 数据库

    1. 克隆虚拟机 2. 上传安装文件 1.上传文件 2.解压文件 tar -xvf 文件 3. 安装数据库 安装顺序: .debuginfo .shared .client .server 1. rp ...

  5. Python进阶【第十篇】模块(上)

    ·一.模块 模块就是一组功能的集合体,我们的程序可以导入模块来复用模块里的功能.为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这 ...

  6. maven项目启动报错;class path resource [com/ssm/mapping/] cannot be resolved to URL because it does not exist

    项目启动报了一堆错误,其实都是class path resource [com/ssm/mapping/] cannot be resolved to URL because it does not ...

  7. Linux环境jdk的安装

    1.下载jdk1.7,oracle的下载地址已经失效,找了个其他的地址进行下载. wget http://pc.xzstatic.com/2017/03/jdk7u79linuxx64.tar.gz ...

  8. Docker学习笔记之docker volume 容器卷的那些事(二)

    预览目录 更改目录拥有者 Data Container 切换用户 参考文章 0x00 概述 如果你读了docker volume 容器卷的那些事(一),我想应该不会遇到下面这些问题的,毕竟是具有指导意 ...

  9. Yii笔记:打印sql、Form表单、时间插件、Mysql的 FIND_IN_SET函数使用、是否是post/ajax请求

    语句部分: yii1版本打印最后一条执行的SQL: $this->getDbConnection()->createCommand()->select()->from()-&g ...

  10. Solr导入MySQL数据之dataimport-handler

    Solr不借助手动JSolr编程情况下也可以将Mysql的数据导入到Solr中.实现方式是安装dataimport-Handler从关系数据库将数据导入到索引库. 1.向SolrCore中加入jar包 ...