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

           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}\n")
13         //对单例模式的类中的非私有成员变量进行修改操作,但前提是这个变量需要用关键字var来声明
14         ScalaStatic.age = 26
15         print(s"res1=====> ${res1}\n")
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  */
Demo.scala 文件内容(调用辅助构造方法案例展示)

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  */
Demo.scala 文件内容(调用主构造方法案例展示)

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  */
Demo.scala 文件内容(调用辅助构造方法案例展示)

 

四.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 }
ScalaTrait.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 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 }
ScalaTrait.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 trait Bird {
 9     /**
10       * 定义有实现的方法
11       */
12     def fly(name:String): Unit ={
13         println(s"${name} 正在天上飞......")
14     }
15     /**
16       * 定义没有实现的方法
17       */
18     def sing()
19 }
Bird.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   * 在定义类时,我们可以用将多个特质混在一起,第一个特质使用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 }
AbstractClass.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 trait Teacher {
 9     def palyGame(name:String):String
10 
11     def teaching(name:String): Unit ={
12         println(s"${name} 正在教学生!")
13     }
14 }
Teacher.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中第一个继承抽象类或者特质,只能使用关键字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 }
Teacher.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   *     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 }
AbstractClass.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   * 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 }
People.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.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

 

posted @ 2018-07-25 12:44  尹正杰  阅读(678)  评论(0编辑  收藏  举报