Scala:类,对象和特征(接口)
http://blog.csdn.net/pipisorry/article/details/52902609
Scala类和对象
类是对象的抽象,而对象是类的具体实例。类是抽象的,不占用内存,而对象是具体的,占用存储空间。类是用于创建对象的蓝图,它是一个定义包括在特定类型的对象中的方法和变量的软件模板。
类的创建和实例化
class Point(xc: Int, yc: Int) { var x: Int = xc var y: Int = yc def move(dx: Int, dy: Int) { x = x + dx y = y + dy println ("x 的坐标点: " + x); println ("y 的坐标点: " + y); } }
Scala中的类不声明为public,一个Scala源文件中可以有多个类。
以上实例的类定义了两个变量 x 和 y ,一个方法:move,方法没有返回值。
Scala 的类定义可以有参数,称为类参数,如上面的 xc, yc,类参数在整个类中都可以访问。
接着我们可以使用 new 来实例化类,并访问类中的方法和变量:
import java.io._ class Point(xc: Int, yc: Int) { var x: Int = xc var y: Int = yc def move(dx: Int, dy: Int) { x = x + dx y = y + dy println ("x 的坐标点: " + x); println ("y 的坐标点: " + y); } } object Test { def main(args: Array[String]) { val pt = new Point(10, 20); // 移到一个新的位置 pt.move(10, 10); } }
实例的默认参数
def this() = this(x = 1, y = 2)
Scala 继承
Scala继承一个基类跟Java很相似, 但我们需要注意一下几点:
- 1、重写一个非抽象方法必须使用override修饰符。
- 2、只有主构造函数才可以往基类的构造函数里写参数。
- 3、在子类中重写超类的抽象方法时,你不需要使用override关键字。
继承会继承父类的所有属性和方法,Scala 只允许继承一个父类。
Scala重写一个非抽象方法,必须用override修饰符。
实例:
class Point(xc: Int, yc: Int) { var x: Int = xc var y: Int = yc def move(dx: Int, dy: Int) { x = x + dx y = y + dy println ("x 的坐标点: " + x); println ("y 的坐标点: " + y); } } class Location(override val xc: Int, override val yc: Int, val zc :Int) extends Point(xc, yc){ var z: Int = zc def move(dx: Int, dy: Int, dz: Int) { x = x + dx y = y + dy z = z + dz println ("x 的坐标点 : " + x); println ("y 的坐标点 : " + y); println ("z 的坐标点 : " + z); } }
Scala 使用 extends 关键字来继承一个类。实例中 Location 类继承了 Point 类。Point 称为父类(基类),Location 称为子类。
override val xc 为重写了父类的字段。
Scala单例对象与伴生对象
Scala的单例对象
Scala没有 static 这个东西,不能定义静态成员,而是代之定义单例对象(singleton object)。以object关键字定义。
对象定义了某个类的单个实例,包含了你想要的特性:
object Accounts{
private var lastNumber = 0
def newUniqueNumber() = { lastNumber += 1; lastNumber}
}
当你在应用程序中需要一个新的唯一账号时,调用Account.newUniqueNumber()即可。
对象的构造器在该对象第一次被使用时调用。
在下面几个场景下可以使用Scala单例对象:
- 作为存放工具函数或常量的地方
- 高效地共享单个不可变实例
- 需要使用单个实例来协调某个服务时
类和单例对象间的差别是,单例对象不带参数,而类可以。因为单例对象不是用new关键字实例化的,所以没机会传递给它实例化参数。每个单例对象都被实现为虚拟类(synthetic class)的实例,并指向静态的变量,因为它们与Java静态类有相同的初始化语义。
独立对象(standalone object)
不与伴生类共享名称的单例对象称为独立对象。它可以用在很多地方,例如作为相关功能方法的工具类,或者定义Scala应用的入口点。
伴生对象(companion object)
当单例对象与某个类共享同一个名称时,它就被称为是这个类的伴生对象(companion object)。类和它的伴生对象必须定义在同一个源文件中。类被称为是这个单例对象的伴生类(companion class)。类和它的伴生对象可以互相访问其私有成员。
|
|
注意:
- 类的伴生对象可以被访问,但并不在作用域当中。Account类必须通过Account.newUniqueNumber()来调用伴生对象的方法。
- 在REPL中,要同时定义类和对象,必须用粘贴模式。键入
:paste
,然后键入或粘贴类和对象的定义,最后一Ctrl+D退出粘贴模式。
将伴生对象作为工厂使用
我们通常将伴生对象作为工厂使用。
下面是一个简单的例子,可以不需要使用’new’来创建一个实例了。
|
|
单例对象实例
import java.io._ class Point(val xc: Int, val yc: Int) { var x: Int = xc var y: Int = yc def move(dx: Int, dy: Int) { x = x + dx y = y + dy } } object Test { def main(args: Array[String]) { val point = new Point(10, 20) printPoint def printPoint{ println ("x 的坐标点 : " + point.x); println ("y 的坐标点 : " + point.y); } } }
伴生对象实例
/* 文件名:Marker.scala */ // 私有构造方法 class Marker private(val color:String) { println("创建" + this) override def toString(): String = "颜色标记:"+ color } // 伴生对象,与类共享名字,可以访问类的私有属性和方法 object Marker{ private val markers: Map[String, Marker] = Map( //一调用这个函数,就会创建3个class Marker "red" -> new Marker("red"), "blue" -> new Marker("blue"), "green" -> new Marker("green") ) def apply(color:String) = { if(markers.contains(color)) markers(color) else null } def getMarker(color:String) = { if(markers.contains(color)) markers(color) else null } def main(args: Array[String]) { println(Marker("red")) //println会调用object Marker的toString函数,伴生对象就直接调用class Marker的toString函数了。 // 单例函数调用,省略了.(点)符号 println(Marker getMarker "blue") } }$ scalac Marker.scala $ scala Marker 创建颜色标记:red 创建颜色标记:blue 创建颜色标记:green 颜色标记:red 颜色标记:blue
Scala Trait(特征)
Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。
与接口不同的是,它还可以定义属性和方法的实现。
一般情况下Scala的类只能够继承单一父类,但是如果是 Trait(特征) 的话就可以继承多个,从结果来看就是实现了多重继承。
Trait(特征) 定义的方式与类类似,但它使用的关键字是 trait,如下所示:
trait Equal { def isEqual(x: Any): Boolean def isNotEqual(x: Any): Boolean = !isEqual(x) }
以上Trait(特征)由两个方法组成:isEqual 和 isNotEqual。isEqual 方法没有定义方法的实现,isNotEqual定义了方法的实现。子类继承特征可以实现未被实现的方法。所以其实 Scala Trait(特征)更像 Java 的抽象类。
特征构造顺序
特征也可以有构造器,由字段的初始化和其他特征体中的语句构成。这些语句在任何混入该特征的对象在构造是都会被执行。
构造器的执行顺序:
- 调用超类的构造器;
- 特征构造器在超类构造器之后、类构造器之前执行;
- 特质由左到右被构造;
- 每个特征当中,父特质先被构造;
- 如果多个特征共有一个父特质,父特质不会被重复构造
- 所有特征被构造完毕,子类被构造。
构造器的顺序是类的线性化的反向。线性化是描述某个类型的所有超类型的一种技术规格。
from: http://blog.csdn.net/pipisorry/article/details/52902609
ref:
Scala:类,对象和特征(接口)的更多相关文章
- 将Model实体类对象作为WebService接口参数(转)
转自:http://www.cnblogs.com/fengyishou/archive/2009/02/27/1399281.html 关于web服务的有关基础知识,看了基本书,但是不敢在这里乱说, ...
- spark快速开发之scala基础之3类,对象,特征
类 scala的类定义非常灵活 class test4 class test2{} class test3(x:Int) 定义一个带构造函数的类 class Point (x : Int,y : In ...
- Scala类与对象
类简介 简介 类是对象的蓝图.一旦你定义了类,就可以用关键字new根据类的蓝图创建对象.在类的定义里,可以放置字段和方法,这些被笼统地称为成员.对于字段,不管是val还是var定义的,都是指向对象的变 ...
- Spark记录-Scala类和对象
本章将介绍如何在Scala编程中使用类和对象.类是对象的蓝图(或叫模板).定义一个类后,可以使用关键字new来创建一个类的对象. 通过对象可以使用定义的类的所有功能. 下面的图通过一个包含成员变量(n ...
- Scala学习——类,继承,接口(中)
基本类的使用:(初) package com.dtspark.scala.basics /** * trait是一个接口 * 接口的第一次继承用extends,多继承时用with * 多继承时,如果这 ...
- Scala类和对象(二)
1. 类和属性 1.1 如何控制构造函数字段的可见性 在Scala中: 如果一个字段被声明为var, Scala会为该字段生成getter和setter方法. 如果字段是val, Scala只生成ge ...
- Java中的对象、类、抽象类、接口的理解
1.对象 对象是个具体的东西,有着明确的属性特征和行为特征. 例如:你手上牵着的女朋友或男朋友就是个具体的对象. 如图中的苏格兰折耳猫,特征是耳朵向下呈折叠状,有着具体的颜色(你看到的颜色),并且和其 ...
- 【无私分享:ASP.NET CORE 项目实战(第二章)】添加EF上下文对象,添加接口、实现类以及无处不在的依赖注入(DI)
目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 上一章,我们介绍了安装和新建控制器.视图,这一章我们来创建个数据模型,并且添加接口和实现类. 添加EF上下文对象 按照我们以前 ...
- 规则引擎集成接口(九)Java类对象
Java类对象 右键点击“对象库” —“添加java类对象”,如下图: 弹出窗体,在文本框中输入类的全名“com.flagleader.test.Test”,选择该类型后确定,如下: 显示如下,勾选上 ...
随机推荐
- [LeetCode] Next Greater Element III 下一个较大的元素之三
Given a positive 32-bit integer n, you need to find the smallest 32-bit integer which has exactly th ...
- spring初学总结思路
spring初步学习总结 总概括有四个方面:IOC,AOP,JDBC,和事务管理 ioc:实现了new类的一个权力的反转.(平时new类导致代码冗余,手动new类无法满足动态new类的需求) aop: ...
- LeetCode题目----求中位数---标签:Array
题目难度---困难 题目要求: 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 . 请找出这两个有序数组的中位数.要求算法的时间复杂度为 O(log (m+n)) . 思路:第一眼 ...
- dnslog搭建
为什么想重写这个呢,想说后面扫描ssrf和命令执行的时候,能快速改成自己想要的api,更容易修改一些. 工具改自:https://github.com/bugScanTeam/DNSLog 需要两个域 ...
- codevs 2964 公共素数因数
提交地址:http://codevs.cn/problem/2964/ 2964 公共素数因数 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 白银 Silver 题解 ...
- 洛谷P2042 [NOI2005]维护数列
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #in ...
- hdu 5465 (树状数组 + 博弈)
题意:基于矩阵的NIM游戏,求异或和. 思路:在x1,y1 到 x2, y2的异或和 = A[ x2 ][ y2 ] ^ A[x1-1][ y2 ] ^ A[ x2 ][y1 - 1] ^ A[ x ...
- python中读取文件数据时要注意文件路径
我们在用python进行数据处理时往往需要将文件中的数据取出来做一些处理,这时我们应该注意数据文件的路径.文件路径不对,回报如下错误: FileNotFoundError: File b'..Adve ...
- sprintf()、fprintf()、fscanf()的用法
sprintf函数的用法1.该函数包含在stdio.h的头文件中. 2.sprintf和平时我们常用的printf函数的功能很相似.sprintf函数打印到字符串中,而printf函数打印输出到屏幕上 ...
- SQL使用总结-like,MAX,MIN
1. 时间索引不容许使用like 对时间索引适应like,会时间索引变成字符串操作,成为遍历动作,失去索引价值. 错误写法: EXPLAIN SELECT AVG(data_value) AS av ...