# 【【面向对象】】
#【实例变量】
=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. 【JavaScript 6连载】一、关于对象(访问)

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  2. flask 请求上下文

    一篇引用大牛的 https://www.cnblogs.com/zhaopanpan/p/9457343.html ### 线程安全 ```python# 线程不安全class Foo(object) ...

  3. PDF文档导出

    代码如下: /// <summary> /// 获取html内容,转成PDF(注册) /// </summary> public void DownloadPDFByHTML( ...

  4. 隐藏域传值到后台controller

    开发背景:一个页面有一个下拉框和一个单选按钮,下拉框保存的是厂商信息,单选按钮保存的是产品信息.每次下拉框的内容被选中,把厂商编码保存到隐藏域 <input type="hidden& ...

  5. asyncio 学习

    来自:https://www.syncd.cn/article/asyncio_article_02 一.asyncio之—-入门初探 通过上一篇关于asyncio的整体介绍,看过之后基本对async ...

  6. MongoDB入门一

    一.环境配置 1.下载MongoDB,找到Bin目录下所有的.exe文件,拷贝到G盘MongoDB(新建)下,在MongoDB下建一个data文件,用于存放数据,创建一个logs文件夹,文件夹下创建一 ...

  7. 20145308 《网络对抗》 MAL_后门应用与实践 学习总结

    20145308 <网络对抗> MAL_后门应用与实践 学习总结 实践目的 使用nc实现win和Linux间的后门连接 meterpreter的应用 MSF POST的应用 知识点学习总结 ...

  8. 【专家坐堂Q&A】在 petalinux-config 中选择外部来源时,可将符号链路添加内核来源目录树

    问题描述 作为 petalinux-config 菜单的一部分,现在可以将 Linux 内核指定为外部来源. 如果选择了该选项,可为内核来源目录树添加两个符号链路. 这会带来两个问题: 1. 符号链路 ...

  9. Spring 学习——Bean容器

    Bean容器初始化 基础 org.springframework.beans org.springframework.context BeanFactory提供配置结构和基本功能,加载并初始化Bean ...

  10. [SDOI2016]游戏 树剖+李超树

    目录 链接 思路 update 代码 链接 https://www.luogu.org/problemnew/show/P4069 思路 树剖+超哥线段树 我已经自毙了,自闭了!!!! update ...