Scala进阶之路-面向对象编程之类的成员详解
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.Scala中的object对象及apply方法
1>.scala 单例对象
在Scala中,是没有static这个东西的,但是它也为我们提供了单例模式的实现方法,那就是使用关键字object。注意:object 对象是不能带参数的。
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass 7 8 /** 9 * 1>.在scala中的object是一个单例对象,没办法new,因为它的构造方法被私有化了 10 * 2>.Object中定义的成员变量和方法都是静态的 11 * 3>.可以通过"类名.方法"或者 "对象名.成员变量" 12 * 13 */ 14 object ScalaStatic { 15 val name:String = "尹正杰" 16 var age:Int = 18 17 18 def sayHello(): Unit ={ 19 println("Hi,I'm yinzhengjie !") 20 } 21 22 //注意:如果调用者没有指定方法,默认会调用apply方法哟! 23 def apply(habby:String) = { 24 println(s"我的爱好是:${habby}") 25 } 26 }
2>.接下来我们一起测试如何访问一个Object的成员变量和方法,具体代码如下:
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass 7 8 object Demo { 9 def main(args: Array[String]): Unit = { 10 //直接“类名.成员变量”就可以访问非私有的变量 11 var res1 = ScalaStatic.age 12 print(s"res1=====> ${res1} ") 13 //对单例模式的类中的非私有成员变量进行修改操作,但前提是这个变量需要用关键字var来声明 14 ScalaStatic.age = 26 15 print(s"res1=====> ${res1} ") 16 17 ScalaStatic.sayHello() 18 19 //如果没有指定方法,默认会调用apply方法哟! 20 ScalaStatic.apply("篮球") 21 ScalaStatic("乒乓球") 22 } 23 }
3>.验证Object编译后文件内容
二.Scala中类的定义及构造器的使用
1>.子定义Scala的Teacher类
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass; 7 8 /** 9 * 关于构造器的注意事项: 10 * 11 * 1>.在Scala中定义类用class关键字修饰,这个类名称后面的构造器叫主构造器。类的主构造器中的属性会定义成类的成员变量。一个类 12 * 只能有一个主构造器,但是可以有多个辅助构造器; 13 * 2>.如果住构造器中成员属性没有val或者var修饰的话,该属性不能被访问,相当于对外没有提供get方法; 14 * 3>.如果成员属性使用var修饰的话,相当于对外提供了getter和setter方法; 15 * 4>.如果成员属性使用val修饰的话,相当于对外只提供了getter方法,因为val用于修饰不可变数据类型,类似与Java中定义常量的关键字“final”; 16 * 5>.辅助构造器是完成赋值操作的,辅助构造器是内部需要调用主构造器或者其它辅助构造器; 17 */ 18 class Teacher(var name:String,val age:Int) { 19 20 //定义sex和blog成员变量,让其默认值为null,我们可以用"_"表示为null。 21 var sex:String = _ 22 var blog:String = _ 23 24 //定义辅助构造器一,辅助构造器需要调用主构造器 25 def this(name:String,age :Int,sex:String)={ 26 //在辅助构造器中必须先调用主构造器 27 this(name,age) 28 this.sex = sex 29 } 30 31 //定义辅助构造器二,辅助构造器如果不调用主构造器那么必须得调用其它的辅助构造器 32 def this(name:String,age:Int,sex:String,blog:String)={ 33 //调用其它辅助构造器,在上面的一个辅助构造器中调用了主构造器 34 this(name,age,sex) 35 this.blog = blog 36 } 37 38 }
2>.使用Scala的单列类调用自定义Teacher类
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass 7 8 object Demo { 9 10 def main(args: Array[String]): Unit = { 11 //调用带有两个参数的主构造器 12 val t1 = new Teacher("尹正杰",18) 13 println(s"姓名:${t1.name},年龄:${t1.age}") 14 15 //调用带有3个参数的辅助构造器 16 val t2 = new Teacher("尹正杰",20,"男") 17 println(s"姓名:${t2.name},年龄:${t2.age},性别:${t2.sex}") 18 19 //调用带有4个参数的辅助构造器 20 val t3 = new Teacher("尹正杰",26,"男","https://www.cnblogs.com/yinzhengjie") 21 println(s"姓名:${t3.name},年龄:${t3.age},性别:${t3.sex},博客:${t3.blog}") 22 } 23 } 24 25 26 27 /* 28 以上代码输出几个如下: 29 姓名:尹正杰,年龄:18 30 姓名:尹正杰,年龄:20,性别:男 31 姓名:尹正杰,年龄:26,性别:男,博客:https://www.cnblogs.com/yinzhengjie 32 */
三.Scala类的访问权限
1>.Scala类的构造器访问权限
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass; 7 8 /** 9 * 关于构造器的访问权限: 10 * 在构造器前加修饰权限就可以设置相应的相应的访问权限,如果你想让主构造器私有化,只需要在主构造器前加private修饰即可。当然这种方法也适用于辅助构造器 11 */ 12 class Teacher private (var name:String,val age:Int) { 13 14 //定义sex和blog成员变量,让其默认值为null,我们可以用"_"表示为null。 15 var sex:String = _ 16 var blog:String = _ 17 18 //定义辅助构造器一,辅助构造器需要调用主构造器,我们想要将这个辅助构造器私有化,只需要在def前面加一个private修饰符即可。 19 private def this(name:String,age :Int,sex:String)={ 20 //在辅助构造器中必须先调用主构造器 21 this(name,age) 22 this.sex = sex 23 } 24 25 //定义辅助构造器二,辅助构造器如果不调用主构造器那么必须得调用其它的辅助构造器 26 def this(name:String,age:Int,sex:String,blog:String)={ 27 //调用其它辅助构造器,在上面的一个辅助构造器中调用了主构造器 28 this(name,age,sex) 29 this.blog = blog 30 } 31 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass 7 8 object Demo { 9 10 def main(args: Array[String]): Unit = { 11 //调用带有4个参数的辅助构造器 12 val t3 = new Teacher("尹正杰",26,"男","https://www.cnblogs.com/yinzhengjie") 13 println(s"姓名:${t3.name},年龄:${t3.age},性别:${t3.sex},博客:${t3.blog}") 14 } 15 } 16 17 18 19 /* 20 以上代码输出几个如下: 21 姓名:尹正杰,年龄:26,性别:男,博客:https://www.cnblogs.com/yinzhengjie 22 */
2>.Scala类的成员属性访问权限
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass; 7 8 /** 9 * 关于类的成员属性访问权限 : 10 * 如果类的主构造器中成员变量是private修饰的,它的setter和getter方法都是私有的,外部不能访问 11 */ 12 class Teacher(var name:String,private val age:Int) { 13 14 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass 7 8 object Demo { 9 10 def main(args: Array[String]): Unit = { 11 //调用带有4个参数的辅助构造器 12 val t1 = new Teacher("尹正杰",26) 13 //由于主构造方法的age字段被私有化了,因此就没法通过getter或者setter方法访问啦!因此我们只可以访问name字段! 14 println(s"姓名:${t1.name}") 15 } 16 } 17 18 19 20 /* 21 以上代码输出几个如下: 22 姓名:尹正杰 23 */
3>.Scala中的类的访问权限(可见性)
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass; 7 8 /** 9 * 10 * 类的访问权限 11 * 类的前面加上private[this] 标识这个类在当前包下都可见,当前包下的子包不可见 12 * 类的前面加上private[包名] 表示这个类在当前包及其子包下都可见 13 */ 14 private[scalaClass] class Teacher(var name:String,val age:Int) { 15 16 //定义sex和blog成员变量,让其默认值为null,我们可以用"_"表示为null。 17 var sex:String = _ 18 var blog:String = _ 19 20 //定义辅助构造器一,辅助构造器需要调用主构造器,我们想要将这个辅助构造器私有化,只需要在def前面加一个private修饰符即可。 21 private def this(name:String,age :Int,sex:String)={ 22 //在辅助构造器中必须先调用主构造器 23 this(name,age) 24 this.sex = sex 25 } 26 27 //定义辅助构造器二,辅助构造器如果不调用主构造器那么必须得调用其它的辅助构造器 28 def this(name:String,age:Int,sex:String,blog:String)={ 29 //调用其它辅助构造器,在上面的一个辅助构造器中调用了主构造器 30 this(name,age,sex) 31 this.blog = blog 32 } 33 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass.scala 7 8 import cn.org.yinzhengjie.scalaClass.Teacher 9 10 object Demo { 11 12 def main(args: Array[String]): Unit = { 13 //调用带有4个参数的辅助构造器 14 val t1 = new Teacher("尹正杰",26,"男","https://www.cnblogs.com/yinzhengjie") 15 println(s"姓名:${t1.name},年龄:${t1.age},性别:${t1.sex},博客:${t1.blog}") 16 } 17 } 18 19 20 21 /* 22 以上代码输出几个如下: 23 姓名:尹正杰,年龄:26,性别:男,博客:https://www.cnblogs.com/yinzhengjie 24 */
四.Scala中的伴生对象
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass; 7 8 /** 9 * 关于构造器的注意事项: 10 * 1>.在Scala中定义类用class关键字修饰,这个类名称后面的构造器叫主构造器。类的主构造器中的属性会定义成类的成员变量。一个类 11 * 只能有一个主构造器,但是可以有多个辅助构造器; 12 * 2>.如果住构造器中成员属性没有val或者var修饰的话,该属性不能被访问,相当于对外没有提供get方法; 13 * 3>.如果成员属性使用var修饰的话,相当于对外提供了getter和setter方法; 14 * 4>.如果成员属性使用val修饰的话,相当于对外只提供了getter方法,因为val用于修饰不可变数据类型,类似与Java中定义常量的关键字“final”; 15 * 5>.辅助构造器是完成赋值操作的,辅助构造器是内部需要调用主构造器或者其它辅助构造器; 16 * 17 * 类的成员属性访问权限: 18 * 如果类的主构造器中成员属性是private修饰的,它的set 和 get方法都是私有的,外部不能访问 19 * 20 * 21 * 类的构造器访问权限 22 * 在构造器前加修饰权限 23 * private 在主构造器之前,这说明该类的主构造器是私有的,外部类或者外部对象不能访问 24 * 也适用于辅助构造器 25 * 26 * 类的访问权限 27 * 类的前面加上private[this] 标识这个类在当前包下都可见,当前包下的子包不可见 28 * 类的前面加上private[包名] 表示这个类在当前包及其子包下都可见 29 */ 30 private[scalaClass] class Teacher(var name:String,val age:Int) { 31 //定义sex和blog成员变量,让其默认值为null,我们可以用"_"表示为null。 32 var sex:String = _ 33 var blog:String = _ 34 //定义辅助构造器一,辅助构造器需要调用主构造器,我们想要将这个辅助构造器私有化,只需要在def前面加一个private修饰符即可。 35 private def this(name:String,age :Int,sex:String)={ 36 //在辅助构造器中必须先调用主构造器 37 this(name,age) 38 this.sex = sex 39 } 40 //定义辅助构造器二,辅助构造器如果不调用主构造器那么必须得调用其它的辅助构造器 41 def this(name:String,age:Int,sex:String,blog:String)={ 42 //调用其它辅助构造器,在上面的一个辅助构造器中调用了主构造器 43 this(name,age,sex) 44 this.blog = blog 45 } 46 } 47 48 /** 49 * 注意:“object Teacher”是“class Teacher”的伴生对象 50 */ 51 object Teacher{ 52 53 /** 54 * 定义apply方法帮我们创建出“class Teacher”的实例,如果调用者在没有指明具体方法时,默认就会调用该方法。 55 */ 56 def apply(name: String, age: Int): Teacher = { 57 // 初始化工作 58 new Teacher(name, age, "男", "http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/") 59 } 60 61 62 def main(args: Array[String]): Unit = { 63 //我们直接调用伴生对象的apply方法,当然apply方法我们可以省略不写。 64 val t1 = Teacher("尹正杰",18) 65 println(s"姓名:${t1.name},年龄:${t1.age},性别:${t1.sex},博客:${t1.blog}") 66 67 //调用带有4个参数的辅助构造器 68 val t2 = new Teacher("尹正杰",26,"男","https://www.cnblogs.com/yinzhengjie") 69 println(s"姓名:${t2.name},年龄:${t2.age},性别:${t2.sex},博客:${t2.blog}") 70 } 71 } 72 73 74 /* 75 以上代码执行结果如下 : 76 姓名:尹正杰,年龄:26,性别:男,博客:https://www.cnblogs.com/yinzhengjie 77 */
五.Scala特质Trait使用
1>.Scala特质Trait定义使用
特质(Trait)相当于Java中的Interface,只不过特质(Trait)要比Java中的interface要强大的多,因为特质(Trait)可以定义已经实现的方法,也可以定义没有实现的方法。
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass 7 8 9 /** 10 * Scala的中的接口叫做特质,关键字为trait。 11 * 在Scala中也没有“implements”关键字,只有“extends”关键字 12 * 在Scala特质中可以定义有实现的方法,也可以定义没有实现的方法 13 */ 14 trait ScalaTrait { 15 /** 16 * 定义有实现的方法 17 */ 18 def sayHello()={ 19 println("I'm Yinzhengjie!") 20 } 21 /** 22 * 定义没有实现的方法 23 */ 24 def playGame(name:String) 25 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass 7 8 class ScalaTraitImpl extends ScalaTrait { 9 10 /** 11 * 如果特质中playGame方法没有实现的话,子类在实现的时候可以不加override关键字也可以加 12 */ 13 def playGame(name: String): Unit = { 14 println(s"${name} 正在玩游戏!") 15 } 16 17 /** 18 * 如果特质中某个方法有具体的实现,在子类继承重写的时候,必须使用override关键字 19 */ 20 override def sayHello(): Unit = { 21 //我们的重写过程需要其实就是调用父类的方法 22 super.sayHello() 23 } 24 25 } 26 27 /** 28 * 注意:“object ScalaTraitImpl”是“class ScalaTraitImpl”的伴生对象 29 */ 30 object ScalaTraitImpl{ 31 def main(args: Array[String]): Unit = { 32 val s1 = new ScalaTraitImpl() 33 s1.sayHello() 34 s1.playGame("尹正杰") 35 } 36 } 37 38 39 /* 40 以上代码执行结果如下: 41 I'm Yinzhengjie! 42 尹正杰 正在玩游戏! 43 */
2>.Scala中混入特质的两种方式
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass 7 8 9 /** 10 * Scala的中的接口叫做特质,关键字为trait。 11 * 在Scala中也没有“implements”关键字,只有“extends”关键字 12 * 在Scala特质中可以定义有实现的方法,也可以定义没有实现的方法 13 */ 14 trait ScalaTrait { 15 /** 16 * 定义有实现的方法 17 */ 18 def sayHello()={ 19 println("I'm Yinzhengjie!") 20 } 21 /** 22 * 定义没有实现的方法 23 */ 24 def playGame(name:String) 25 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass 7 8 trait Bird { 9 /** 10 * 定义有实现的方法 11 */ 12 def fly(name:String): Unit ={ 13 println(s"${name} 正在天上飞......") 14 } 15 /** 16 * 定义没有实现的方法 17 */ 18 def sing() 19 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass 7 8 /** 9 * 在定义类时,我们可以用将多个特质混在一起,第一个特质使用extends连接,后续的特质依次使用with连接即可。 10 */ 11 class ScalaTraitImpl extends ScalaTrait with Bird { 12 13 /** 14 * 如果特质中playGame方法没有实现的话,子类在实现的时候可以不加override关键字也可以加 15 */ 16 def playGame(name: String): Unit = { 17 println(s"${name} 正在玩游戏!") 18 } 19 20 /** 21 * 如果特质中某个方法有具体的实现,在子类继承重写的时候,必须使用override关键字 22 */ 23 override def sayHello(): Unit = { 24 //我们的重写过程需要其实就是调用父类的方法 25 super.sayHello() 26 } 27 28 /** 29 * 定义有实现的方法 30 */ 31 override def fly(name: String): Unit = super.fly(name) 32 33 def sing(): Unit = { 34 println("Sing a song!") 35 } 36 } 37 38 39 /** 40 * 注意:“object ScalaTraitImpl”是“class ScalaTraitImpl”的伴生对象 41 */ 42 object ScalaTraitImpl{ 43 def main(args: Array[String]): Unit = { 44 /** 45 * 在Scala中可以动态混入N个特质,各个特质之间使用关键字with连接即可 46 */ 47 val s1 = new ScalaTraitImpl with Bird with ScalaTrait 48 s1.sayHello() 49 s1.playGame("尹正杰") 50 s1.sing() 51 s1.fly("猫头鹰") 52 } 53 } 54 55 56 /* 57 以上代码执行结果如下: 58 I'm Yinzhengjie! 59 尹正杰 正在玩游戏! 60 Sing a song! 61 猫头鹰 正在天上飞...... 62 */
六.Scala中得抽象类abstract
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass 7 8 /** 9 * 1>.使用关键字abstract定义一个抽象类 10 * 2>.抽象类可以具体实现方法 11 * 3>.也可以有具体实现的方法 12 */ 13 abstract class AbstractClass { 14 def eat(food:String):String 15 16 def sayHello() = { 17 println("I'm yinzhengjie!") 18 } 19 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass 7 8 trait Teacher { 9 def palyGame(name:String):String 10 11 def teaching(name:String): Unit ={ 12 println(s"${name} 正在教学生!") 13 } 14 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass 7 8 9 /** 10 * 1>.在Scala中第一个继承抽象类或者特质,只能使用关键字extends 11 * 2>.如果想继承多个独特的话,可以在extends之后使用with关键字。 12 */ 13 object AbstractClassImpl extends AbstractClass with Teacher { 14 override def sayHello(): Unit = { 15 super.sayHello() 16 } 17 18 def eat(food: String): String = { 19 "炒着吃" + food 20 } 21 22 override def palyGame(name: String): String = { 23 s"$name 正在打王者荣耀哟......." 24 } 25 26 def main(args: Array[String]): Unit = { 27 AbstractClassImpl.sayHello() 28 val res1 = AbstractClassImpl.eat("腊肉") 29 println(s"res1 =====> ${res1}") 30 } 31 }
七.Scala中得final和type
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass 7 8 trait Teacher { 9 10 /** 11 * 使用type关键字定义一个自定义类型Yinzhengjie,这个类型并没有被确定,而是让继承者自己去指定。 12 */ 13 type Yinzhengjie 14 15 final def Bodybuilding(s:Yinzhengjie)={ 16 println(s"${s} 正在健身....") 17 } 18 19 20 def palyGame(name:String):String 21 22 /** 23 * 由于teaching方法被我加了关键字final,因此这个方法没法重写(override)! 24 */ 25 final def teaching(name:String): Unit ={ 26 println(s"${name} 正在教学生!") 27 } 28 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass 7 8 /** 9 * 1>.使用关键字abstract定义一个抽象类 10 * 2>.抽象类可以具体实现方法 11 * 3>.也可以有具体实现的方法 12 */ 13 abstract class AbstractClass { 14 def eat(food:String):String 15 16 /** 17 * 由于sayHello方法被我加了关键字final,因此这个方法没法重写(override)! 18 */ 19 final def sayHello() = { 20 println("I'm yinzhengjie!") 21 } 22 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass 7 8 9 /** 10 * final关键字: 11 * 1>.在Scala中,final修饰的类或者方法或者成员变量,不能被重写 12 * 2>.如果使用final关键字修饰类,则该类不能被继承 13 * 3>.如果使用final关键字修饰方法,则该方法不能被重写(override) 14 * 4>.如果使用final关键字修饰成员变量,则该成员变量不能被重新修改(无法再次赋值) 15 * type关键字: 16 * 我们可以理解type的功能就是一个别名。 17 */ 18 final object AbstractClassImpl extends AbstractClass with Teacher { 19 20 /** 21 * 我们在继承的时候,需要指定“Yinzhengjie”的类型,比如我们此处指定其类型为String。 22 */ 23 type Yinzhengjie = String 24 25 def eat(food: String): String = { 26 "炒着吃" + food 27 } 28 29 override def palyGame(name: String): String = { 30 s"$name 正在打王者荣耀哟......." 31 } 32 33 def main(args: Array[String]): Unit = { 34 AbstractClassImpl.sayHello() 35 val res1 = AbstractClassImpl.eat("腊肉") 36 println(s"res1 =====> ${res1}") 37 AbstractClassImpl.Bodybuilding("尹正杰") 38 39 } 40 } 41 42 43 /* 44 以上代码执行结果如下: 45 I'm yinzhengjie! 46 res1 =====> 炒着吃腊肉 47 尹正杰 正在健身.... 48 */
八.Scala中样例类和样例对象
样例类是特殊类,经过了优化处理,经常用于模式匹配。好处是内置实现了众多scala常用的功能,比如serializable、compare、apply、unapply
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.scalaClass 7 8 /** 9 * 样例类: 10 * 1>.在类前加关键字case就是一个样例类 11 * 2>.它支持模式匹配,默认实现了Serializable接口 12 * 3>.具体格式为:case class Message(属性......) 13 * 14 * 定义变量规则: 15 * 1>.类名的定义首字母大写推荐使用驼峰式; 16 * 2>.属性名称第一个字母小写; 17 * 一个标准的命名规则是一个资深开发的基础。 18 */ 19 case class Message(name:String,countent:String) { 20 21 } 22 23 24 /** 25 * 样例对象: 26 * 1>.用于模式匹配 27 * 2>.样例对象不能封装数据 28 * 3>.样例对象格式:case opject 对象名 29 */ 30 case object MonitorServer 31 32 object CaseDemo{ 33 def main(args: Array[String]): Unit = { 34 val message = new Message("杨幂","今天晚上要拍戏......") 35 println(message.name) 36 println(message.countent) 37 } 38 } 39 40 /* 41 以上代码输出结果如下 : 42 杨幂 43 今天晚上要拍戏...... 44 */
九.Scala中得模式匹配---match case
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.function 7 8 object People { 9 10 val (name,age) = ("尹正杰",26) 11 12 def sayHello(): Unit ={ 13 println("I'm yinzhengjie!") 14 } 15 16 def init(): String ={ 17 s"姓名:$name,年龄:${age}" 18 } 19 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.function 7 8 import java.awt.Color 9 10 11 /** 12 * 模式匹配 match case 13 * 一旦一个case 匹配上了,就不会再往下匹配了 14 */ 15 object PatternMatching { 16 def main(args: Array[String]): Unit={ 17 matchingConstant(Color.orange) 18 contentMatch("yinzhengjie") 19 typeMatch(2018) 20 typeMatch(true) 21 arrayMatch(Array(8)) 22 listMatch(1::2::3::Nil) 23 tupleMatch((0, 1)) 24 objMatch(1,2) 25 objMatch(People) 26 } 27 /** 28 * 匹配对象 29 */ 30 def objMatch(obj: Any) = { 31 val res = obj match { 32 case (x, y) =>s"$x $y" 33 case Int => "int" 34 case People => People.init() 35 case _ => "匹配失败!" 36 } 37 println(res) 38 } 39 /** 40 * 匹配元组 41 */ 42 def tupleMatch(tuple: Any) = { 43 val res = tuple match{ 44 case (0, _) => "元组的第一个元素为0, 第二个元素为任意类型的数据,且只有2个元素" 45 case (a, b, c) => "拥有三个元素的元组" 46 case (_, "98K + 八倍镜") => "[98K + 八倍镜] 套装" 47 case _ => "匹配失败!" 48 } 49 println(res) 50 } 51 /** 52 * 匹配List 53 */ 54 def listMatch(list: Any) = { 55 val res = list match{ 56 case 0::Nil => "只有一个0元素的List" 57 case 7::9::Nil => "只有7和9元素的List" 58 case x::y::z::Nil => "只有三个元素的List" 59 case m::n if n.length > 0 => "------" // 拥有head,和 tail的数组, “if n.length > 0” 是守卫条件 60 case _ => "匹配失败!" 61 } 62 println(res) 63 } 64 /** 65 * 匹配Array 66 */ 67 def arrayMatch(arr: Any) = { 68 val res = arr match { 69 case Array(0) => "只有一个0元素的数组" 70 case Array(0, _) => "以0开头的,拥有2个元素的数组" 71 case Array(1, _, 3) => "已1开头,3结尾,中间为任意元素的三个元素的数组" 72 case Array(8, _*) => "已8开头,N个元素的数组" // _*标识0个或者多个任意类型的数据 73 case _ => "匹配失败!" 74 } 75 println(res) 76 } 77 /** 78 * 匹配数据类型 79 */ 80 def typeMatch(tp: Any) = { 81 val res = tp match{ 82 case x: Int => s"Int $x" 83 case y: Long => s"Long $y" 84 case z: Boolean => s"boolean $z" 85 case _ => "匹配失败!" 86 } 87 println(res) 88 } 89 /** 90 * 匹配字符串内容 91 */ 92 def contentMatch(str: String) = { 93 val res = str match{ 94 case "yinzhengjie" => "尹正杰" 95 case "Python" => "Python" 96 case "Golang" => "Golang" 97 case "Java" => "Java" 98 case "2018" => "2018" 99 case _ => "匹配失败!" // "_"用于任意内容 100 } 101 println(res) 102 } 103 /** 104 * 匹配常量 + 守卫条件 105 * 扩展常量问题:大写会识别成常量,小写是变量,如果让小写也是常量,使用``标出 106 */ 107 def matchingConstant(color: Color)={ 108 val res = color match { 109 case Color.RED => "红色" //case Color.RED 匹配结果为 "红色",下面两行代码类似。 110 case Color.GREEN => "绿色" 111 case Color.yellow => "黄色" 112 case _ if color == Color.orange => "恭喜你,中奖了!" //这里定义的就是守卫条件。 113 case _ => "匹配失败!" //case _ 表示匹配任意类型。换句话说,这里定义的是默认匹配情况,即上面的3中匹配均无效。 114 } 115 println(res) 116 } 117 } 118 119 120 121 /* 122 以上代码执行结果如下 : 123 恭喜你,中奖了! 124 尹正杰 125 Int 2018 126 boolean true 127 已8开头,N个元素的数组 128 只有三个元素的List 129 元组的第一个元素为0, 第二个元素为任意类型的数据,且只有2个元素 130 1 2 131 姓名:尹正杰,年龄:26 132 */
十.密封样例类
必须将样例子类和父类定义在一个scala文件中。
//必须将样例子类和父类定义在一个scala文件中。 sealed abstract class Dog case class Jing8(var name:String) extends Dog case class HaShiQi(var name:String) extends Dog