文档章节

类和对象之类与字段和方法

柳哥
 柳哥
发布于 2014/06/05 20:50
字数 1396
阅读 164
收藏 2

类是对象的蓝图,一旦你定义了类,就可以用关键字new根据类的蓝图创建对象。类定义里,可以放置字段和方法,这些被笼统地称为成员。字段,不管是用val还是用var定义的,都是指向对象的变量。方法,用def定义,包含了可执行的代码。字段保留了对象的状态或数据,而方法使用这些数据执行对象的运算工作。如例,定义了ChecksumAccumulator类并内置名为sum的var字段:

class ChecksumAccumulator{
  var sum = 0;
}

然后实例化两次:

val acc = new ChecksumAccumulator
val csa = new ChecksumAccumulator

每一个实例都有自己的变量集。如果你改变acc对象的sum变量值,而csa对象的sum值是不会一起跟着改变的,因为它们都属于各自的对象(跟Java是一样的)。另外还需要注意的是,尽管acc,csa都是val的,但仍可以修改它们所指向的对象。val类型的限制仅在于不可以把它们(acc,csa)再次赋值为其他对象(这一点跟Java的final关键字使用是一样的)。因此,我们可以得出结论:val的acc,csa将始终指向初始化时的ChecksumAccumulator对象,但是对象包含的字段可以随时改动

Scala中,字段可以申明为私有的。通过把字段变为私有的(private)以阻止外界直接对它的访问,因为私有字段只能被定义在同一个类里的方法访问,所有能更新字段的代码将被锁定在类里。要声明字段是私有的,可以把访问修饰符private放在字段的前面(这与java使用private关键字相同),如例:

class ChecksumAccumulator{
  private var sum = 0;
}

现在sum是私有的,所以唯一能访问sum的代码都定义在类的内部。


如上例:acc.sum = 5         //编译不过,因为sum是私有的。
注意在scala里把成员变量公开的方法是不显式地指定任何访问修饰符。换句话说,在java里要写上“public”的地方,在scala里只要什么都不要写就成。public是scala方法的默认访问级别。上面的例子,除非我们定义其它什么方法,否则ChecksumAccumulator对任何人都没有什么用处:

class ChecksumAccumulator{
  private var sum = 0;
  def add(b:Byte):Unit = {
      sum += b;
  }
  def checksum():Int = {
      return ~(sum &0xFF) + 1;
  }
}

现在ChecksumAccumulator有两个方法了,add和checksum。
传递给方法的任何参数都可以在方法内部使用。Scala里方法参数的一个重要特征是:它们都是val的,不是var的。如果你想在方法里面给参数赋值,编译会失败。如例:


尽管ChecksumAccumulator在这个版本里的add与checksum方法正确地实现了预期的功能,但还不够简洁。首先,checksum方法最后的return语句是多余的可以去掉。如果没有发现任何显式的返回语句,scala方法将返回方法中最后一次计算得到的值。如例:

方法的推荐风格是尽量避免使用返回语句,尤其是多条返回语句。代之以把每个方法当作是创建返回值的表达式。这种逻辑鼓励你分层简化方法,把较大的方法分解为多个更小的方法。另一方面,内容决定形式,如果确实需要,scala也能够很容易地编写具有多个显式的return的方法。
接着上面那个ChecksumAccumulator类,checksum只要计算值,不用return。所以这个方法有另一种简写方式:假如某个方法仅计算单个结果表达式,则可以去掉花括号。如果结果表达式很短,甚至可以把它放在def的同一行里。这样改动之后,ChecksumAccumulator看上去像这样:

class ChecksumAccumulator{
  private var sum = 0
  def add(b:Byte):Unit = sum += b
  def checksum():Int = ~(sum & 0XFF) + 1
}

对于像ChecksumAccumulator的add方法那样的结果类型为Unit的方法来说,执行的目的就是为了它的副作用。通常我们定义副作用为能够改变方法之外的某处状态或执行I/O活动的方法。比方说,在add这个例子里,副作用就是sum被重新赋值了。它的另一种表达方式是去掉结果类型和等号,把方法体放在花括号里。在这种形式下,方法看上去很像过程(procedure),一种仅为了副作用而执行的方法。如例,add方法可以改写如下:

class ChecksumAccumulator{
    private var sum = 0;
    def add(b:Byte){sum += b}
    def checksum():Int = ~(sum & 0XFF) + 1
}

比较容易出错的地方是:如果去掉方法体前面的等号,那么方法的结果类型就必定是Unit。这种说法不论方法体里面包含什么都成立,因为Scala编译器可以把任何类型转换为Unit。例如,如果方法的最后结果是String,但结果类型被声明为Unit,那么String将被转变为Unit并丢弃原值:


例子里,函数f声明了结果类型Unit,因此String被转换为Unit。带有花括号但没有等号的,本质上当作Unit结果类型的方法,例如:

因此,对于本想返回非Unit值的方法却忘记加等号时,错误就出现了。所以为了得到想要的结果,等号是必不可少的:

© 著作权归作者所有

共有 人打赏支持
柳哥
粉丝 206
博文 405
码字总数 347782
作品 0
杭州
技术主管
私信 提问
python面向对象之类成员

一、概述 上篇《python面向对象OOP》介绍了python面向对象的基础初级入门部分,提到了类的定义,使用,类的三大特性;经典类,新式类在查找时的区别等,有了前面的基础,本文接着描述面向对象...

dyc2005
2017/11/18
0
0
2Python全栈之路系列之面向对象进阶及类成员

再次了解多继承 先来一段代码 执行结果 流程释意: 创建了类A、B、C、D; 继承了和,继承了,内什么都不做,; 创建一个对象,类是,当执行的方法的时候会先从里面寻找有没有方法; 内没有方...

余二五
2017/11/14
0
0
Kotlin之类、对象和接口

Kotlin的类和接口与Java的类和接口是有一定的区别的。 Kotlin的接口是可以包含属性声明。 Kotlin默认的声明是fianl 和public的。 Kotlin里嵌套的类默认并不是内部内,不包含对器外部类的隐式...

程自舟
2017/12/24
0
0
vc++windows编程技术(1)

1.1Windows应用特点 windows应用的面相对象性的了解 。并不是意味着windows应用是采用面相对象的语言开发的。 windows应用时多任务的可以同时运行2个或以上的控制台应用;而控制台应用是单任...

mli
2014/10/23
0
0
浅谈Java并发编程系列(八)—— LockSupport原理剖析

LockSupport 用法简介 LockSupport 和 CAS 是Java并发包中很多并发工具控制机制的基础,它们底层其实都是依赖Unsafe实现。 LockSupport是用来创建锁和其他同步类的基本线程阻塞原语。LockSup...

codershamo
2017/02/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

解析如何用爬虫程序批量采集梨视频数据

本文介绍如何使用爬虫程序免费采集梨视频拍客的视频标题、链接、简介等信息。 采集字段: 视频标题 视频链接 点赞数 视频时长 发布时间 拍客 拍客链接 视频简介 标签 功能点目录: 如何对采集...

技术阿飞
8分钟前
0
0
《阿里铁军》的读书笔记和读后感范文2600字

《阿里铁军》的读书笔记和读后感范文2600字: 在中国互联网,有一个流传很广的说法是,百度强在技术,腾讯强在产品,阿里强在运营。虽然发展到今天,已经不能再用这样简单的视角来看待这三个...

原创小博客
37分钟前
3
0
怎样实际项目中运用责任链模式

1 模式概要 1.1 简介 责任链模式为请求创建一个接收者对象链,每个接收者都包含对另一个接收者的引用,如果一个对象不能处理该请求,那么它会把请求传给下一个接收者,依此类推 责任链模式避...

小刀爱编程
52分钟前
2
0
【宇润日常疯测-004】JS 遍历数组如何快!快!快!

首先,我就是一后端全栈,对前端也只是会用罢了。闲的无聊来测测,不深究,只看表面,不喜勿喷! 遍历数组在写 JS 代码时候一定是经常用的,那么怎么遍历能达到最高效率呢,很多人一定没有测...

宇润
56分钟前
11
2
Linux系统如何定制History输出格式

Linux系统使用History命令来查看系统的运行记录,从而找出一些问题。但是History输出的数据中常常没有时间等信息。本文就来教大家Linux系统如何定制History输出格式。   具体方法如下 以r...

linuxprobe16
58分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部