类和模块

1.类

类是面向对象中一个重要的术语。我们可以把类看作是对象的抽象,

所有的这类对象都有这些特征。而对象则是类的具体实现,按照类的要求创建的

对象就是该类的对象。类就像对象的雏形一样,决定了对象的行为。

eg:用数组类创建数组对象

arr=Array.new   #[]

用class方法查看对象属于那个类

arr=[1,2,3]
p arr.class #Array
p Array.class #Class

所有的类都是Class类的对象。

当判断某个对象是否属于某个类,我们可以使用instance_of?方法。

arr=[1,2,3]
p arr.instance_of? Array #true
p arr.instance_of? Object #false

继承

通过扩展已经创建的类来创建新的类成为继承。继承后创建的新类被称为子类。

被继承的类称为父类。

BasicObject类是ruby中所有类的父类。他定义了作为ruby对象最基本的功能。

Object是BasicObject的子类。定义一般类所需要的功能。

根据类的反向继承关系追查对象是否属于某个类,则可以使用is_a?方法。

arr=[1,2,3]
p arr.is_a? Array #true
p arr.is_a? Object #true

创建类

class 类名
类的定义
end

类名的首字母必须大写.eg:

class Sayhello
def initialize(myname="ruby")
puts "调用我实例化对象"
@name=myname
end def hello
puts "hello,I am #{@name}!"
end
end #实例化对象
java=Sayhello.new("java")
ruby=Sayhello.new

调用new方法创建对象时会默认调用initialize方法。

@name时实例变量。hello方法时实例方法。实例方法中可以直接引用实例变量。

引用未定义的实例变量会返回nil.

存取器

ruby中不能直接访问实例变量或对实例变量赋值。需要通过方法来操作。
class Sayhello
def initialize(myname="ruby")
puts "调用我实例化对象"
@name=myname
end def hello
puts "hello,I am #{@name}!"
end
#获取实例变量的方法
def name
puts "获取实例变量@name"
@name
end
#修改实例变量的方法
def name=(value)
puts "修改实例变量@name"
@name=value
end
end #实例化对象
java=Sayhello.new("java") #调用initialize方法
p java.name #调用name方法
java.name="python" #调用name=方法
p java.name #调用name方法
java.hello #调用hello方法

Ruby提供了更简便的实现方法

定义 意义
attr_reader :name 只读(定义name方法)
attr_writer :name 只写(定义name=方法)
attr_accessor :name 读写(定义上面的两个方法)

eg:

class Sayhello
#name和name=
attr_accessor :name
def initialize(myname="ruby")
puts "调用我实例化对象"
@name=myname
end def hello
puts "hello,I am #{@name}!"
end
end #实例化对象
java=Sayhello.new("java") #调用initialize方法
p java.name #"java"
java.name="python"
p java.name #"python"
java.hello #hell0,I am python

特殊变量self

在类内部self指向类自身,在实例方法内部,self指向调用方法的实例。

class Sayhello
#name和name=
attr_accessor :name
def initialize(myname="ruby")
puts "调用我实例化对象"
@name=myname
end def hello
puts "hello,I am #{self.name}!"
end
end #实例化对象
java=Sayhello.new("java") #调用initialize方法 java.hello #hell0,I am java

等价于

class Sayhello
#name和name=
attr_accessor :name
def initialize(myname="ruby")
puts "调用我实例化对象"
@name=myname
end def hello
puts "hello,I am #{@name}!"
end
end #实例化对象
java=Sayhello.new("java") #调用initialize方法 java.hello #hell0,I am java

类方法

class Sayhello
class << Sayhello
def hello(name)
puts "#{name} said hello."
end
end def initialize(myname="ruby")
puts "调用我实例化对象"
@name=myname
end def hello
puts "hello,I am #{@name}!"
end
end #实例化对象
java=Sayhello.new("java") #调用initialize方法
java.hello #hell0,I am java
#调用类方法
Sayhello.hello "ruby" #ruby said hello;

在类内部定义类方法

class Sayhello
class << self
def hello(name)
puts "#{name} said hello"
end
end
def initialize(myname="ruby")
puts "调用我实例化对象"
@name=myname
end def hello
puts "hello,I am #{@name}!"
end
end #调用类方法
Sayhello.hello "ruby" #ruby said hello

或者

class Sayhello
def Sayhello.hello(name)
puts "#{name} said hello"
end
def initialize(myname="ruby")
puts "调用我实例化对象"
@name=myname
end def hello
puts "hello,I am #{@name}!"
end
end #调用类方法
Sayhello.hello "ruby" #ruby said hello

或者

class Sayhello
def self.hello(name)
puts "#{name} said hello"
end
def initialize(myname="ruby")
puts "调用我实例化对象"
@name=myname
end def hello
puts "hello,I am #{@name}!"
end
end #调用类方法
Sayhello.hello "ruby" #ruby said hello

使用class <<类名 ~ end 这种写法的类定义称为单例类定义。

单例类定义中定义的方法称为单例类方法。

常量

class语句中可以定义常量

class Sayhello
Version="1.0"
def initialize(myname="ruby")
puts "调用我实例化对象"
@name=myname
end def hello
puts "hello,I am #{@name}!"
end
end #实例化对象
p Sayhello::Version #"1.0"

类变量

类变量为所有类的实例所共享,从类的外部访问类变量时需要存储器,不能使用

attr_accessor等,需要直接定义。

class Sayhello
@@count=0
def Sayhello.count
@@count
end
def initialize(myname="ruby")
puts "调用我实例化对象"
@name=myname
end def hello
@@count+=1
puts "hello,I am #{@name}!"
end end #实例化对象
p Sayhello.count #0
ruby=Sayhello.new
ruby.hello
java=Sayhello.new "java"
java.hello
p Sayhello.count #2

限制方法的调用

Ruby提供了三种方法的访问级别:

关键字 访问级别
public 以实例方法的形式向外公开该方法
private 只在类内部可以用
protected 类内部及子类中可以使用

eg:

class AccTest
def pub
puts "hello"
end
#设置方法的访问权限
public :pub
def priv
puts "private"
end
#设置方法的访问权限
private :priv
end acc=AccTest.new
acc.pub
acc.priv #NoMethodError

希望统一定义多个方法的访问级别时。可以使用下面的语法。

eg:

class AccTest
public #以下的方法都被定义为public
def pub
puts "hello"
end
private #以下方法都被定义为private
def priv
puts "private"
end
end acc=AccTest.new
acc.pub
acc.priv #NoMethodError

没有定义访问访问级别方法默认为public,但是initialize方法是个例外,

他通常被定义为private.

扩展类

eg:在原有的类的基础上添加方法

class String
def count_word
#用空格分割self
ary=self.split(/\s+/)
#返回分解后的数组的长度
return ary.size
end
end
str="I am ruby"
p str.count_word #3

继承

class 类名 < 父类名
类定义
end

eg:RingArray继承Array

class RingArray < Array
#重定义运算符[]
def[](i)
ind=i%self.size
super(ind)
end
end arr=RingArray["金","木","水","火","土"]
p arr[6] #"木"
p arr[12] #"水"

定义类的时候没有指定父类的情况下,ruby会默认该类为Object类的子类。

有时候我们希望继承更轻量级的类,就会使用BasicObject类

eg:查看类的实例方法

p Object.instance_methods
p BasicObject.instance_methods
#[:!, :==, :!=, :__send__, :equal?, :instance_eval, :instance_exec, :__id__]

需要继承BasicObject类,需要显式的继承。

alias与undef

使用alias给方法设置别名.或者在重定义已经存在的方法时,为了使用别名调用

原来的方法,也需要用到alias.

alias 别名  原名
alias :别名 :原名
class Sayhello
def hello
"hello"
end
alias sayhello hello
end h=Sayhello.new
p h.sayhello #"hello"

eg:

class Sayhello
def hello
"hello"
end
alias sayhello hello
end class Child < Sayhello
alias old_hello hello
def hello
"#{old_hello},again."
end
end child=Child.new
p child.old_hello #"hello"
p child.hello #"hello,again."

undef

undef用于删除已定义的方法。

undef 方法名
undef :方法名

eg:子类中删除父类定义的方法

class Sayhello
def hello
"hello"
end
alias sayhello hello
def del
"delete"
end
end class Child < Sayhello
alias old_hello hello
def hello
"#{old_hello},again."
end
undef del
end child=Child.new
p child.old_hello #"hello"
p child.hello #"hello,again."
p child.del #NoMethodError

单例类

利用单例类给对象添加方法

str1="Ruby"
str2="Ruby"
class << str1
def hello
"hello,#{self}!"
end
end p str1.hello #"hello,Ruby!"
p str2.hello #(NoMethodError)

Ruby中所有的类都是Class类的对象,因此,Class对象的实例方法以及

类对象的单例方法都是类方法。

ruby基础(三)的更多相关文章

  1. Ruby语法基础(三)

    Ruby语法基础(三) ​ 在前面快速入之后,这次加深对基本概念的理解. 字符串 ​ Ruby字符串可以分为单引号字符串和双引号字符串,单引号字符串效率更高,但双引号的支持转义和运行 puts '单引 ...

  2. 1月10日 ruby基础教程,查漏补缺; 2月22日 Exception补充

    https://ruby-doc.org/core-2.5.0/Exception.html 1月20日练习完1,2章. 第一章 初探 ‘’单引号不执行转义符. \t 制表符.\n 换行符. p me ...

  3. Python全栈开发【基础三】

    Python全栈开发[基础三]  本节内容: 函数(全局与局部变量) 递归 内置函数 函数 一.定义和使用 函数最重要的是减少代码的重用性和增强代码可读性 def 函数名(参数): ... 函数体 . ...

  4. Bootstrap <基础三十二>模态框(Modal)插件

    模态框(Modal)是覆盖在父窗体上的子窗体.通常,目的是显示来自一个单独的源的内容,可以在不离开父窗体的情况下有一些互动.子窗体可提供信息.交互等. 如果您想要单独引用该插件的功能,那么您需要引用  ...

  5. Bootstrap <基础三十一>插件概览

    在前面布局组件中所讨论到的组件仅仅是个开始.Bootstrap 自带 12 种 jQuery 插件,扩展了功能,可以给站点添加更多的互动.即使不是一名高级的 JavaScript 开发人员,也可以着手 ...

  6. Bootstrap <基础三十>Well

    Well 是一种会引起内容凹陷显示或插图效果的容器 <div>.为了创建 Well,只需要简单地把内容放在带有 class .well 的 <div> 中即可.下面的实例演示了 ...

  7. Bootstrap<基础三> 排版

    Bootstrap 使用 Helvetica Neue. Helvetica. Arial 和 sans-serif 作为其默认的字体栈. 使用 Bootstrap 的排版特性,您可以创建标题.段落. ...

  8. jdbc基础 (三) 大文本、二进制数据处理

    LOB (Large Objects)   分为:CLOB和BLOB,即大文本和大二进制数据 CLOB:用于存储大文本 BLOB:用于存储二进制数据,例如图像.声音.二进制文件 在mysql中,只有B ...

  9. C#_02.13_基础三_.NET类基础

    C#_02.13_基础三_.NET类基础 一.类概述: 类是一个能存储数据和功能并执行代码的数据结构,包含数据成员和函数成员.(有什么和能够干什么) 运行中的程序是一组相互作用的对象的集合. 二.为类 ...

  10. Ruby基础教程

    一.Ruby基础知识 1.关于Ruby Ruby是脚本语言 Ruby是面向对象语言 Ruby是跨平台语言 Ruby是开放源码软件 2.Ruby入门书籍推荐 <Ruby.Programming向R ...

随机推荐

  1. 最小生成树,Prim和Kruskal的原理与实现

    文章首先于微信公众号:小K算法,关注第一时间获取更新信息 1 新农村建设 大清都亡了,我们村还没有通网.为了响应国家的新农村建设的号召,村里也开始了网络工程的建设. 穷乡僻壤,人烟稀少,如何布局网线, ...

  2. 使用KeepAlived来实现高可用的DR模型

    环境 VMware 16 CentOS8 相关软件 keepalived ipvsadm httpd 准备工作 准备四个节点,如上图,Node01 ~ Node04, 本文默认你会在VMWare上安装 ...

  3. Redis生产环境节点宕机问题报错及恢复排错

    Redis故障发现 主观下线 当cluster-node-timeout时间内某节点无法与另一个节点顺利完成ping消息通信时,则将该节点标记为主观下线状态. 客观下线 当某个节点判断另一个节点主观下 ...

  4. 面试题:Linux 中一个文件的 MAC 代表什么意思

    查看文件状态 stat ls 命令能够查看文件的类型.时间.属主.属组,大小以及最近的修改时间等信息,但是还有一些文件的扩展属性,是使用 ls 命令无法查看到的 stat 命令则用于显示文件的详细属性 ...

  5. 【软件推荐】使用Cmder替换Windows自带的控制台

    安装地址 进入cmder官网,下载相应版本. 如果本地已经安装了git,可以选择mini版本. 将 λ 替换为 $ 当前cmder默认的提示符是λ,看上去总是有点不习惯. 打开cmder目录下的ven ...

  6. 010_Nginx入门

    目录 使用场景 什么是Nginx 正向代理与反向代理 正向代理:代理客户端 反向代理:代理服务端 Nginx的作用 反向代理 负载均衡 轮询 加权轮询 IP hash 动静分离 Windows下安装 ...

  7. 八戒转世投胎竟然是Java设计模式:桥接模式

    目录 示例 代码实例 桥接模式 定义 意图 主要解决问题 何时使用 优缺点 八戒转世投胎的故事 示例 请开发一个画图程序,可以画各种颜色不同形状的图形,请用面向对象的思 想设计图形 分析: 1.比如有 ...

  8. Day 12_61_多线程的创建和启动(二)

    多线程的创建和启动 * 在java中实现多线程的第二种方法 实现java.lang.Runnable接口,重写run()方法 * 推荐使用这种方式,因为实现接口还可以保留类的继承. package c ...

  9. 哈工大LTP进阶使用-三元组事件抽取

    哈工大LTP基本使用-分词.词性标注.依存句法分析.命名实体识别.角色标注 上一节我们讲了LTP的基本使用,接下来我们使用其进行事件抽取. 参考代码:https://github.com/liuhua ...

  10. vagrant构建centos虚拟环境

    vagrant搭建centos 什么是vagrant 如何使用 1.构建本地的目录 2.官方下载对应的镜像文件,官方下载地址 3.导入刚刚下载的镜像(box文件) 4.初始化 5.修改Vagrantf ...