Scala - 快速学习06 - 面向对象
1- 类
1.1- 简介:类、方法及对象
- 字段默认为public,在类外部和内部都可以访问该字段。
- 私有字段使用private关键字修饰,外界无法访问,只有在类内部可以访问该字段。
- 通过def关键字实现方法的定义
- 方法的返回值:方法里面的最后一个表达式的值就是方法的返回值,不需要靠return语句。
- 如果方法不返回任何值,返回值的类型就为Unit。
- 如果包含方法具体操作语句的大括号里面只有一行语句,可以省略大括号。
package testscala object TestScala {
def main(args: Array[String]) {
println("Testing, Scala!") val myTest1 = new myCounter
myTest1.increment()
// myTest1.increment // 调用无参方法时,可以省略方法名后面的圆括号
println(myTest1.current) val myTest2 = new myCounter2
myTest2.increment(5)
println(myTest2.current)
} } class myCounter {
private var value = 0
def increment(): Unit = { value += 1 }
// def increment(): Unit = value += 1 // 大括号里面只有一行语句,可以省略大括号
def current(): Int = { value }
} class myCounter2 {
private var value = 0
def increment(step: Int): Unit = { value += step }
def current(): Int = { value }
}
1.2- 定义类似getter和setter的方法
package testscala object TestScala {
def main(args: Array[String]) {
println("Testing, Scala!") val myTest3 = new myCounter3
println(myTest3.value)
myTest3.value = 3
println(myTest3.value)
myTest3.increment(1)
println(myTest3.current) val myTest4 = new myCounter4
println(myTest4.value)
myTest4.value = 3
println(myTest4.value)
myTest4.increment(1)
println(myTest4.current)
}
} class myCounter3 {
var value = 0 // 变量默认为public,对外部可见
def increment(step: Int): Unit = { value += step }
def current(): Int = { value }
} class myCounter4 {
private var privateValue = 0 // 变量为private,私有字段
def value = privateValue
def value_=(newValue: Int) {
if (newValue > 0) privateValue = newValue // 新值为正数才可以修改
}
def increment(step: Int): Unit = { value += step }
def current(): Int = { value }
}
1.3- 构造器
package helloscala object helloscala {
def main(args: Array[String]) {
println("Testing, Scala!") val myTest5 = new myCounter5("Timer", 2)
myTest5.info
myTest5.increment(1)
printf("Current Value is: %d\n", myTest5.current)
}
} class myCounter5(val name: String, val mode: Int) {
private var value = 0
def increment(step: Int): Unit = { value += step }
def current(): Int = { value }
def info(): Unit = { printf("Name:%s and mode is %d \n", name, mode) }
}
package helloscala object helloscala {
def main(args: Array[String]) {
println("Testing, Scala!") val myTest6 = new myCounter6
myTest6.info
myTest6.increment(1)
printf("Current Value is: %d\n", myTest6.current) val myTest62 = new myCounter6("Runner")
myTest62.info
myTest62.increment(2)
printf("Current Value is: %d\n", myTest62.current) val myTest63 = new myCounter6("Timer", 2)
myTest63.info
myTest63.increment(3)
printf("Current Value is: %d\n", myTest63.current)
}
} class myCounter6 {
private var value = 0
private var name = ""
private var mode = 1
def this(name: String) {
this()
this.name = name
}
def this(name: String, mode: Int) {
this(name)
this.mode = mode
}
def increment(step: Int): Unit = { value += step }
def current(): Int = { value }
def info(): Unit = { printf("Name:%s and mode is %d \n", name, mode) }
}
2- 面向对象-对象
2.1- 单例对象
package helloscala object helloscala {
def main(args: Array[String]) {
println("Testing, Scala!")
printf("The first person id is %d.\n", Person.newPersonId())
printf("The second person id is %d.\n", Person.newPersonId())
printf("The third person id is %d.\n", Person.newPersonId())
}
} object Person {
private var lastId = 0
def newPersonId() = {
lastId += 1
lastId
}
}
2.2- 伴生对象
package testscala object TestScala { // 单例对象与某个类具有相同的名称,称为这个类的伴生对象 private var lastId = 0
private def newPersonId() = {
lastId += 1
lastId
} def main(args: Array[String]) {
println("Testing, Scala!")
val person1 = new TestScala("AAA")
val person2 = new TestScala("BBB")
person1.info()
person2.info()
}
} class TestScala {
private val id = TestScala.newPersonId() //调用伴生对象中的方法
private var name = "" def this(name: String) {
this()
this.name = name
} def info() { printf("The id of %s is %d.\n", name, id) }
}
2.3- 应用程序对象
guowli@5CG450158J MINGW64 /d/Anliven-Running/Zen/ScalaProjets/temptest
$ ls -l
total 1
-rw-r--r-- 1 guowli 1049089 88 Nov 21 11:31 test.scala guowli@5CG450158J MINGW64 /d/Anliven-Running/Zen/ScalaProjets/temptest
$ cat test.scala
object HelloWorld {
def main(args: Array[String]){
println("Hello, World!")
}
} guowli@5CG450158J MINGW64 /d/Anliven-Running/Zen/ScalaProjets/temptest
$ scala test.scala
Hello, World! guowli@5CG450158J MINGW64 /d/Anliven-Running/Zen/ScalaProjets/temptest
$ ls -l
total 1
-rw-r--r-- 1 guowli 1049089 88 Nov 21 11:31 test.scala guowli@5CG450158J MINGW64 /d/Anliven-Running/Zen/ScalaProjets/temptest
$
第二种方法:先编译再执行
guowli@5CG450158J MINGW64 /d/Anliven-Running/Zen/ScalaProjets/temptest
$ scalac test.scala guowli@5CG450158J MINGW64 /d/Anliven-Running/Zen/ScalaProjets/temptest
$ ls -l
total 3
-rw-r--r-- 1 guowli 1049089 665 Nov 21 11:33 'HelloWorld$.class'
-rw-r--r-- 1 guowli 1049089 602 Nov 21 11:33 HelloWorld.class
-rw-r--r-- 1 guowli 1049089 88 Nov 21 11:31 test.scala guowli@5CG450158J MINGW64 /d/Anliven-Running/Zen/ScalaProjets/temptest
$ scala -classpath . HelloWorld
Hello, World! guowli@5CG450158J MINGW64 /d/Anliven-Running/Zen/ScalaProjets/temptest
$
2.4- apply方法和update方法
package testscala object TestScala {
def main(args: Array[String]) {
println("Testing, Scala!")
val myObject = new TestApplyClass
println(myObject("param1")) // 执行myObject("param1")时调用了apply方法
}
} class TestApplyClass {
def apply(param: String): String = {
println("apply method called, parameter is: " + param)
"Hello World!" // apply方法的返回值
}
}
单例对象中定义apply方法:
package testscala object TestScala { def main(args: Array[String]) {
println("Testing, Scala!")
val group = TestScala("AAA", "BBB") // 调用了apply方法,获得返回值并赋值给变量
println(group)
} def apply(param1: String, param2: String): String = {
println("apply method called")
param1 + " and " + param2 // 方法的返回值
} }
伴生类和伴生对象中的apply方法:
package testscala object TestScala {
def main(args: Array[String]) {
val a = ApplyTest() // 调用伴生对象中的apply方法并返回该方法调用的值
a.greetingOfClass
a() // 调用伴生类中的apply方法
}
} object ApplyTest {
def apply() = {
println("apply method in object is called")
new ApplyTest() // 返回ApplyTest类的实例化对象
}
} class TestScala {
} class ApplyTest {
def apply() = println("apply method in class is called!")
def greetingOfClass: Unit = {
println("Greeting method in class is called.")
}
}
示例:apply方法
val myStrArr = Array("AAA", "BBB", "CCC") //> myStrArr : Array[String] = Array(AAA, BBB, CCC)
package testscala object TestScala {
def main(args: Array[String]) {
val mycar = Car("BMW") // 调用伴生对象中的apply方法创建一个Car类的实例化对象
mycar.info()
}
} class Car(name: String) {
def info() { println("Car name is " + name) }
} object Car {
def apply(name: String) = new Car(name) // 调用伴生类Car的构造方法创建一个Car类的实例化对象
}
val myStrArr = new Array[String](3) //> myStrArr : Array[String] = Array(null, null, null)
myStrArr(0) = "AAA" //实际调用了伴生类Array中的update方法,执行myStrArr.update(0,"AAA")
myStrArr(1) = "BBB" //实际调用了伴生类Array中的update方法,执行myStrArr.update(1,"BBB")
myStrArr.update(2, "CCC") // 执行myStrArr.update(2,"CCC")
for (x <- myStrArr) println(x) //> AAA
//| BBB
//| CCC
注意:在进行元组赋值的时候,之所以没有采用Java中的方括号myStrArr[0],而是采用圆括号的形式,myStrArr(0),是因为存在上述的update方法的机制。
3- 面向对象-继承
- 重写一个非抽象方法必须使用override修饰符。
- 只有主构造器可以调用超类的主构造器。
- 在子类中重写超类的抽象方法时,不需要使用override关键字。
- 可以重写超类中的字段。
- 使用关键字abstract定义抽象类
- 抽象类不能直接被实例化,可以被其他类继承
- 定义抽象类中的抽象方法不需要使用abstract关键字,方法体为空
- 抽象类中定义的字段必须声明类型,否则编译会报错;如果字段没有初始化值,就表示是一个抽象字段
package testscala object TestScala {
def main(args: Array[String]) {
val myCar1 = new BMWCar()
val myCar2 = new BenzCar()
myCar1.greeting()
myCar1.info()
myCar2.greeting()
myCar2.info()
}
} abstract class Car { //抽象类
val carBrand: String //抽象字段没有初始化值
def info() //抽象方法,不需要使用abstract关键字,方法体为空
def greeting() { println("Welcome to my car!") } //非抽象方法,方法体内容非空
} class BMWCar extends Car { //扩展类
override val carBrand = "BMW" //重写超类字段,需要使用override关键字,否则编译会报错
def info() { printf("This is a %s car.\n", carBrand) } //重写超类的抽象方法时,可以不使用override关键字
override def greeting() { println("Welcome to my BMW car!") } //重写超类的非抽象方法,必须使用override关键字
} class BenzCar extends Car { //扩展类
override val carBrand = "Benz"
def info() { printf("This is a %s car.\n", carBrand) }
override def greeting() { println("Welcome to my Benz car!") }
}
4- 面向对象-特质
- 使用关键字trait定义特质
- 特质中没有方法体的方法,默认为抽象方法。抽象方法不需要使用abstract关键字。
- 特质定义完成后,可以使用extends或with关键字把特质混入类中。
- 特质可以包含具体实现,特质中的字段和方法不一定要是抽象的。
- 如果特质只包含了抽象字段和抽象方法,相当于实现了类似Java接口的功能。
package helloscala object helloscala {
def main(args: Array[String]) {
println("Testing, Scala!")
val myCarId1 = new BenzCarId()
val myCarId2 = new BMWCarId()
printf("My first CarId is %d.\n", myCarId1.currentId)
myCarId2.greeting("Welcome my second car.")
printf("My second CarId is %d.\n", myCarId2.currentId)
}
} trait CarId { //使用关键字trait定义特质
var id: Int //定义抽象字段
def currentId(): Int //定义抽象方法,不需要使用abstract关键字
} trait CarGreeting { //使用关键字trait定义特质
def greeting(msg: String) { println(msg) } //定义非抽象方法,
} class BenzCarId extends CarId { //使用extends关键字把特质混入类中
override var id = 10000 //BYD汽车编号从10000开始
def currentId(): Int = { id += 1; id } //返回汽车编号
} class BMWCarId extends CarId with CarGreeting { //使用extends关键字混入第1个特质,后面可以反复使用with关键字混入更多特质
override var id = 20000
def currentId(): Int = { id += 1; id }
}
Scala - 快速学习06 - 面向对象的更多相关文章
- Scala - 快速学习05 - 数据结构
1- 数组(Array) 数组一般包括定长数组和变长数组. 可以不指明数组类型,Scala会自动根据提供的初始化数据来推断出数组的类型. 在Scala中,对数组元素的应用,是使用圆括号,而不是方括号. ...
- Scala - 快速学习01 - Scala简介
Scala简介 Scala(Scalable Language)是一门多范式(multi-paradigm)编程语言,Scala的设计吸收借鉴了许多种编程语言的思想,具备面向对象编程.函数式编程等特性 ...
- scala快速学习笔记(一):变量函数,操作符,基本类型
为了用spark,先学下scala. 参考教程:http://meetfp.com/zh/scala-basic doc查询:http://docs.scala-lang.org 其它资料:http: ...
- 快速学习JavaScript面向对象编程
到处都是属性.方法,代码极其难懂,天哪,我的程序员,你究竟在做什么?仔细看看这篇指南,让我们一起写出优雅的面向对象的JavaScript代码吧! 作为一个开发者,能否写出优雅的代码对于你的职业生涯至关 ...
- Scala - 快速学习09 - 函数式编程:一些操作
1- 集合类(collection) 系统地区分了可变的和不可变的集合. scala.collection包中所有的集合类 可变集合(Mutable) 顾名思义,意味着可以修改,移除或者添加一个元素. ...
- Scala - 快速学习08 - 函数式编程:高阶函数
函数式编程的崛起 函数式编程中的“值不可变性”避免了对公共的可变状态进行同步访问控制的复杂问题,能够较好满足分布式并行编程的需求,适应大数据时代的到来. 函数是第一等公民 可以作为实参传递给另外一个函 ...
- Scala - 快速学习07 - 模式匹配
Scala中的模式匹配的功能可以应用到switch语句.类型检查.“解构”等多种场合. 简单匹配 Scala的模式匹配最常用于match语句中.Scala的match语句类似Java里的switch. ...
- Scala - 快速学习04 - 求值策略
表达式求值策略(Evaluation Strategy) Scala中所有的运算都是基于表达式的. Call By Value - 对函数实参求值,且仅求值一次:函数调用之前对所有表达式进行求值 Ca ...
- Scala - 快速学习03 - 基础语法
1- 变量 变量 mutable variable 在程序运行过程中其值可能发生改变的量 关键词var定义变量,定义时直接进行求值 常量 immutable variable 在程序运行过程中其值不会 ...
随机推荐
- Chapter_4_JAVA作业
一.类的封装,继承与多态 1.课前预习 1.1 举列现实生活中的封装,以及简述在程序中什么是属性的封装? 1.1.1 将东西捆绑在一起,如集成芯片:高压电线等等 1.1.2 封装就是将属性私有化,提供 ...
- docker--容器和镜像的导入导出及部署
一.镜像导出 save 1.查看镜像 docker images 2.导出镜像 docker save -o test.tar image_name 或 docker save image_name ...
- CSS定位网页中的元素
relative相对定位 偏移设置:left.right.top.bottom 值单位:px 元素的规律: 相对定位元素的规律 设置相对定位的盒子会相对它原来的位置通过指定偏移,到达新的位置. 设置相 ...
- shell脚本学习-练习写一个脚本2
# 1.依次展示/var目录下的对象,并说明是文件或者目录.格式如:Hello,$file. # 2.统计一个有多少个文件. #!/bin/bash #Program Description: #Au ...
- ACM(数学问题)——UVa202:输入整数a和b(0≤a≤3000,1≤b≤3000),输出a/b的循环小数表示以及循环节长度。
主要思路: 通过模拟除法运算过程,来判断循环节结束的位置,不断将余数*10再对除数取余得到新的余数,并记录下来,知道出现的余数之前出现过,此时小数开始循环. 例如: 假设 -> a ...
- Java集合类的底层实现探索
List: ArrayList 首先我们来看看jdk的ArrayList的add方法的源码是如何实现的: public boolean add(E e) { ensureCapacityInterna ...
- usb 枚举流程简介
1. 枚举是什么? 枚举就是从设备读取一些信息,知道设备是什么样的设备,如何进行通信,这样主机就可以根据这些信息来加载合适的驱动程序.调试USB设备,很重要的一点就是USB的枚举过程,只 ...
- MySql在Mac上的安装配置
一.下载安装 官网下载社区版dmg安装文件: https://dev.mysql.com/downloads/mysql/ 1.执行安装文件,按步骤完成安装. 2.安装完成后终端输入: mysql - ...
- 设置MessageBox自动关闭
通过设置定时器,让定时器的Tick事件模拟往MessageBox发送一个Enter按钮代替用鼠标点击MessageBox上的确定按钮,来实现MessageBox的自动关闭,实现代码如下: System ...
- GodMode
将“GodMode.{ED7BA470-8E54-465E-825C-99712043E01C}”(不含引号)复制过去,保存即可.