【Ruby】【高级编程】面向对象
# 【【面向对象】】
#【实例变量】
=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】【高级编程】面向对象的更多相关文章
- C++面向对象高级编程(九)Reference与重载operator new和operator delete
摘要: 技术在于交流.沟通,转载请注明出处并保持作品的完整性. 一 Reference 引用:之前提及过,他的主要作用就是取别名,与指针很相似,实现也是基于指针. 1.引用必须有初值,且不能引用nul ...
- C++面向对象高级编程(八)模板
技术在于交流.沟通,转载请注明出处并保持作品的完整性. 这节课主要讲模板的使用,之前我们谈到过函数模板与类模板 (C++面向对象高级编程(四)基础篇)这里不再说明 1.成员模板 成员模板:参数为tem ...
- C++面向对象高级编程(七)point-like classes和function-like classes
技术在于交流.沟通,转载请注明出处并保持作品的完整性. 1.pointer-like class 类设计成指针那样,可以当做指针来用,指针有两个常用操作符(*和->),所以我们必须重载这两个操作 ...
- C++面向对象高级编程(六)转换函数与non-explicit one argument ctor
技术在于交流.沟通,转载请注明出处并保持作品的完整性. 1.conversion function 转换函数 //1.转换函数 //conversion function //只要你认为合理 你可以任 ...
- C++面向对象高级编程(五)类与类之间的关系
技术在于交流.沟通,转载请注明出处并保持作品的完整性. 本节主要介绍一下类与类之间的关系,也就是面向对象编程先介绍两个术语 Object Oriented Programming OOP面向对象编 ...
- C++面向对象高级编程(四)基础篇
技术在于交流.沟通,转载请注明出处并保持作品的完整性. 一.Static 二.模板类和模板函数 三.namespace 一.Static 静态成员是“类级别”的,也就是它和类的地位等同,而普通成员是“ ...
- C++面向对象高级编程(三)基础篇
技术在于交流.沟通,转载请注明出处并保持作品的完整性. 概要 一.拷贝构造 二.拷贝赋值 三.重写操作符 四.生命周期 本节主要介绍 Big Three 即析构函数,拷贝构造函数,赋值拷贝函数,前面主 ...
- C++面向对象高级编程(二)基础篇
技术在于交流.沟通,转载请注明出处并保持作品的完整性. 概要 知识点1.重载成员函数 知识点2 . return by value, return by reference 知识点3 重载非成员函数 ...
- C++面向对象高级编程(一)基础篇
技术在于交流.沟通,转载请注明出处并保持作品的完整性. 概要: 知识点1 构造函数与析构函数 知识点2 参数与返回值 知识点3 const 知识点4 函数重载(要与重写区分开) 知识点5 友元 先以C ...
- Python 面向对象之高级编程
7.面向对象高级编程 7.1使用__slots__ python动态语言,new 对象后绑定属性和方法 Tip:给一个实例绑定的方法,对其他对象无效.可以通过对class绑定后,所有对象可以调用该方法 ...
随机推荐
- [转载]web安全之token
参考:http://blog.csdn.net/sum_rain/article/details/37085771 Token,就是令牌,最大的特点就是随机性,不可预测.一般黑客或软件无法猜测出来. ...
- Java常用API、Math类介绍
一.API的概述 API——Application Programing Interface:应用程序编程接口,是java提供的一些预定义的函数: 目的:基于API实现程序的快速编写,只需了解其作用, ...
- sudo: apt-get: command not found
apt-get是debian(Ubuntu)才有的包管理器,而在Apple 的OS X系统中是没有的. brew(全称Homebrew)是Mac OSX上的软件包管理工具,能在Mac中方便的安装软件或 ...
- puts函数
1.puts函数是gets函数的输出版本,它把指定的字符串写到标准输出并在末尾添加一个换行符 #include <stdio.h> #include <stdlib.h> in ...
- Java 安全套接字编程以及keytool 使用最佳实践
概述 利用 Java 的 JSSE(Java Secure Socket Extension)技术,我们可以方便的编写安全套接字程序,关于 JSSE 的介绍,可以参阅 Oracle 网站提供的 JSS ...
- kivy 使用webview加载网页
from kivy.app import App from kivy.uix.widget import Widget from kivy.clock import Clock from jnius ...
- Git clone 报错 Unable to negotiate with xxx.xxx.xxx.xxx port 12345: no matching cipher found. Their offer: aes128-cbc,3des-cbc,blowfish-cbc
git clone 报错 Unable to negotiate with xxx.xxx.xxx.xxx. port 12345: no matching cipher found. Their o ...
- NATS—协议详解(nats-protocol)
NATS的协议是一个简单的.基于文本的发布/订阅风格的协议.客户端连接到 gnatsd(NATS服务器),并与 gnatsd 进行通信,通信基于普通的 TCP/IP 套接字,并定义了很小的操作集,换行 ...
- Mac下Homebrew的安装与使用
Homebrew简介,安装与使用 简介 Homebrew 官方网站 Homebrew是一个包管理器,用于安装Apple没有预装但你需要的UNIX工具.(比如著名的wget). Homebrew会将软件 ...
- 【题解】Luogu P1972 [SDOI2009]HH的项链
原题传送门 莫队入门题 我博客里对莫队的介绍 很多人说这题卡莫队,但窝随便写了一个程序就过了qaq(虽说开了氧化) 我们在排序询问时,普通是这样qaq inline bool cmp(register ...