《Scala By Examples》第6章 类和对象
先定义了一个“有理数”(rational)类:
package ch6_classes_and_objects/*** 以Class的形式定义一个有理数的类型*/ class Rational(n : Int , d : Int) {/*** 求公约数*/private def gcd( x : Int , y : Int) : Int = {if ( x == 0 ) y else if ( x < 0 ) gcd ( -x , y )else if ( y < 0 ) -gcd ( x , -y)else gcd ( y % x , x) }private val g = gcd ( n , d) // 分子,分母的最大公约数 val number : Int = n / g val denom : Int = d / gdef +(that : Rational) = new Rational(number * that.denom + that.number * denom , denom * that.denom)def -(that : Rational) = new Rational(number * that.denom - that.number * denom , denom * that.denom)}
私有成员:这个类里定义一个私有方法:gcd,用来计算最大公约数。还有一个私有成员g ,用来持有构造参数(n , d)的最大公约数。这些变量在Rational类外部是不能访问到的。这些是用来保证分子(numerator)和分母(denominator)在一个正常的格式里。
创建和访问对象:以下的例子用来展示如何使用这个类的:
var i = 1 var x = new Rational(0 , 1) while(i < = 10){x += new Rational(1 , i )i += 1 } println("" + x.number + "/" + x.denom)
继承(Inheritance)和重写(Overriding):Scala里每个类都有一个超类(superClass)。如果没有明写出来,默认就是继承自scala.AnyRef类。一个类会继承父类所有的成员,当然,它也可以再重写(override)它们。比如toString方法。不过要注意的是,跟Java不同的是,Scala里,重定义的要在变量要在前面加上一个override标识符。
与Java里的继承一样,如果A类继承自B类,那么A可以用在所在需要B类型的地方。说类型A遵从(conform to)类型B。也即如下正确:
var x : AnyRef = new Rational(1 , 2)
省略参数的方法(Parameterless Methods):不像Java,Scala里的方法不一定要带参数列表。如下面的square方法:
def square = new Rational(number * number , denom * denom)val r = new Rational(3 , 4) println(r.square)
也就是说,无参的方法可以像值参数一样的访问。值和无参方法间的不同就是在于它们的定义。val的右侧值在对象被创建时就被计算出来,并且不再变换。而无参方法右侧的值只是在每次被调用的时候再进行计算。这种对属性和无参方法进行统一访问的方式使类实现变得可扩展。通常,一个版本中的一个属性会在下个版本中变成计算得到的值。统一访问保证了客户端不会因这种变化而重写。
抽象类:
abstract class IntSet{def incl(x : Int) : IntSetdef contains(x : Int) : Boolean }
IntSet这个类被标记为abstract class . 它有两个结果。首先,抽象类可能有声明的(declared)但没有实现的委托(deferred)成员。在上面这个例子里,incl和contains就是这样的成员。其次,因为一个抽象类可能有未实现的成员,所以不能用new 来创建一个这个类的对象。相反地,抽象类可以用来作为其他类的基本类(base class ),这些子类要实现这个委托成员(deferred members)。
特质(trait):与abstract class 类似的,在Scala里也可以用关键字trait 来表示。特质是用来被加到其他类里的抽象类。另一个应用场景,就像Java里的接口(interface)一样,用来收集一些不同类中的通用功能。也可以如下定义上面的IntSet类
trait IntSet{def incl(x : Int) : IntSetdef contains(x : Int) : Boolean }
实现抽象类:现在我们打算用二叉树来实现集合。有两种可能性,一种树是空集合(empty set),另一种是由一个整数和两个子树组成。以下是实现的代码:
EmptySet:
class EmptySet extends IntSet {def incl(x: Int): IntSet = { null }def contains(x: Int): Boolean = false }
NonEmptySet:
class NonEmptySet( elem : Int , left : IntSet , right : IntSet) extends IntSet {def incl(x: Int): IntSet = if ( x < elem) new NonEmptySet(elem , left incl(x) , right)else if ( x > elem ) new NonEmptySet(elem , left , right incl(x))else thisdef contains(x: Int): Boolean = if ( x < elem) left contains x else if ( x > elem ) right contains xelse true }
两个类都是继承自IntSet,所以都可以用在所在需要IntSet类型的地方。
动态绑定(dynamic binding):面向对象的语言都是用动态发送(dynamic dispatch)的方式给方法的调用。即调用一个方法依赖于包含这个方法的对象的运行进类型(run-time type)。(可以理解成类似于多态的意思?)Scala把所有的函数都当成对象来对待。
对象(objects):在之前的代码里,用表达式:new EmptySet 来创建了一个EmptySet的对象,所以,可以在任何需要空集合的时候通过这种方式来创建一个空集合。例如:
val EmptySetVal = new EmptySet
来创建一个新的空集合。但有一个问题:这么定义的值不是一个合法的Scala顶级(top-level)定义。因为它必须成为另一个类或对象的某个部分。一个更为直接点的方法,就是用object 来作定义。以下是一个合理化的可选的定义一个空集合对象:
object EmptySet extends IntSet{def contains(x : Int) : Boolean = falsedef incl(x : Int) : IntSet = new NonEmptySet(x , EmptySet , EmptySet) }
因为它可以不用像类一样的使用new 来创建,而是可以直接使用(注:有点类似于Java中的静态类),那这个对象是何时创建的?回答是它其中的一个成员第一次被访问的时候,这个对象就创建出来了。这个策略叫作延迟赋值(lazy evaluation。是不是也可以叫“懒加载”)。
标准类:Scala是一个纯粹的面向对象的语言。意味着Scala里的所有值都可以当成对象。甚至连基本类型int , boolean都没有特殊对待。它们被当成Scala类的简写,被定义在Predef中:
type boolean = scala.Boolean type int = scala.Int type long = scala.Long
(之后给出了标准库中Boolean 对象的定义。略过)。还举例了一个“自然数”的定义。之后再看。
转载于:https://www.cnblogs.com/peterzd/archive/2012/04/11/2440149.html
《Scala By Examples》第6章 类和对象相关推荐
- Kotlin学习笔记 第二章 类与对象 第十二 十三节 对象表达式与对象声明 类型别名
参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...
- Kotlin学习笔记 第二章 类与对象 第三节接口 第四节 函数式接口
参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...
- 第三章类与对象基础 ① 笔记
1. 内容回顾 1.1. 课前测试 1.2. 上节内容 2. 本章重点 2.1. 类和对象的概念 2.2. 类的基本组成 2.3. 构造方法 2.4. 成员方法 3. 具体内容 3.1. 类和对象的概 ...
- java怎么给类中的私有变量赋值_Java核心技术笔记分享------第二章 类与对象
对象与类 一.面向对象思想的概述 1>面向对象与面向过程: 二者都是一种思想,面向对象是相对于面向过程而言的.面向过程强调的是功能行为.面向对象,将功能封装进对象,强调具备了功能的对象. 面向对 ...
- Python程序开发——第六章 类与对象
目录 一.类 (一)类.对象 (二)类的定义 (三)对象的创建和使用 二.限制对象访问 (一)定义私有成员.方法 (二)访问私有成员.方法 三.构造方法和析构方法 (一)构造方法 (二)析构方法 四. ...
- 第四章类和对象 习题答案
一.选择题1.能提供封装的C++的下列关键字是(C)A.whileB. unionC. classD. for2.在下面所列项中,不是面向对象的特点的是(C)A. 多面性B. 抽象性和封装性C. 多线 ...
- JAVA入门第二季 第一章 类和对象
面向对象编程 Object Oriented Programming OOP 第一.什么是类和对象 在具体说明类和对象之前,先说说别的. 眼睛在人类身体上最为有用的器官.如果一个没有了眼睛,这个人与世 ...
- C++语言程序设计——知识点复盘(第四章 类与对象)
目录 面向对象程序设计的基本特点 1.抽象 2.封装 3.继承 4.多态 类和对象 类的成员函数 1.成员函数的实现 2.目的对象. 3.带默认形参值的成员函数 4.内联成员函数 构造函数 析构函数 ...
- 第四章——类和对象(一)
c++面向对象的三大特性:封装.继承.多态 4.1封装 4.1.1封装的意义 封装的意义 将属性和行为作为一个整体,表现生活中的事物 将属性和行为加以权限控制 封装意义一: 在设计类的时候,属性和行为 ...
最新文章
- Linux基础知识题解答(一)
- nginx 官方手册 php,nginx + php 的配置
- caffe训练输入数据格式介绍(LMDB/imagelist)
- QT每日一练day28:QT中的2D绘图知识概念——讲义截图
- 检验密码强度的JS类(from thin's blog)
- 票据的生命周期与人的灵魂
- 【实战】NLP命名实体识别开源实战教程
- Python学习之面向对象(一)
- iPad mini2 Vieux降级ios10.3.3 问题解决合集
- 远程计算机桌面图标不见了怎么办,远程桌面图标不见了怎么办
- gorm中使用where in 条件
- 小的以及大的Typhon IDE
- 安全日志分析的五种类型
- python4delphi和tesserocr库安装配置
- 优秀广告设计作品常用的几大设计思维
- guido正式对外发布python版本的年份_Guido van Rossum正式对外发布Python版本的年份是:______。...
- 通过Docker容器搭建私有网盘(NextCloud)
- 蓝牙路由器蓝牙点对多点组网蓝牙远程控制
- 王者荣耀刷金币脚本,买英雄你还愁么?
- Concept Whitening for interpretable image recognition 用于可解释图像识别的概念白化
热门文章
- LeetCode Construct Binary Tree from Inorder and Postorder Traversal
- Spring boot 梳理 - 在bean中使用命令行参数-自动装配ApplicationArguments
- [luogu2576 SCOI2010] 幸运数字 (容斥原理)
- Partition List
- bzoj1013球形空间
- ajax实现文件上传,多文件上传,追加参数
- 前序,中序,后序遍历
- E: Could not get lock /var/lib/dpkg/lock解决
- CAShapeLayer和CAGradientLayer
- C# 获取字符串长度 获取字符串字节长度