Scala基础(四)
1.定义Scala类
Scala是一种纯粹的面向对象语言,面向对象语言有两个重要的概念:类和对象。
其中,类是对象的抽象,也可以把类理解为模板,对象才是真正的实体。
一般定义类的格式如下:
class ClassName(参数列表) extends t {}
一个Scala源文件中可以有多个类,并且Scala类可以有参数。
一般,Scala类名的第一个字母需要大写,如果需要使用几个单词构成一个类的名称,那么每个单词的第一个字母都要大写。
与Java等其他语言不同的是,Scala中的类不定义为public。
【例】定义一个Point,计算二维坐标点移动后的坐标
#代码2-19 定义类Point
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)
}
}
分析:类的名称是Point,包含两个参数(Int类型),类里面定义了一个方法move()
【例】实例化类并使用new调用Point类中的方法
# 实例化Point类,调用move()方法将坐标为(1,2)的点向右移动2位,向上移动3位
new Point(1, 2).move(2, 3)
执行结果:将坐标为(1,2)的点,向右移动2位,向上移动3位,得到新的坐标点(3,5)
Scala类继承一个类时需要使用关键字extends。
定义一个类Location,该类继承了Point类,Point为父类,Location是子类
【例】Scala继承示例
class Location(val xc: Int,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只允许继承一个父类,并且继承父类的所有属性和方法。
子类继承父类中已经实现的方法时,需要使用override关键字,子类继承父类中未实现的方法时,可以不用override关键字。
【例】override关键字的使用
abstract class Father {
def fun1 = 1
def fun2: Int
}
class Child extends Father {
override def fun1 = 2
def fun2 = 1
}
2.使用scala单例模式
scala中没有static关键字,所以scala的类中不存在静态成员。但是可以使用object关键字实现单例模式。
Scala中使用单例模式时需要使用object定义一个单例对象(object对象),单例对象在整个程序中只有一个实例。
单例对象与类的区别在于单例对象不能带参数。
定义单例对象的语法格式如下:
object ObjectName()
【例】定义单例对象Person
object Person {
val age = 10
def getAge = age
}
包含main()方法的单例对象可以作为程序的入口点。
当单例对象与某个类共享同一个名称时,单例对象被称为这个类的伴生对象,类被称为这个单例对象的伴生类。
类和它的伴生对象可以相互访问对象的私有成员。注意:需要在同一个源文件中定义类和它的伴生对象。
【例】伴生类和伴生对象
定义Person类,类中包含私有成员name和私有方法getSkill(),再定义类的伴生对象,伴生对象访问了伴生类的私有成员和私有方法,而伴生类访问了伴生对象的私有成员skill。
class Person private(val name: String) {
private def getSkill() = name+"s skill is:" + Person.skill
}
object Person {
private val skill = "basketball"
private val person = new Person("Tracy")
def printSkill = println(person.getSkill())
def main(args: Array[String]): Unit = {
Person.printSkill
}
}
3.使用Scala模式匹配
Scala具有强大的模式匹配机制,Scala模式匹配的一般形式为“选择器match{备选项}”。
- 一个模式匹配包含一系列备选项,每个备选项都开始于关键字case。
- 每个备选项都包含一个模式、一到多个表达式。
- 模式和表达式之间使用“=>"隔开。
【例】变量模式匹配示例
定义一个函数matchTest,函数的参数为一个Int类型变量,函数体的功能是对参数进行模式匹配。若参数匹配到的是1,则输出one,匹配到的是2,则输出two;匹配到初1和2以外的其他值,则输出many。
def matchTest(x: Int) = x match {
case 1 => println("one")
case 2 => println("two")
case _ => println("many")
}
【例】列表模式匹配示例
def matchTest(x: List[Int]) = x match {
case List(0, _, _) => println("列表x有3个元素并且第一个元素是0")
case List(1, _*) => println("列表x有任意个元素并且第一个元素是1")
case List(_, 1, _*) => println("列表至少有两个元素并且第二个元素是1")
}
在Scala中,使用case关键字定义的 类称为样例类。
【例】样例类
case class Person(name: String,age: Int)
val alice = new Person("Alice", 25)
val bob = new Person("Bob", 22)
val mike = new Person("mike", 24)
for(person <- List(alice, bob, mike)) {
person match {
case Person("Alice", 25) => println("Hi, Alice!")
case Person("Bob", 22) => println("Hi, Bob!")
case Person(name, age) => println("name:" + name + "\t" + "age:" + age)
}
}
Scala编译器为样例类添加了一些语法上的便捷设定,具体如下:
- 在伴生对象中提供了apply()方法,因此不使用new关键字也可以构造对象。
- 样例类参数列表中的所有参数已隐式获得val关键字。
- 编译器为样例类添加了toString()、hashCode()和equals()等方法。
4.读写文件
在实际的实践中,常常需要涉及文件的读写操作。
Scala不提供任何特殊文件写入能力,所以进行文件的写操作使用的是Java的I/O类中的PrintWriter来实现。
【例】Scala写入文件:将”I amlearning Scala"写入/opt/scala目录下的test.txt文件中
import java.io._
val pw = new PrintWriter(new File("/opt/scala/test.txt"))
pw.println("I am learing Scala")
pw.close
有时候需要接收用户在屏幕上输入的指令来处理程序,这时可以使用StdIn.readLine接收用户输入的指令。
用户可以在REPL中直接输入“StdIn.readLine”命令并按“Enter”键,并在屏幕上输入指令;也可以将StdIn.readLine赋值给一个变量,用户在屏幕上输入的内容即可赋值给该变量。
使用scala的Source类读取文件内容
【例】Scala读取文件数据
import scala.io.Source
Source.fromFile("/opt/scala/test.txt").foreach{print}
5.任务实现
任务描述:
- 筛选某个地区的所有手机号码段。
- 首先需要根据地区对手机号码段进行分组。
- 再根据地区取出该分组内的所有手机号码段。
读取表中的内容,编写程序完成手机号码归属地信息查询。
- 读取完整数据,编写程序完成手机号码归属地信息查询。将2020phonelocation.txt文件上传至Linux虚拟机的**/opt/scala**目录下。
- 首先使用object定义一个单例对象Phone,在该对象中定义一个checkPhone方法,读取完整的数据,并将数据存储在一个列表中,使用Console.readLine接收用户输入的指令,用户在屏幕上输入要查询的手机号码段,程序接收到屏幕上的指令之后遍历存储数据的列表,若列表中某个元素包含该指令则输出该元素。
import scala.io.StdIn
import scala.io.Source
object Phone {
def checkPhone() {
val phone = for(line <- Source.fromFile("/opt/scala/2020phonelocation.txt").getLines) yield line
val phoneList: List[String] = phone.toList
var num: String = StdIn.readLine
for(line <- phoneList; if line.contains(num)) {println(line)}
}
}
调用单例对象Phone中的checkPhone方法,在屏幕上输出一个手机号码段
import Phone.checkPhone
checkPhone
输入六位号码段:如115036(号码不显示,输入完直接按“Enter”键回车)
Z_Data: out路径解释
Z_Data: 设置的文件输出路径,运行项目会自动生成
ugfhg13: 不是将数据集上传到weather目录了嘛,怎么找不到
阿J~: 先一键三连,有空慢慢研究
2301_77247661: thanks you