文章目录
Scala编程,类似Java,面向对象
常量和变量
定义方式:
val/var 变量名:变量类型 [= 初始值]
若定义了类型,初始值可省略
若省略类型,则必须有初始值
插值表达式
此方法用来拼接字符串
val/var 变量名 = s"${变量/表达式}字符串"
转换
自动转换和强制转换
-
自动转换是从范围小的类型向范围大的类型转换
-
强制转换
val/var 变量名:String = 值类型数据.toXXXX //XXX表示你要转换到的数据类型
val/var 变量名:值类型 = 字符串值.toXXXX //XXX表示你要转换到的数据类型
转换成字符串示例
val a1:Int = 10
val b1:Double = 3.6
val c1:Boolean = false
// 类型首字母要大写
//方式一: 通过和空字符串拼接的形式实现
val a2:String = a1 + ""
val b2:String = b1 + ""
val c2:String = c1 + ""
//方式二: 通过toString函数实现
val a3:String = a1.toString
val b3:String = b1.toString
val c3:String = c1.toString
输入输出
- 先导入包
import scala.io.StdIn
// 接收输入
println("请输入字符串: ")
val str = StdIn.readLine()
println("您输入的字符串内容为: " + str)
println("请输入整数: ")
val num = StdIn.readInt()
println("您输入的数字为: " + num)
println("请输入浮点数: ")
val num = StdIn.readFloat()
println("您输入的数字为: " + num)
循环
while
do…while
for循环有区别
for( var x <- Range ){
statement(s);
}
object Test {
def main(args: Array[String]) {
var a = 0;
// for 循环
for( a <- 1 to 10){
println( "Value of a: " + a );
}
}
}
数组
可以指定数据类型也可以不指定,但是数据类型必须保持一致
object TestArray {
def main(args: Array[String]) {
/**
* 数组语法格式
* var z:Array[String] = new Array[String](3)
* 或
* var z = new Array[String](3)
*/
var myList = Array(1.9, 2.9, 3.4, 3.5)
// 输出所有数组元素
for ( x <- myList ) {
println( x )
}
// 计算数组所有元素的总和
var total = 0.0;
for ( i <- 0 to (myList.length - 1)) {
total += myList(i);
}
println("总和为 " + total);
// 查找数组中的最大元素
var max = myList(0);
for ( i <- 1 to (myList.length - 1) ) {
if (myList(i) > max) max = myList(i);
}
println("最大值为 " + max);
}
}
元组
- new Tuplex( ) , 此处x代表的是元组的长度
- 目前 Scala 支持的元组最大长度为 22。对于更大长度你可以使用集合,或者扩展元组。
object TestTuple {
def main(args: Array[String]) {
val t = new Tuple3(1, "hello", Console)
println("连接后的字符串为: " + t.toString() )
// 我们可以使用 t._1 访问第一个元素, t._2 访问第二个元素,如下所示:
println(t._1)
// 迭代访问元组
t.productIterator.foreach{ i =>println("Value = " + i )}
}
}
类和对象
在 Scala 中用 Object 来代替 java 中 static 单例关键字
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);
}
}
输出:
x 的坐标点: 20
y 的坐标点: 30
类的构造顺序
class bike (var message: String)
{
println("I have " + message)
}
class speeding (message: String) extends bike (message)
{
println("subclass")
def display()
{
println("Bike bike goes Brooom! ")
}
}
object MyObject
{
def main(args: Array[String])
{
var newbike = new speeding("Ninja H2R");
newbike.display();
}
}
特征也可以有构造器,由字段的初始化和其他特征体中的语句构成。这些语句在任何混入该特征的对象在构造时都会被执行。
构造器的执行顺序:
- 调用超类的构造器;
- 特征构造器在超类构造器之后、类构造器之前执行;
- 特征由左到右被构造;
- 每个特征当中,父特征先被构造;
- 如果多个特征共有一个父特征,父特征不会被重复构造
- 所有特征被构造完毕,子类被构造。
Trait(特征)
Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。
与接口不同的是,它还可以定义属性和方法的实现。
一般情况下Scala的类只能够继承单一父类,但是如果是 Trait(特征) 的话就可以继承多个,从结果来看就是实现了多重继承。
如果继承多个Trait需要同时使用extends和with关键字
trait Equal {
def isEqual(x: Any): Boolean
def isNotEqual(x: Any): Boolean = !isEqual(x)
}
// 必须实现特性(trait)中所有位实现的抽象方法
class Point(xc: Int, yc: Int) extends Equal {
var x: Int = xc
var y: Int = yc
def isEqual(obj: Any) =
obj.isInstanceOf[Point] &&
obj.asInstanceOf[Point].x == x
}
模式匹配(case)
在声明样例类时,下面的过程自动发生了:
- 构造器的每个参数都成为val,除非显式被声明为var,但是并不推荐这么做;
- 在伴生对象中提供了apply方法,所以可以不使用new关键字就可构建对象;
- 提供unapply方法使模式匹配可以工作;
- 生成toString、equals、hashCode和copy方法,除非显示给出这些方 法的定义。
object Testcase {
def main(args: Array[String]) {
println(matchTest("two"))
println(matchTest("test"))
println(matchTest(1))
println(matchTest(6))
}
// scala的模式匹配相当于java中的switch,但是只要匹配成功就不会运行后面的代码
def matchTest(x: Any): Any = x match {
case 1 => "one"
case "two" => 2
case y: Int => "scala.Int"
case _ => "many"
}
}
抛出异常
import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException
// 异常捕捉的机制与其他语言中一样,如果有异常发生,catch 字句是按次序捕捉的。
// 因此,在 catch 字句中,越具体的异常越要靠前,越普遍的异常越靠后。
// 如果抛出的异常不在 catch 字句中,该异常则无法处理,会被升级到调用者处。
object TestCatchException {
def main(args: Array[String]) {
try {
val f = new FileReader("input.txt")
} catch {
case ex: FileNotFoundException =>{
println("Missing file exception")
}
case ex: IOException => {
println("IO Exception")
}
} finally {
println("Exiting finally...")
}
}
}
Missing file exception
Exiting finally…
提取器
object TestExtractor {
def main(args: Array[String]) {
println ("Apply 方法 : " + apply("Zara", "gmail.com"));
println ("Unapply 方法 : " + unapply("Zara@gmail.com"));
println ("Unapply 方法 : " + unapply("Zara Ali"));
}
// Scala 提取器是一个带有unapply方法的对象。unapply方法算是apply方法的反向操作:
// unapply接受一个对象,然后从对象中提取值,提取的值通常是用来构造该对象的值。
// 注入方法 (可选)
def apply(user: String, domain: String) = {
user +"@"+ domain
}
// 提取方法(必选)
def unapply(str: String): Option[(String, String)] = {
val parts = str split "@"
if (parts.length == 2){
Some(parts(0), parts(1))
}else{
None
}
}
}
可用来提取邮箱,提取关键字等等
提取
object TestExtractor {
def main(args: Array[String]) {
val x = TestExtractor(5)
println(x)
x match
{
case TestExtractor(num) => println(x + " 是 " + num + " 的两倍!")
//unapply 被调用
case _ => println("无法计算")
}
}
// apply 和 unapply 在进行模式匹配时是关键字!!!
def apply(x: Int) = x*2
def unapply(z: Int): Option[Int] = if (z%2==0) Some(z/2) else None
}