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”,选择该类型后确定,如下: 显示如下,勾选上 ...
随机推荐
- vue-cli 体验
vue-cli 是一个官方发布 vue.js 项目脚手架,使用 vue-cli 可以快速创建 vue 项目,GitHub地址是:https://github.com/vuejs/vue-cli 一. ...
- C#之不安全代码
MSDN:"尽管实际上对 C 或 C++ 中的每种指针类型构造,C# 都设置了与之对应的引用类型,但仍然会有一些场合需要访问指针类型.例如,当需要与基础操作系统进行交互.访问内存映射设备,或 ...
- [WC2006]水管局长数据加强版
Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一 ...
- 计蒜客模拟赛5 D2T1 成绩统计
又到了一年一度的新生入学季了,清华和北大的计算机系同学都参加了同一场开学考试(因为两校兄弟情谊深厚嘛,来一场联考还是很正常的). 不幸的是,正当老师要统计大家的成绩时,世界上的所有计算机全部瘫痪了. ...
- ●CodeForce 293E Close Vertices
题链: http://codeforces.com/contest/293/problem/E题解: 点分治,树状数组 大致思路和 POJ 1741 那道点分治入门题相同, 只是因为多了一个路径的边数 ...
- [BZOJ]1071 组队(SCOI2007)
一道比较NB的套路题. Description NBA每年都有球员选秀环节.通常用速度和身高两项数据来衡量一个篮球运动员的基本素质.假如一支球队里速度最慢的球员速度为minV,身高最矮的球员高度为mi ...
- bzoj 4033: [HAOI2015]树上染色
Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并 将其他的N-K个点染成白色.将所有点染色后,你会获得黑点两两之间的距 ...
- [BZOJ]1005 明明的烦恼(HNOI2008)
BZOJ的第一页果然还是很多裸题啊,小C陆续划水屯些板子. Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间 ...
- Thinkphp中的 I 函数(Thinkphp3.2.3版本)
I 函数的作用是获取系统变量,必要时还可以对变量值进行过滤及强制转化,I 函数的语法格式: I('变量类型.变量名/修饰符',['默认值'],['过滤方法或正则'],['额外数据源']) 一.获取变量 ...
- Jenkins简明入门(二) -- 利用Jenkins完成Python程序的build、test、deployment
大家可能还没搞清楚,Jenkins到底能做什么? 本节内容利用Jenkins完成python程序的build.test.deployment,让大家对Jenkins能做的事情有一个直观的了解. 本节内 ...