文档章节

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

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

类是对象的蓝图,一旦你定义了类,就可以用关键字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值的方法却忘记加等号时,错误就出现了。所以为了得到想要的结果,等号是必不可少的:

© 著作权归作者所有

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

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

dyc2005 ⋅ 2017/11/18 ⋅ 0

2Python全栈之路系列之面向对象进阶及类成员

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

余二五 ⋅ 2017/11/14 ⋅ 0

Kotlin之类、对象和接口

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

程自舟 ⋅ 2017/12/24 ⋅ 0

vc++windows编程技术(1)

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

mli ⋅ 2014/10/23 ⋅ 0

浅谈Java并发编程系列(八)—— LockSupport原理剖析

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

codershamo ⋅ 2017/02/21 ⋅ 0

[Class文件结构] 2 - 常量池、字段表

前言 [Class文件结构] 1- 概述 文中对Class文件结构进行了基本阐述,本文继续分析常量池中的具体类型。 CONSTANTClassinfo 表中第一项常量一定是CONSTANTClassinfo类型,它的结构较为简单。 ...

某昆 ⋅ 2017/12/31 ⋅ 0

动态代理的应用---AOP

AOP:面向切面编程 2. 实现原理:动态代理 3. 配置方式: <1> @AspectJ <2> XML 推荐<2>,原因:可实现"热插拔". 4. 相关术语介绍 <1> 切面:aspect 需要实现的交叉功能----通知和切入点的结合...

绿林小子 ⋅ 2015/11/12 ⋅ 0

java.util.concurrent.locks.LockSupport

要学习JAVA中是如何实现线程间的锁,就得从LockSupport这个类先说起,因为这个类实现了底层的一些方法,各种的锁实现都是这个基础上发展而来的。这个类方法很少,但理解起来需要花费一点时间...

黑妹妹牙膏 ⋅ 2014/06/22 ⋅ 5

WebService接口如何(优雅地)同时校验多个字段,并返回不同的校验后提示信息?

情景 : 例如 添加接口,服务端(先不管客户端)必须同时校验 多个字段信息,包括长度、格式、特殊字符之类的。 如果有一个字段校验不通过则返回校验不通过的提示信息,程序不运行下去。 如果...

Qiurf ⋅ 2015/04/03 ⋅ 0

JVM详解之类加载过程

JVM详解之类加载过程 什么叫类?类在什么时候进行加载?类加载过程发生了什么?或者叫jvm做了哪些工作? 类的概念(.java/.class的区别)和范围扩充 java语言和Java虚拟机的概念 java可以运行...

默默学习中 ⋅ 2016/04/15 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

两道面试题,带你解析Java类加载机制

在许多Java面试中,我们经常会看到关于Java类加载机制的考察,例如下面这道题: class Grandpa{ static { System.out.println("爷爷在静态代码块"); }} cl...

1527 ⋅ 25分钟前 ⋅ 0

SpringCloud(Data Flow)

dataflow-server

赵-猛 ⋅ 35分钟前 ⋅ 0

深入理解Java虚拟机

这本书我读到第8章,之后就是在读不下去了。 读到后面是一种痛苦的体验,太多的东西是不全面的,大量的专有名词是没有解释的,读到最后很多东西仅仅是一个侧面,所以我觉得,这本书不适合初学...

颖伙虫 ⋅ 40分钟前 ⋅ 0

B树和B+树的总结

B树 为什么要B树 磁盘中有两个机械运动的部分,分别是盘片旋转和磁臂移动。盘片旋转就是我们市面上所提到的多少转每分钟,而磁盘移动则是在盘片旋转到指定位置以后,移动磁臂后开始进行数据的...

浮躁的码农 ⋅ 43分钟前 ⋅ 0

NanoPi NEO core/ Ubuntu16.04单网卡配置3个IP地址(2个静态,1个动态)

配置 root@NanoPi-NEO-Core:/etc/network# cat interfacesauto loiface lo inet loopbackallow-hotplug eth0iface eth0 inet static address 172.31.188.249 netmask 255.......

SamXIAO ⋅ 今天 ⋅ 0

三步为你的App集成LivePhoto功能

摘要:LivePhoto是iOS9新推出的一种拍照方式,类似于拍摄Gif图或录制视频片段生成图片。如果没有画面感,可以联想《哈利波特》霍格沃茨城堡的壁画,哈哈,很炫酷有木有,但坑爹的是只有iphone6S以...

壹峰 ⋅ 今天 ⋅ 0

centos7 git安装

由于centos中的源仓库中git不是最新版本,需要进行源码安装。 1、查看yum仓库git信息 [root@iZm5e3d4r5i5ml889vh6esZ zh]# yum info gitLoaded plugins: fastestmirrorLoading mirror s...

xixingzhe ⋅ 今天 ⋅ 0

input file 重复上传同一张图片失效的解决办法

解决办法 方法一:来回切换input[type='file']的type属性值,可以是‘text’,'button','button'....,然后再切换回来‘file’ 方法二:每次取消图片预览后,重置input[type='file']的value的...

时刻在奔跑 ⋅ 今天 ⋅ 0

Mahout推荐算法API详解

前言 用Mahout来构建推荐系统,是一件既简单又困难的事情。简单是因为Mahout完整地封装了“协同过滤”算法,并实现了并行化,提供非常简单的API接口;困难是因为我们不了解算法细节,很难去根...

xiaomin0322 ⋅ 今天 ⋅ 0

WampServer默认web服务器根目录位置

安装WampServer之后的web服务器根目录默认位置在WampServer安装目录下的www:

临江仙卜算子 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部