1.4 Scala面向对象的特性
1.4.1 类与对象
无论是在Scala中还是Java中,类都是对象的抽象,而对象都是类的具体实例;类不占用内存,而对象占用存储空间。由于面向对象的核心是对象,若想要在应用程序中使用对象,就必须得先创建一个类。类是用于描述一组对象的共同特征和行为。
创建类的语法格式如下:
class 类名[参数列表]
当类创建好之后,若是想要访问类中的方法和字段,就需要创建一个对象。
创建对象的语法格式如下:
类名 对象名称 = new 类名();
下面创建一个Point类,并在类中定义两个字段x和y以及一个没有返回值的move( )方法,使Point类的实例对象来访问类中的方法和字段,代码如文件1-7所示:
文件1-1 Ch07_ClassTest.scala
package cn.itcast.scala
//定义类
class Point(xc:Int,yc:Int){
//定义字段
var x:Int = xc
var y:Int = yc
//定义方法
def move(dx:Int,dy:Int):Unit = {
x = x + dx
y = y + dy
println("x的坐标点:"+x)
println("y的坐标点:"+y)
}
}
object Ch07_ClassTest {
def main(args: Array[String]): Unit = {
//定义类对象
val pt = new Point(10,20)
//移动到一个新的位置
pt.move(10,10)
}
}
1.4.2 继承
• Scala和Java类似,只允许继承一个父类。
• Java只能继承父类中非私有的属性和方法,而Scala可以继承父类中的所有属性和方法。
在Scala子类继承父类的时候,有以下几点需要注意
• 如果子类要重写一个父类中的非抽象方法,则必须使用override关键字,否则会出现语法错误。
• 如果子类要重写父类中抽象方法时,则无需使用override关键字
下面,创建一个Point类和Location类,并且Location类继承Point类,演示子类Location重写父类Point中的字段,具体代码如文件1-8所示:
文件1-2 Ch08_ExtendsTest.scala
package cn.itcast.scala
//定义父类:Point类
class Point2(val xc:Int,val yc:Int){
//定义字段
var x:Int = xc
var y:Int = yc
//定义方法
def move(dx:Int,dy:Int):Unit = {
x = x + dx
y = y + dy
println("x的坐标点:"+x)
println("y的坐标点:"+y)
}
}
//定义子类:Location类继承Point类
class Location(override val xc:Int,override val yc:Int,zc:Int) extends Point2 (xc,yc){
var z:Int = zc
def move(dx:Int,dy:Int,dz:Int): Unit ={
x = x + dx
y = y + dy
z = z + dz
println("x的坐标点:"+x)
println("y的坐标点:"+y)
println("z的坐标点:"+z)
}
}
object Ch08_ExtendsTest {
def main(args: Array[String]): Unit = {
var loc = new Location(10,20,15)
loc.move(10,10,5)
}
}
1.4.3 单例对象和伴生对象
在Scala中,没有静态方法或静态字段,所以不能用类名直接访问类中的方法和字段,而是创建类的实例和实例对象对访问类中的方法和字段。但是,Scala中提供了object这个关键字用来实现单例模式,使用关键字object创建的对象为单例对象。
创建单例对象的语法格式如下:
object objectName
下面,创建一个单例对象SingletonObject,代码如文件所1-9示:
文件1-9 Ch09_Singleton.scala
package cn.itcast.scala
//创建一个单例对象
object SingletonObject{
def hello(): Unit ={
println("Hello,This is Singleton object")
}
}
object Ch09_Singleton {
def main(args: Array[String]): Unit = {
//调用hello 方法
SingletonObject.hello()
}
}
在一个源文件中有一个类和一个单例对象,若单例对象名与类名相同,则把这个单例对象称作伴生对象(companion object),这个类则被称为是单例对象的伴生类(companion class)。类和伴生对象之间可以相互访问私有的方法和字段。
下面,定义一个伴生对象Dog,演示操作类中的私有方法和字段。具体代码如文件1-10所示。
文件1-10 CH10_Dog.scala
package cn.itcast.scala
//创建c:Dog
class CH10_Dog {
val id = 666
private var name = "二哈"
def printName(): Unit ={
//在Dog类中可以访问伴生对象Dog的私有字段
println(CH10_Dog.CONSTANT + name)
}
}
//伴生对象
object CH10_Dog {
//伴生对象中添加私有字段
private var CONSTANT = "汪汪汪。。。"
def main(args: Array[String]): Unit = {
val dog = new CH10_Dog
dog.name = "二哈 666"
dog.printName()
}
}
1.4.4 特质
在Scala中,Trait(特质)的功能类似于Java中的接口,但Trait的功能却比Java中的接口强大。例如,Trait可以对定义字段和方法进行实现,而接口却不能。Scala中的Trait可以被类和对象(Objects)使用关键字extends来继承。
创建特质的语法格式如下:
trait traitName
下面,创建一个特质Animal,演示类继承特质并访问特质中方法的操作。具体代码如文件1-11所示。
文件1-11 Ch11_People.scala
package cn.itcast.scala
//定义特质
trait Animal{
//定义一个抽象方法(没有实现的方法)
def spek()
def listen(): Unit ={
}
def run(): Unit ={
println("I'm runing")
}
}
//定义类,继承特质
class Ch11_People extends Animal {
override def spek(): Unit = {
println("I'm speaking English")
}
}
object Ch11_People {
def main(args: Array[String]): Unit = {
val people = new Ch11_People
people.spek()
people.listen()
people.run()
}
}
注意,特质允许继承多个,用with关键字。
class Ch11_People extends Animal with A
1.5 Scala的模式匹配与样例类
Scala提供了强大的模式匹配机制,最常见的模式匹配就是math语句,主要应用于从多个分支中进行选择的场景。
1.5.1 模式匹配
Scala中的模式匹配是由match case组成,它类似于Java中的switch case。即对一个值进行条件判断,针对不同的条件,进行不同的处理。
match关键字主要用来描述一个表达式,位于表达式位置的后面。
case关键字主要用来描述和表达式结果进行比较后的模式。
创建模式匹配的语法格式如下:
表达式 match {
case 模式1 => 语句1
case 模式2 => 语句2
case 模式3 => 语句3
}
下面,定义一个方法matchTest(),方法的参数是一个整形字段,而方法的调用则是对参数进行模式匹配,若参数匹配的是1,则打印输出“one”;若参数匹配的是2,则打印输出“two”;若参数匹配的是_,则打印输出“many”,具体实现代码如文件1-12所示。
文件1-12 Ch12_PatternMatch.scala
package cn.itcast.scala
object Ch12_PatternMatch {
def main(args: Array[String]): Unit = {
println(matchTest(5))
}
//模式匹配
def matchTest(x:Int):String = x match{
case 1 => "one"
case 2 => "two"
case _ => "many"
}
}
1.5.2 样例类
• 在Scala中,使用case关键字来定义的类被称为样例类。
• 样例类是一种特殊的类,经过优化可以被用于模式匹配。
下面,使用case关键字来定义样例类Person,并将该样例类应用到模式匹配中,具体代码如文件1-13所示。
文件1-13 Ch13_CaseClass.scala
package cn.itcast.scala
object Ch13_CaseClass {
//定义样例类
case class Person(name:String,age:Int)
def main(args: Array[String]): Unit = {
//创建样例类对象
val alice = new Person("Alice", 25)
val bob = new Person("Bob", 32)
val charlie = new Person("Charlie", 33)
//val tom = Person("tom",26) //这种方式创建也可以
for(person <- List(alice,bob,charlie)){
//模式匹配
person match {
case Person("Alice",25) => println("Hi Alice")
case Person("Bob", 32) => println("Hi Bob")
case Person("Charlie", 33) => println("Hi Charlie")
//找不到以上匹配时
case Person(name,age) => println("Name:"+name+"\t"+"Age:"+age)
}
}
}
}