Scala进阶之路-面向对象编程之类的成员详解

           Scala进阶之路-面向对象编程之类的成员详解

                               作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.Scala中的object对象及apply方法

1>.scala 单例对象

  在Scala中,是没有static这个东西的,但是它也为我们提供了单例模式的实现方法,那就是使用关键字object。注意:object 对象是不能带参数的。

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass /**
* 1>.在scala中的object是一个单例对象,没办法new,因为它的构造方法被私有化了
* 2>.Object中定义的成员变量和方法都是静态的
* 3>.可以通过"类名.方法"或者 "对象名.成员变量"
*
*/
object ScalaStatic {
val name:String = "尹正杰"
var age:Int = 18 def sayHello(): Unit ={
println("Hi,I'm yinzhengjie !")
} //注意:如果调用者没有指定方法,默认会调用apply方法哟!
def apply(habby:String) = {
println(s"我的爱好是:${habby}")
}
}

2>.接下来我们一起测试如何访问一个Object的成员变量和方法,具体代码如下:

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass object Demo {
def main(args: Array[String]): Unit = {
//直接“类名.成员变量”就可以访问非私有的变量
var res1 = ScalaStatic.age
print(s"res1=====> ${res1}\n")
//对单例模式的类中的非私有成员变量进行修改操作,但前提是这个变量需要用关键字var来声明
ScalaStatic.age = 26
print(s"res1=====> ${res1}\n") ScalaStatic.sayHello() //如果没有指定方法,默认会调用apply方法哟!
ScalaStatic.apply("篮球")
ScalaStatic("乒乓球")
}
}

3>.验证Object编译后文件内容

Scala进阶之路-面向对象编程之类的成员详解

二.Scala中类的定义及构造器的使用

1>.子定义Scala的Teacher类

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass; /**
* 关于构造器的注意事项:
*
* 1>.在Scala中定义类用class关键字修饰,这个类名称后面的构造器叫主构造器。类的主构造器中的属性会定义成类的成员变量。一个类
* 只能有一个主构造器,但是可以有多个辅助构造器;
* 2>.如果住构造器中成员属性没有val或者var修饰的话,该属性不能被访问,相当于对外没有提供get方法;
* 3>.如果成员属性使用var修饰的话,相当于对外提供了getter和setter方法;
* 4>.如果成员属性使用val修饰的话,相当于对外只提供了getter方法,因为val用于修饰不可变数据类型,类似与Java中定义常量的关键字“final”;
* 5>.辅助构造器是完成赋值操作的,辅助构造器是内部需要调用主构造器或者其它辅助构造器;
*/
class Teacher(var name:String,val age:Int) { //定义sex和blog成员变量,让其默认值为null,我们可以用"_"表示为null。
var sex:String = _
var blog:String = _ //定义辅助构造器一,辅助构造器需要调用主构造器
def this(name:String,age :Int,sex:String)={
//在辅助构造器中必须先调用主构造器
this(name,age)
this.sex = sex
} //定义辅助构造器二,辅助构造器如果不调用主构造器那么必须得调用其它的辅助构造器
def this(name:String,age:Int,sex:String,blog:String)={
//调用其它辅助构造器,在上面的一个辅助构造器中调用了主构造器
this(name,age,sex)
this.blog = blog
} }

2>.使用Scala的单列类调用自定义Teacher类

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass object Demo { def main(args: Array[String]): Unit = {
//调用带有两个参数的主构造器
val t1 = new Teacher("尹正杰",18)
println(s"姓名:${t1.name},年龄:${t1.age}") //调用带有3个参数的辅助构造器
val t2 = new Teacher("尹正杰",20,"男")
println(s"姓名:${t2.name},年龄:${t2.age},性别:${t2.sex}") //调用带有4个参数的辅助构造器
val t3 = new Teacher("尹正杰",26,"男","https://www.cnblogs.com/yinzhengjie")
println(s"姓名:${t3.name},年龄:${t3.age},性别:${t3.sex},博客:${t3.blog}")
}
} /*
以上代码输出几个如下:
姓名:尹正杰,年龄:18
姓名:尹正杰,年龄:20,性别:男
姓名:尹正杰,年龄:26,性别:男,博客:https://www.cnblogs.com/yinzhengjie
*/

三.Scala类的访问权限

1>.Scala类的构造器访问权限

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass; /**
* 关于构造器的访问权限:
* 在构造器前加修饰权限就可以设置相应的相应的访问权限,如果你想让主构造器私有化,只需要在主构造器前加private修饰即可。当然这种方法也适用于辅助构造器
*/
class Teacher private (var name:String,val age:Int) { //定义sex和blog成员变量,让其默认值为null,我们可以用"_"表示为null。
var sex:String = _
var blog:String = _ //定义辅助构造器一,辅助构造器需要调用主构造器,我们想要将这个辅助构造器私有化,只需要在def前面加一个private修饰符即可。
private def this(name:String,age :Int,sex:String)={
//在辅助构造器中必须先调用主构造器
this(name,age)
this.sex = sex
} //定义辅助构造器二,辅助构造器如果不调用主构造器那么必须得调用其它的辅助构造器
def this(name:String,age:Int,sex:String,blog:String)={
//调用其它辅助构造器,在上面的一个辅助构造器中调用了主构造器
this(name,age,sex)
this.blog = blog
}
}
 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass object Demo { def main(args: Array[String]): Unit = {
//调用带有4个参数的辅助构造器
val t3 = new Teacher("尹正杰",26,"男","https://www.cnblogs.com/yinzhengjie")
println(s"姓名:${t3.name},年龄:${t3.age},性别:${t3.sex},博客:${t3.blog}")
}
} /*
以上代码输出几个如下:
姓名:尹正杰,年龄:26,性别:男,博客:https://www.cnblogs.com/yinzhengjie
*/

Demo.scala 文件内容(调用辅助构造方法案例展示)

2>.Scala类的成员属性访问权限

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass; /**
* 关于类的成员属性访问权限 :
* 如果类的主构造器中成员变量是private修饰的,它的setter和getter方法都是私有的,外部不能访问
*/
class Teacher(var name:String,private val age:Int) { }
 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass object Demo { def main(args: Array[String]): Unit = {
//调用带有4个参数的辅助构造器
val t1 = new Teacher("尹正杰",26)
//由于主构造方法的age字段被私有化了,因此就没法通过getter或者setter方法访问啦!因此我们只可以访问name字段!
println(s"姓名:${t1.name}")
}
} /*
以上代码输出几个如下:
姓名:尹正杰
*/

Demo.scala 文件内容(调用主构造方法案例展示)

3>.Scala中的类的访问权限(可见性)

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass; /**
*
* 类的访问权限
* 类的前面加上private[this] 标识这个类在当前包下都可见,当前包下的子包不可见
* 类的前面加上private[包名] 表示这个类在当前包及其子包下都可见
*/
private[scalaClass] class Teacher(var name:String,val age:Int) { //定义sex和blog成员变量,让其默认值为null,我们可以用"_"表示为null。
var sex:String = _
var blog:String = _ //定义辅助构造器一,辅助构造器需要调用主构造器,我们想要将这个辅助构造器私有化,只需要在def前面加一个private修饰符即可。
private def this(name:String,age :Int,sex:String)={
//在辅助构造器中必须先调用主构造器
this(name,age)
this.sex = sex
} //定义辅助构造器二,辅助构造器如果不调用主构造器那么必须得调用其它的辅助构造器
def this(name:String,age:Int,sex:String,blog:String)={
//调用其它辅助构造器,在上面的一个辅助构造器中调用了主构造器
this(name,age,sex)
this.blog = blog
}
}
 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass.scala import cn.org.yinzhengjie.scalaClass.Teacher object Demo { def main(args: Array[String]): Unit = {
//调用带有4个参数的辅助构造器
val t1 = new Teacher("尹正杰",26,"男","https://www.cnblogs.com/yinzhengjie")
println(s"姓名:${t1.name},年龄:${t1.age},性别:${t1.sex},博客:${t1.blog}")
}
} /*
以上代码输出几个如下:
姓名:尹正杰,年龄:26,性别:男,博客:https://www.cnblogs.com/yinzhengjie
*/

Demo.scala 文件内容(调用辅助构造方法案例展示)

四.Scala中的伴生对象

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass; /**
* 关于构造器的注意事项:
* 1>.在Scala中定义类用class关键字修饰,这个类名称后面的构造器叫主构造器。类的主构造器中的属性会定义成类的成员变量。一个类
* 只能有一个主构造器,但是可以有多个辅助构造器;
* 2>.如果住构造器中成员属性没有val或者var修饰的话,该属性不能被访问,相当于对外没有提供get方法;
* 3>.如果成员属性使用var修饰的话,相当于对外提供了getter和setter方法;
* 4>.如果成员属性使用val修饰的话,相当于对外只提供了getter方法,因为val用于修饰不可变数据类型,类似与Java中定义常量的关键字“final”;
* 5>.辅助构造器是完成赋值操作的,辅助构造器是内部需要调用主构造器或者其它辅助构造器;
*
* 类的成员属性访问权限:
* 如果类的主构造器中成员属性是private修饰的,它的set 和 get方法都是私有的,外部不能访问
*
*
* 类的构造器访问权限
* 在构造器前加修饰权限
* private 在主构造器之前,这说明该类的主构造器是私有的,外部类或者外部对象不能访问
* 也适用于辅助构造器
*
* 类的访问权限
* 类的前面加上private[this] 标识这个类在当前包下都可见,当前包下的子包不可见
* 类的前面加上private[包名] 表示这个类在当前包及其子包下都可见
*/
private[scalaClass] class Teacher(var name:String,val age:Int) {
//定义sex和blog成员变量,让其默认值为null,我们可以用"_"表示为null。
var sex:String = _
var blog:String = _
//定义辅助构造器一,辅助构造器需要调用主构造器,我们想要将这个辅助构造器私有化,只需要在def前面加一个private修饰符即可。
private def this(name:String,age :Int,sex:String)={
//在辅助构造器中必须先调用主构造器
this(name,age)
this.sex = sex
}
//定义辅助构造器二,辅助构造器如果不调用主构造器那么必须得调用其它的辅助构造器
def this(name:String,age:Int,sex:String,blog:String)={
//调用其它辅助构造器,在上面的一个辅助构造器中调用了主构造器
this(name,age,sex)
this.blog = blog
}
} /**
* 注意:“object Teacher”是“class Teacher”的伴生对象
*/
object Teacher{ /**
* 定义apply方法帮我们创建出“class Teacher”的实例,如果调用者在没有指明具体方法时,默认就会调用该方法。
*/
def apply(name: String, age: Int): Teacher = {
// 初始化工作
new Teacher(name, age, "男", "http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/")
} def main(args: Array[String]): Unit = {
//我们直接调用伴生对象的apply方法,当然apply方法我们可以省略不写。
val t1 = Teacher("尹正杰",18)
println(s"姓名:${t1.name},年龄:${t1.age},性别:${t1.sex},博客:${t1.blog}") //调用带有4个参数的辅助构造器
val t2 = new Teacher("尹正杰",26,"男","https://www.cnblogs.com/yinzhengjie")
println(s"姓名:${t2.name},年龄:${t2.age},性别:${t2.sex},博客:${t2.blog}")
}
} /*
以上代码执行结果如下 :
姓名:尹正杰,年龄:26,性别:男,博客:https://www.cnblogs.com/yinzhengjie
*/

五.Scala特质Trait使用

1>.Scala特质Trait定义使用

  特质(Trait)相当于Java中的Interface,只不过特质(Trait)要比Java中的interface要强大的多,因为特质(Trait)可以定义已经实现的方法,也可以定义没有实现的方法。

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass /**
* Scala的中的接口叫做特质,关键字为trait。
* 在Scala中也没有“implements”关键字,只有“extends”关键字
* 在Scala特质中可以定义有实现的方法,也可以定义没有实现的方法
*/
trait ScalaTrait {
/**
* 定义有实现的方法
*/
def sayHello()={
println("I'm Yinzhengjie!")
}
/**
* 定义没有实现的方法
*/
def playGame(name:String)
}

ScalaTrait.scala 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass class ScalaTraitImpl extends ScalaTrait { /**
* 如果特质中playGame方法没有实现的话,子类在实现的时候可以不加override关键字也可以加
*/
def playGame(name: String): Unit = {
println(s"${name} 正在玩游戏!")
} /**
* 如果特质中某个方法有具体的实现,在子类继承重写的时候,必须使用override关键字
*/
override def sayHello(): Unit = {
//我们的重写过程需要其实就是调用父类的方法
super.sayHello()
} } /**
* 注意:“object ScalaTraitImpl”是“class ScalaTraitImpl”的伴生对象
*/
object ScalaTraitImpl{
def main(args: Array[String]): Unit = {
val s1 = new ScalaTraitImpl()
s1.sayHello()
s1.playGame("尹正杰")
}
} /*
以上代码执行结果如下:
I'm Yinzhengjie!
尹正杰 正在玩游戏!
*/

2>.Scala中混入特质的两种方式

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass /**
* Scala的中的接口叫做特质,关键字为trait。
* 在Scala中也没有“implements”关键字,只有“extends”关键字
* 在Scala特质中可以定义有实现的方法,也可以定义没有实现的方法
*/
trait ScalaTrait {
/**
* 定义有实现的方法
*/
def sayHello()={
println("I'm Yinzhengjie!")
}
/**
* 定义没有实现的方法
*/
def playGame(name:String)
}

ScalaTrait.scala 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass trait Bird {
/**
* 定义有实现的方法
*/
def fly(name:String): Unit ={
println(s"${name} 正在天上飞......")
}
/**
* 定义没有实现的方法
*/
def sing()
}

Bird.scala 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass /**
* 在定义类时,我们可以用将多个特质混在一起,第一个特质使用extends连接,后续的特质依次使用with连接即可。
*/
class ScalaTraitImpl extends ScalaTrait with Bird { /**
* 如果特质中playGame方法没有实现的话,子类在实现的时候可以不加override关键字也可以加
*/
def playGame(name: String): Unit = {
println(s"${name} 正在玩游戏!")
} /**
* 如果特质中某个方法有具体的实现,在子类继承重写的时候,必须使用override关键字
*/
override def sayHello(): Unit = {
//我们的重写过程需要其实就是调用父类的方法
super.sayHello()
} /**
* 定义有实现的方法
*/
override def fly(name: String): Unit = super.fly(name) def sing(): Unit = {
println("Sing a song!")
}
} /**
* 注意:“object ScalaTraitImpl”是“class ScalaTraitImpl”的伴生对象
*/
object ScalaTraitImpl{
def main(args: Array[String]): Unit = {
/**
* 在Scala中可以动态混入N个特质,各个特质之间使用关键字with连接即可
*/
val s1 = new ScalaTraitImpl with Bird with ScalaTrait
s1.sayHello()
s1.playGame("尹正杰")
s1.sing()
s1.fly("猫头鹰")
}
} /*
以上代码执行结果如下:
I'm Yinzhengjie!
尹正杰 正在玩游戏!
Sing a song!
猫头鹰 正在天上飞......
*/

六.Scala中得抽象类abstract

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass /**
* 1>.使用关键字abstract定义一个抽象类
* 2>.抽象类可以具体实现方法
* 3>.也可以有具体实现的方法
*/
abstract class AbstractClass {
def eat(food:String):String def sayHello() = {
println("I'm yinzhengjie!")
}
}

AbstractClass.scala 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass trait Teacher {
def palyGame(name:String):String def teaching(name:String): Unit ={
println(s"${name} 正在教学生!")
}
}

Teacher.scala 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass /**
* 1>.在Scala中第一个继承抽象类或者特质,只能使用关键字extends
* 2>.如果想继承多个独特的话,可以在extends之后使用with关键字。
*/
object AbstractClassImpl extends AbstractClass with Teacher {
override def sayHello(): Unit = {
super.sayHello()
} def eat(food: String): String = {
"炒着吃" + food
} override def palyGame(name: String): String = {
s"$name 正在打王者荣耀哟......."
} def main(args: Array[String]): Unit = {
AbstractClassImpl.sayHello()
val res1 = AbstractClassImpl.eat("腊肉")
println(s"res1 =====> ${res1}")
}
}

七.Scala中得final和type

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass trait Teacher { /**
* 使用type关键字定义一个自定义类型Yinzhengjie,这个类型并没有被确定,而是让继承者自己去指定。
*/
type Yinzhengjie final def Bodybuilding(s:Yinzhengjie)={
println(s"${s} 正在健身....")
} def palyGame(name:String):String /**
* 由于teaching方法被我加了关键字final,因此这个方法没法重写(override)!
*/
final def teaching(name:String): Unit ={
println(s"${name} 正在教学生!")
}
}

Teacher.scala 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass /**
* 1>.使用关键字abstract定义一个抽象类
* 2>.抽象类可以具体实现方法
* 3>.也可以有具体实现的方法
*/
abstract class AbstractClass {
def eat(food:String):String /**
* 由于sayHello方法被我加了关键字final,因此这个方法没法重写(override)!
*/
final def sayHello() = {
println("I'm yinzhengjie!")
}
}

AbstractClass.scala 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass /**
* final关键字:
* 1>.在Scala中,final修饰的类或者方法或者成员变量,不能被重写
* 2>.如果使用final关键字修饰类,则该类不能被继承
* 3>.如果使用final关键字修饰方法,则该方法不能被重写(override)
* 4>.如果使用final关键字修饰成员变量,则该成员变量不能被重新修改(无法再次赋值)
* type关键字:
* 我们可以理解type的功能就是一个别名。
*/
final object AbstractClassImpl extends AbstractClass with Teacher { /**
* 我们在继承的时候,需要指定“Yinzhengjie”的类型,比如我们此处指定其类型为String。
*/
type Yinzhengjie = String def eat(food: String): String = {
"炒着吃" + food
} override def palyGame(name: String): String = {
s"$name 正在打王者荣耀哟......."
} def main(args: Array[String]): Unit = {
AbstractClassImpl.sayHello()
val res1 = AbstractClassImpl.eat("腊肉")
println(s"res1 =====> ${res1}")
AbstractClassImpl.Bodybuilding("尹正杰") }
} /*
以上代码执行结果如下:
I'm yinzhengjie!
res1 =====> 炒着吃腊肉
尹正杰 正在健身....
*/

八.Scala中样例类和样例对象

  样例类是特殊类,经过了优化处理,经常用于模式匹配。好处是内置实现了众多scala常用的功能,比如serializable、compare、apply、unapply

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaClass /**
* 样例类:
* 1>.在类前加关键字case就是一个样例类
* 2>.它支持模式匹配,默认实现了Serializable接口
* 3>.具体格式为:case class Message(属性......)
*
* 定义变量规则:
* 1>.类名的定义首字母大写推荐使用驼峰式;
* 2>.属性名称第一个字母小写;
* 一个标准的命名规则是一个资深开发的基础。
*/
case class Message(name:String,countent:String) { } /**
* 样例对象:
* 1>.用于模式匹配
* 2>.样例对象不能封装数据
* 3>.样例对象格式:case opject 对象名
*/
case object MonitorServer object CaseDemo{
def main(args: Array[String]): Unit = {
val message = new Message("杨幂","今天晚上要拍戏......")
println(message.name)
println(message.countent)
}
} /*
以上代码输出结果如下 :
杨幂
今天晚上要拍戏......
*/

九.Scala中得模式匹配---match case

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.function object People { val (name,age) = ("尹正杰",26) def sayHello(): Unit ={
println("I'm yinzhengjie!")
} def init(): String ={
s"姓名:$name,年龄:${age}"
}
}

People.scala 文件内容(自定义类)

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.function import java.awt.Color /**
* 模式匹配 match case
* 一旦一个case 匹配上了,就不会再往下匹配了
*/
object PatternMatching {
def main(args: Array[String]): Unit={
matchingConstant(Color.orange)
contentMatch("yinzhengjie")
typeMatch(2018)
typeMatch(true)
arrayMatch(Array(8))
listMatch(1::2::3::Nil)
tupleMatch((0, 1))
objMatch(1,2)
objMatch(People)
}
/**
* 匹配对象
*/
def objMatch(obj: Any) = {
val res = obj match {
case (x, y) =>s"$x $y"
case Int => "int"
case People => People.init()
case _ => "匹配失败!"
}
println(res)
}
/**
* 匹配元组
*/
def tupleMatch(tuple: Any) = {
val res = tuple match{
case (0, _) => "元组的第一个元素为0, 第二个元素为任意类型的数据,且只有2个元素"
case (a, b, c) => "拥有三个元素的元组"
case (_, "98K + 八倍镜") => "[98K + 八倍镜] 套装"
case _ => "匹配失败!"
}
println(res)
}
/**
* 匹配List
*/
def listMatch(list: Any) = {
val res = list match{
case 0::Nil => "只有一个0元素的List"
case 7::9::Nil => "只有7和9元素的List"
case x::y::z::Nil => "只有三个元素的List"
case m::n if n.length > 0 => "------" // 拥有head,和 tail的数组, “if n.length > 0” 是守卫条件
case _ => "匹配失败!"
}
println(res)
}
/**
* 匹配Array
*/
def arrayMatch(arr: Any) = {
val res = arr match {
case Array(0) => "只有一个0元素的数组"
case Array(0, _) => "以0开头的,拥有2个元素的数组"
case Array(1, _, 3) => "已1开头,3结尾,中间为任意元素的三个元素的数组"
case Array(8, _*) => "已8开头,N个元素的数组" // _*标识0个或者多个任意类型的数据
case _ => "匹配失败!"
}
println(res)
}
/**
* 匹配数据类型
*/
def typeMatch(tp: Any) = {
val res = tp match{
case x: Int => s"Int $x"
case y: Long => s"Long $y"
case z: Boolean => s"boolean $z"
case _ => "匹配失败!"
}
println(res)
}
/**
* 匹配字符串内容
*/
def contentMatch(str: String) = {
val res = str match{
case "yinzhengjie" => "尹正杰"
case "Python" => "Python"
case "Golang" => "Golang"
case "Java" => "Java"
case "2018" => "2018"
case _ => "匹配失败!" // "_"用于任意内容
}
println(res)
}
/**
* 匹配常量 + 守卫条件
* 扩展常量问题:大写会识别成常量,小写是变量,如果让小写也是常量,使用``标出
*/
def matchingConstant(color: Color)={
val res = color match {
case Color.RED => "红色" //case Color.RED 匹配结果为 "红色",下面两行代码类似。
case Color.GREEN => "绿色"
case Color.yellow => "黄色"
case _ if color == Color.orange => "恭喜你,中奖了!" //这里定义的就是守卫条件。
case _ => "匹配失败!" //case _ 表示匹配任意类型。换句话说,这里定义的是默认匹配情况,即上面的3中匹配均无效。
}
println(res)
}
} /*
以上代码执行结果如下 :
恭喜你,中奖了!
尹正杰
Int 2018
boolean true
已8开头,N个元素的数组
只有三个元素的List
元组的第一个元素为0, 第二个元素为任意类型的数据,且只有2个元素
1 2
姓名:尹正杰,年龄:26
*/

十.密封样例类

  必须将样例子类和父类定义在一个scala文件中。

//必须将样例子类和父类定义在一个scala文件中。
sealed abstract class Dog
case class Jing8(var name:String) extends Dog
case class HaShiQi(var name:String) extends Dog

Scala进阶之路-面向对象编程之类的成员详解

上一篇:Linux C/C++的编译


下一篇:9.6noip模拟试题