类似于Java,Scala中也有类和对象的概念。

一、类、属性和方法

1、类

  类是对一类事物的抽象,当一个类被定义后,就可以以该定义为模板,定义该类的一系列对象。比如说有以下一个模板

人类:
有姓名;
有一个大脑;
有四肢;
有性别;
会思考;
有语言能力;

  上面这个模板可以认为是对正常人类的一个最简单的抽象,那么有两个人张三和李四,就是人类这一模板的具体实例了。

  在Scala中,用class关键字定义一个类,用new关键字实例化该类的一个对象。一个简单的类定义和实例化如下所示

class ChecksumAccumulator {
// 具体定义代码省略
} new ChecksumAccumulator

  在上面代码中省略的部分可以写入一些该类的属性和方法。所谓属性是指该类的一些特性,比如上面例子中的姓名,性别等,都可以认为是人类的一个属性。而方法是指该类可以执行的一些逻辑片段,比如上面例子中定义人类的走路方式为站立行走,那么正常的两个人类张三和李四的行走方式都是站立行走了。

  有关类的属性和方法,接下来再进行分析。

2、属性

  属性可以用var和val来定义,比如

  

class ChecksumAccumulator {
var sum = 0
}

  那么,使用下面代码new出两个对象  

val acc = new ChecksumAccumulator
val csa = new ChecksumAccumulator

  acc和csa都有一个属性sum。并且值都是0。如下图所示,前面两个圆圈表示acc和csa对象的具体存储,指向同一个0是由于0在常量池中只有一个。

  

  执行acc.sum=3可以将acc的sum属性更新为3,那么现在的情况是这样的

  

  

  从这里可以看出,虽然acc是以val来定义的,但是可以修改其中的属性值。定义为val的作用是,如果将acc指向另一个ChecksumAccumulator对象时就会报错了。一般来说,最好将属性定义为private类型,private类型的属性,只能由该类中的方法进行访问和修改,尽量避免外部代码直接修改对象的属性值。如果需要属性发生变化,可以通过方法来实现。

3、方法

  方法以def开头,里面包含了一段可执行的代码片段。这里需要注意的是,方法的参数是val类型的,如果在代码中更改参数值,是会报错的。 

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

  上面代码中定义了两个方法,根据这两个方法的定义,可以进行一定的简化,

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

  上一篇博客中提到过,返回值为Unit的语句,会产生side effects。这里add方法的side effects是改变了sum变量的值。side effects产生的影响,要么是改变了某个mutable变量的值,要么是产生了一些I/O,这些并不会影响其他代码的执行。

  对于这种返回值为Unit的方法,可以去掉前面的Unit =部分,将函数体用花括号包起来。

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

  上面代码中add方法的写法,即使其执行逻辑的返回值不为Unit,这种写法也显示的将该方法返回值设置为Unit了。

二、语句划分

  不知道有没有发现在上面的代码中并不像Java代码那样,每一句代码的结尾用分号进行分割。在Scala中每一行语句的结尾并不需要写一个分号,一般情况下,以换行作为默认的分隔符。只有当一行中写多句代码时,代码之间才需要以分号进行分隔。

val s = "hello"; println(s)

  Scala默认换行为代码直接的分隔符,

x
+ y

会被认为是两行代码,x和+ y。但是如果确实同一句代码需要换行应该怎么办?可以用圆括号将同一句代码包围起来,在圆括号中可以使用换行。

(x
+ y)

其实就是x + y的换行形式。

三、单例对象

  虽然Scala是函数式编程语言,但是说到面向对象,其实Scala比Java还严格。在Java中,一个类还可以有一些静态属性或者静态方法,这样在不new一个对象时,也可以使用其中很多的静态属性和方法。但是Scala没有静态属性和方法一说,任何属性和方法的使用,都是通过对象来进行的。

  如果确实需要在Scala中直接使用类名调用属性和方法应该怎么做?Scala通过提供一种单例对象,或者说伴生对象巧妙的实现了这一功能。前面我们定义了一个ChecksumAccumulator类,我们用另一个关键字object,同样使用ChecksumAccumularot这个名字,就生成了一个ChecksumAccumulator类的伴生对象了。

import scala.collection.mutable.Map
object ChecksumAccumulator {
private val cache = Map[String, Int]()
def calculate(s: String): Int =
if (cache.contains(s))
cache(s)
else {
val acc = new ChecksumAccumulator
for (c <- s)
acc.add(c.toByte)
val cs = acc.checksum()
cache += (s -> cs)
cs
}
}

接下来我们就可以使用ChecksumAccumulator.calculate直接进行计算了。从字面上看,和Java中调用静态方法是一样的。

  上面的ChecksumAccumulator对象称为ChecksumAccumulator类的伴生对象,ChecksumAccumulator类称为ChecksumAccumulator对象的伴生类。伴生对象和伴生类,需要写在同一个源文件中,并且伴生类和伴生对象之间可以互相访问对方的private成员。

四、代码运行的入口

  在Java中,一个Application是以某个Class中的public static void main(String[] args)的方法开始的。想要运行一段Scala代码,需要定义一个单例对象,并且在该单例对象中写一个main方法,这个方法接收的参数是一个String类型数组,返回值类型为Unit。

import ChecksumAccumulator.calculate
object Summer {
def main(args: Array[String]) {
for (arg <- args)
println(arg +": "+ calculate(arg))
}
}

  一个object中的main方法,是一个Application的入口。类似于java中的main方法。

  

  不过Scala也提供了一个名为Application的trait,可以简单的把trait理解成Java中的接口。如果object继承自该trait的话,那么不需要main方法也能运行起来。把原来需要写在main方法中的代码,直接写在随后的花括号中。

import ChecksumAccumulator.calculate
object FallWinterSpringSummer extends Application {
for (season <- List("fall", "winter", "spring"))
println(season + " : " + calculate(season))
}

这段代码之所以能够运行,从Application中可以看到,这里面已经实现了一个main方法。上面写的这些代码,在这个类被初始化时由主构造方法执行。

Programming In Scala笔记-第四章、类和对象的更多相关文章

  1. Programming In Scala笔记-第六章、函数式对象

    这一章主要是以定义和完善一个有理数类Rational为线索,分析和介绍有关类定义,构造函数,方法重写,变量定义和私有化,以及对操作符的定义等. 一.Rational类定义和构造函数 1.定义一个空类 ...

  2. Programming In Scala笔记-第十一章、Scala中的类继承关系

    本章主要从整体层面了解Scala中的类层级关系. 一.Scala的类层级 在Java中Object类是所有类的最终父类,其他所有类都直接或间接的继承了Object类.在Scala中所有类的最终父类为A ...

  3. java面向对象编程——第四章 类和对象

    OO:面向对象 OOP:面向对象编程 OOA:面向对象分析 OOD:面向对象设计 结构化编程:从顶向下,将一个大问题分解成更小的任务,然后为每一个更小的任务编写一个过程.最后程序员会编写一个主过程来启 ...

  4. Java学习笔记【四、类、对象、接口】

    编程语言的发展 机器语言 过程语言 面向对象编程--封装.继承.多态 关键字 extends implements override overload super this static abstra ...

  5. Programming In Scala笔记-第十七章、Scala中的集合类型

    本章主要介绍Scala中的集合类型,主要包括:Array, ListBuffer, Arraybuffer, Set, Map和Tuple. 一.序列 序列类型的对象中包含多个按顺序排列好的元素,可以 ...

  6. Programming In Scala笔记-第七章、Scala中的控制结构

    所谓的内建控制结构是指编程语言中可以使用的一些代码控制语法,如Scala中的if, while, for, try, match, 以及函数调用等.需要注意的是,Scala几乎所有的内建控制结构都会返 ...

  7. Programming In Scala笔记-第五章、Scala中的变量类型和操作

    这一章的一些基础性的东西,主要包括Scala中的基本变量类型,以及相关的一些操作符. 一.简单类型 下表中列出Scala语言中的基本类型,以及其字节长度,其中Byte, Short, Int, Lon ...

  8. The C++ Programming Language 学习笔记 第四章 类型和声明

    1.关于main 函数中的 return 0 C99标准中,main 函数的返回值类型必须是 int ,这样返回值才能传递给程序的激活者(如操作系统).如果 main 函数的最后没有写 return ...

  9. scala编程(四)——类和对象

     类,字段和方法 在scala里定义一个典型的类,代码如下: class ChecksumAccumulator { private var sum = 0 def add(b: Byte): Uni ...

随机推荐

  1. WPF Command

    使用CustomControl时绑定Command用法 C# Part public static RoutedUICommand ClearCommand { get; private set; } ...

  2. 开发一个成功APP的六个技巧

    越来越多的人开始使用智能手机,平板电脑或其他的移动设备.出于这个原因,移动APP开发已成为当今软件开发中增长最快的领域之一.本文提供九个简单而有效的提示,可帮助您规划和实施成功的移动APP. 1.目标 ...

  3. Oracle服务启动项

    七个服务的含义分别为: 1. Oracle ORCL VSS Writer Service: Oracle卷映射拷贝写入服务,VSS(Volume Shadow Copy Service)能够让存储基 ...

  4. MyBatis(2)——MyBatis 深入学习

    编写日志输出环境配置文件 在开发过程中,最重要的就是在控制台查看程序输出的日志信息,在这里我们选择使用 log4j 工具来输出: 准备工作: 将[MyBatis]文件夹下[lib]中的 log4j 开 ...

  5. [HNOI 2016]树

    Description 题库链接 给你一棵 \(N\) 个节点根节点为 \(1\) 的有根树,结点的编号为 \(1\sim N\) :我们称这颗树为模板树.需要通过这棵模板树来构建一颗大树.构建过程如 ...

  6. [HAOI2007]覆盖问题

    题目描述 某人在山上种了N棵小树苗.冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄膜把这些小树遮盖起来,经过一番长久的思考,他决定 用3个L*L的正方形塑料薄膜将小树遮起来.我 ...

  7. UVA12186

    给出一个树状关系图,公司里只有一个老板编号为0,其他人员从1开始编号.除了老板,每个人都有一个直接上司,没有下属的员工成为工人. 工人们想写一份加工资的请愿书,只有当不少于员工的所有下属的T%人递交请 ...

  8. SpringCloud学习之soa基础

    一.soa简单介绍 1)面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来.SOA是解决复杂业务模块,提高扩展性,维护性,可伸缩 ...

  9. HTTPS介绍

    超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂 ...

  10. Triangle(动态规划)

    题目描述 Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjac ...