- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章进一步深入Ruby中的类与对象概念由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
Ruby是纯面向对象的语言,所有项目似乎要Ruby中为一个对象。Ruby中的每个值是一个对象,即使是最原始的东西:字符串,数字甚至true和false。即使是一个类本身是一个对象,它是Class类的一个实例。本章将通过所有功能涉及到Ruby的面向对象.
类是用来指定对象的形式,它结合了数据表示和方法操纵这些数据,转换成一个整齐的包。在一个类的数据和方法,被称为类的成员。 Ruby类的定义:
定义一个类,定义的数据类型的草图。 这实际上并不定义任何数据,但它定义的类名字的意思什么,即是什么类的对象将包括这样一个对象上执行什么操作可以.
类定义开始与关键字class类名和 end 分隔。例如,我们定义Box类使用class关键字如下:
class Box code end 。
名称必须以大写字母开始,按照约定名称中包含多个单词,每个单词没有分隔符(驼峰式)一起执行。 定义Ruby的对象:
类为对象的蓝图,所以基本上是一个从一个类对象被创建。我们声明一个类的对象使用new关键字。下面的语句声明了两个对象,Box 类:
1
2
|
box1 = Box.
new
box2 = Box.
new
|
initialize方法:
initialize方法是一个标准的Ruby类的方法,和其它面向对象编程语言的构造方法有相同的方式工作。 initialize方法是有用的,在创建对象的时候,一些类变量初始化。这种方法可能需要的参数列表,它像其他Ruby之前的方法用def关键字定义,如下所示:
class Box def initialize(w,h) @width, @height = w, h end end 。
实例变量:
实例变量是类的一种属性,一旦我们使用的类对象被创建的对象的属性。每个对象的属性被分别赋值的并与其它对象共享,它们在类的内部使用@操作符访问,但访问类之外的,我们使用的公共方法被称为访问器方法。如果我们把上述定义的类 Box,然后 @width 和 @height 类 Box实例变量.
1
2
3
4
5
6
|
class
Box
def
initialize(w,h)
# assign instance avriables
@width
,
@height
= w, h
end
end
|
访问器和setter方法:
为了外部能访问类的变量,它们必须定义存取器方法,这些存取器方法也被称为getter方法。下面的例子演示了如何使用访问器方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
#!/usr/bin/ruby -w
# define a class
class
Box
# constructor method
def
initialize(w,h)
@width
,
@height
= w, h
end
# accessor methods
def
printWidth
@width
end
def
printHeight
@height
end
end
# create an object
box = Box.
new
(
10
,
20
)
# use accessor methods
x = box.printWidth()
y = box.printHeight()
puts
"Width of the box is : #{x}"
puts
"Height of the box is : #{y}"
|
当上面的代码执行时,它会产生以下结果:
1
2
|
Width of the box is :
10
Height of the box is :
20
|
类似的存取方法用于访问的变量值,Ruby提供了一种方法来从类的外部设置这些变量的值,那就是setter方法??,定义如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
#!/usr/bin/ruby -w
# define a class
class
Box
# constructor method
def
initialize(w,h)
@width
,
@height
= w, h
end
# accessor methods
def
getWidth
@width
end
def
getHeight
@height
end
# setter methods
def
setWidth=(value)
@width
= value
end
def
setHeight=(value)
@height
= value
end
end
# create an object
box = Box.
new
(
10
,
20
)
# use setter methods
box.setWidth =
30
box.setHeight =
50
# use accessor methods
x = box.getWidth()
y = box.getHeight()
puts
"Width of the box is : #{x}"
puts
"Height of the box is : #{y}"
|
当上面的代码执行时,它会产生以下结果:
1
2
|
Width of the box is :
30
Height of the box is :
50
|
实例方法:
也以同样的方式,因为我们使用def关键字定义其他方法,并按下图所示仅对使用一个类的实例,它们可以被用来定义该实例方法。它们的功能不局限于访问实例变量,他们也可以按要求做更多的事情.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#!/usr/bin/ruby -w
# define a class
class
Box
# constructor method
def
initialize(w,h)
@width
,
@height
= w, h
end
# instance method
def
getArea
@width
*
@height
end
end
# create an object
box = Box.
new
(
10
,
20
)
# call instance methods
a = box.getArea()
puts
"Area of the box is : #{a}"
|
当上面的代码执行时,它会产生以下结果:
1
|
Area of the box is :
200
|
类的方法和变量:
类变量是一个变量,这是一个类的所有实例之间共享。该变量是一个实例,它是可访问对象实例。两个@字符类变量带有前缀(@@)。在类定义类变量必须初始化,如下所示.
类方法的定义使用:def self.methodname() 以 end 字符结束,将被称为使用classname.methodname类名,在下面的例子所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#!/usr/bin/ruby -w
class
Box
# Initialize our class variables
@@count
=
0
def
initialize(w,h)
# assign instance avriables
@width
,
@height
= w, h
@@count
+=
1
end
def
self
.printCount()
puts
"Box count is : #@@count"
end
end
# create two object
box1 = Box.
new
(
10
,
20
)
box2 = Box.
new
(
30
,
100
)
# call class method to print box count
Box.printCount()
|
当上面的代码执行时,它会产生以下结果:
1
|
Box count is :
2
|
to_s 方法
所定义的任何类的实例应该有一个 to_s 方法返回一个字符串形式表示对象。下面以一个简单的例子来表示一个Box对象,在宽度和高度方面:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#!/usr/bin/ruby -w
class
Box
# constructor method
def
initialize(w,h)
@width
,
@height
= w, h
end
# define to_s method
def
to_s
"(w:#@width,h:#@height)"
# string formatting of the object.
end
end
# create an object
box = Box.
new
(
10
,
20
)
# to_s method will be called in reference of string automatically.
puts
"String representation of box is : #{box}"
|
当上面的代码执行时,它会产生以下结果:
1
|
String
representation of box is : (w:
10
,h:
20
)
|
访问控制:
Ruby提供了三个级别的保护实例方法的级别:public, private 和 protected。 Ruby没有应用实例和类变量的任何访问控制权.
以下是一个简单的例子来说明三个访问修饰符的语法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
#!/usr/bin/ruby -w
# define a class
class
Box
# constructor method
def
initialize(w,h)
@width
,
@height
= w, h
end
# instance method by default it is public
def
getArea
getWidth() * getHeight
end
# define private accessor methods
def
getWidth
@width
end
def
getHeight
@height
end
# make them private
private
:getWidth
,
:getHeight
# instance method to print area
def
printArea
@area
= getWidth() * getHeight
puts
"Big box area is : #@area"
end
# make it protected
protected
:printArea
end
# create an object
box = Box.
new
(
10
,
20
)
# call instance methods
a = box.getArea()
puts
"Area of the box is : #{a}"
# try to call protected or methods
box.printArea()
|
当上面的代码被执行时,产生下面的结果。在这里,第一种方法被调用成功,但第二种方法给一个提示.
1
2
3
|
Area of the box is :
200
test.rb:
42
: protected method `printArea' called
for
#
<Box:0xb7f11280
@height
=
20
,
@width
=
10
> (NoMethodError)
|
类的继承:
在面向对象的编程中最重要的概念之一是继承。继承允许我们定义一个类在另一个类的项目,这使得它更容易创建和维护应用程序.
继承也提供了一个机会,重用代码的功能和快速的实现时间,但不幸的是Ruby不支持多级的继承,但Ruby支持混入。一个mixin继承多重继承,只有接口部分像一个专门的实现.
当创建一个类,而不是写入新的数据成员和成员函数,程序员可以指定新的类继承现有类的成员。这种现有的类称为基类或父类和新类称为派生类或子类.
Ruby也支持继承。继承和下面的例子解释了这个概念。扩展类的语法很简单。只需添加一个<字符的超类声明的名称。例如,定义Box类的子类classBigBox:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
#!/usr/bin/ruby -w
# define a class
class
Box
# constructor method
def
initialize(w,h)
@width
,
@height
= w, h
end
# instance method
def
getArea
@width
*
@height
end
end
# define a subclass
class
BigBox < Box
# add a new instance method
def
printArea
@area
=
@width
*
@height
puts
"Big box area is : #@area"
end
end
# create an object
box = BigBox.
new
(
10
,
20
)
# print the area
box.printArea()
|
当上面的代码执行时,它会产生以下结果:
1
|
Big box area is :
200
|
方法重载:
虽然可以在派生类中添加新的函数,但有时想改变的行为已经在父类中定义的方法。只需通过保持相同的方法名和重写该方法的功能,如下图所示,在这个例子可以这样做:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
#!/usr/bin/ruby -w
# define a class
class
Box
# constructor method
def
initialize(w,h)
@width
,
@height
= w, h
end
# instance method
def
getArea
@width
*
@height
end
end
# define a subclass
class
BigBox < Box
# change existing getArea method as follows
def
getArea
@area
=
@width
*
@height
puts
"Big box area is : #@area"
end
end
# create an object
box = BigBox.
new
(
10
,
20
)
# print the area using overriden method.
box.getArea()
|
运算符重载:
我们想“+”运算符使用+,*操作由一个标量乘以一箱的宽度和高度,这里是一个版Box类的定义及数学运算符:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
class
Box
def
initialize(w,h)
# Initialize the width and height
@width
,
@height
= w, h
end
def
+(other)
# Define + to do vector addition
Box.
new
(
@width
+ other.width,
@height
+ other.height)
end
def
-@
# Define unary minus to negate width and height
Box.
new
(-
@width
, -
@height
)
end
def
*(scalar)
# To perform scalar multiplication
Box.
new
(
@width
*scalar,
@height
*scalar)
end
end
|
冻结对象:
有时候,我们要防止被改变的对象。冻结对象的方法可以让我们做到这一点,有效地把一个对象到一个恒定。任何对象都可以被冻结通过调用Object.freeze。不得修改冻结对象:不能改变它的实例变量.
可以使用Object.frozen?语句检查一个给定的对象是否已经被冻结,被冻结的情况下的对象语句方法返回true,否则返回false值。下面的示例 freeze 的概念:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
#!/usr/bin/ruby -w
# define a class
class
Box
# constructor method
def
initialize(w,h)
@width
,
@height
= w, h
end
# accessor methods
def
getWidth
@width
end
def
getHeight
@height
end
# setter methods
def
setWidth=(value)
@width
= value
end
def
setHeight=(value)
@height
= value
end
end
# create an object
box = Box.
new
(
10
,
20
)
# let us freez this object
box.freeze
if
( box.frozen? )
puts
"Box object is frozen object"
else
puts
"Box object is normal object"
end
# now try using setter methods
box.setWidth =
30
box.setHeight =
50
# use accessor methods
x = box.getWidth()
y = box.getHeight()
puts
"Width of the box is : #{x}"
puts
"Height of the box is : #{y}"
|
当上面的代码执行时,它会产生以下结果:
1
2
3
|
Box object is frozen object
test.rb:
20
:in
`setWidth=
': can'
t modify frozen object (TypeError)
from test.rb:
39
|
类常量:
可以在类里定义分配一个直接的数字或字符串值,而不使用其定义一个变量为@@ 或 @。按照规范,我们保持常量名大写.
一个常量一旦被定义就不能改变它的值,但可以在类里像常量一样直接访问,但如果要访问一个类之外的常量,那么要使用类名::常量,所示在下面的例子.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#!/usr/bin/ruby -w
# define a class
class
Box
BOX_COMPANY
=
"TATA Inc"
BOXWEIGHT
=
10
# constructor method
def
initialize(w,h)
@width
,
@height
= w, h
end
# instance method
def
getArea
@width
*
@height
end
end
# create an object
box = Box.
new
(
10
,
20
)
# call instance methods
a = box.getArea()
puts
"Area of the box is : #{a}"
puts Box::
BOX_COMPANY
puts
"Box weight is: #{Box::BOXWEIGHT}"
|
当上面的代码执行时,它会产生以下结果:
1
2
3
|
Area of the box is :
200
TATA
Inc
Box weight is:
10
|
类常量继承和实例方法一样,可以覆盖。 创建对象使用分配:
当创建一个对象,而不调用它的构造函数初始化,即可能有一个情况:采用 new 方法,在这种情况下可以调用分配,这将创造一个未初始化的对象,看下面的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
#!/usr/bin/ruby -w
# define a class
class
Box
attr_accessor
:width
,
:height
# constructor method
def
initialize(w,h)
@width
,
@height
= w, h
end
# instance method
def
getArea
@width
*
@height
end
end
# create an object using new
box1 = Box.
new
(
10
,
20
)
# create another object using allocate
box2 = Box.allocate
# call instance method using box1
a = box1.getArea()
puts
"Area of the box is : #{a}"
# call instance method using box2
a = box2.getArea()
puts
"Area of the box is : #{a}"
|
当上面的代码执行时,它会产生以下结果:
1
2
3
4
5
|
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
|
类信息:
如果类定义的可执行代码,这意味着他们在执行的上下文中一些对象:自身都必须引用的东西。让我们来看看它是什么.
1
2
3
4
5
6
7
|
#!/usr/bin/ruby -w
class
Box
# print class information
puts
"Type of self = #{self.type}"
puts
"Name of self = #{self.name}"
end
|
当上面的代码执行时,它会产生以下结果:
1
2
|
Type of
self
=
Class
Name of
self
= Box
|
这意味着,一个类的定义,作为当前对象的类并执行。在元类和其超类的方法将在执行过程中使用的方法定义.
最后此篇关于进一步深入Ruby中的类与对象概念的文章就讲到这里了,如果你想了解更多关于进一步深入Ruby中的类与对象概念的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我想做的是让 JTextPane 在 JPanel 中占用尽可能多的空间。对于我使用的 UpdateInfoPanel: public class UpdateInfoPanel extends JP
我在 JPanel 中有一个 JTextArea,我想将其与 JScrollPane 一起使用。我正在使用 GridBagLayout。当我运行它时,框架似乎为 JScrollPane 腾出了空间,但
我想在 xcode 中实现以下功能。 我有一个 View Controller 。在这个 UIViewController 中,我有一个 UITabBar。它们下面是一个 UIView。将 UITab
有谁知道Firebird 2.5有没有类似于SQL中“STUFF”函数的功能? 我有一个包含父用户记录的表,另一个表包含与父相关的子用户记录。我希望能够提取用户拥有的“ROLES”的逗号分隔字符串,而
我想使用 JSON 作为 mirth channel 的输入和输出,例如详细信息保存在数据库中或创建 HL7 消息。 简而言之,输入为 JSON 解析它并输出为任何格式。 最佳答案 var objec
通常我会使用 R 并执行 merge.by,但这个文件似乎太大了,部门中的任何一台计算机都无法处理它! (任何从事遗传学工作的人的附加信息)本质上,插补似乎删除了 snp ID 的 rs 数字,我只剩
我有一个以前可能被问过的问题,但我很难找到正确的描述。我希望有人能帮助我。 在下面的代码中,我设置了varprice,我想添加javascript变量accu_id以通过rails在我的数据库中查找记
我有一个简单的 SVG 文件,在 Firefox 中可以正常查看 - 它的一些包装文本使用 foreignObject 包含一些 HTML - 文本包装在 div 中:
所以我正在为学校编写一个 Ruby 程序,如果某个值是 1 或 3,则将 bool 值更改为 true,如果是 0 或 2,则更改为 false。由于我有 Java 背景,所以我认为这段代码应该有效:
我做了什么: 我在这些账户之间创建了 VPC 对等连接 互联网网关也连接到每个 VPC 还配置了路由表(以允许来自双方的流量) 情况1: 当这两个 VPC 在同一个账户中时,我成功测试了从另一个 La
我有一个名为 contacts 的表: user_id contact_id 10294 10295 10294 10293 10293 10294 102
我正在使用 Magento 中的新模板。为避免重复代码,我想为每个产品预览使用相同的子模板。 特别是我做了这样一个展示: $products = Mage::getModel('catalog/pro
“for”是否总是检查协议(protocol)中定义的每个函数中第一个参数的类型? 编辑(改写): 当协议(protocol)方法只有一个参数时,根据该单个参数的类型(直接或任意)找到实现。当协议(p
我想从我的 PHP 代码中调用 JavaScript 函数。我通过使用以下方法实现了这一点: echo ' drawChart($id); '; 这工作正常,但我想从我的 PHP 代码中获取数据,我使
这个问题已经有答案了: Event binding on dynamically created elements? (23 个回答) 已关闭 5 年前。 我有一个动态表单,我想在其中附加一些其他 h
我正在尝试找到一种解决方案,以在 componentDidMount 中的映射项上使用 setState。 我正在使用 GraphQL连同 Gatsby返回许多 data 项目,但要求在特定的 pat
我在 ScrollView 中有一个 View 。只要用户按住该 View ,我想每 80 毫秒调用一次方法。这是我已经实现的: final Runnable vibrate = new Runnab
我用 jni 开发了一个 android 应用程序。我在 GetStringUTFChars 的 dvmDecodeIndirectRef 中得到了一个 dvmabort。我只中止了一次。 为什么会这
当我到达我的 Activity 时,我调用 FragmentPagerAdapter 来处理我的不同选项卡。在我的一个选项卡中,我想显示一个 RecyclerView,但他从未出现过,有了断点,我看到
当我按下 Activity 中的按钮时,会弹出一个 DialogFragment。在对话框 fragment 中,有一个看起来像普通 ListView 的 RecyclerView。 我想要的行为是当
我是一名优秀的程序员,十分优秀!