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

转载于:https://www.cnblogs.com/yinzhengjie/p/9365342.html

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

  1. Scala进阶之路-并发编程模型Akka入门篇

    Scala进阶之路-并发编程模型Akka入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Akka Actor介绍 1>.Akka介绍 写并发程序很难.程序员不得不处 ...

  2. python对象编程例子-Python3.5面向对象编程图文与实例详解

    本文实例讲述了Python3.5面向对象编程.分享给大家供大家参考,具体如下: 1.面向过程与面向对象的比较 (1)面向过程编程(procedural programming) 面向过程编程又被称为: ...

  3. 面向对象编程(Python版详解)

    [辰兮要努力]:hello你好我是辰兮,很高兴你能来阅读,昵称是希望自己能不断精进,向着优秀程序员前行! 博客来源于项目以及编程中遇到的问题总结,偶尔会有读书分享,我会陆续更新Java前端.后台.数据 ...

  4. WebRTC学习进阶之路 --- 五、WebRTC网络知识详解(三)(最全流媒体协议(RTP/RTCP/RTSP/RTMP/MMS/HLS/HTTP/ HTTP-FLV(HDL)/SDP)

    WebRTC学习进阶之路系列总目录:https://blog.csdn.net/xiaomucgwlmx/article/details/103204274 RTP:实时传输协议(Real-time ...

  5. python类的使用方法图解_Python3.5面向对象编程图文与实例详解

    本文实例讲述了Python3.5面向对象编程.分享给大家供大家参考,具体如下: 1.面向过程与面向对象的比较 (1)面向过程编程(procedural programming) 面向过程编程又被称为: ...

  6. python编程实例详解-Python3.5面向对象编程图文与实例详解

    本文实例讲述了Python3.5面向对象编程.分享给大家供大家参考,具体如下: 1.面向过程与面向对象的比较 (1)面向过程编程(procedural programming) 面向过程编程又被称为: ...

  7. 网工进阶之路之华为VRRP配置实验详解 ----尚文网络奎哥

    这些年来,我们越来越关注网络的可靠性,一个高效的网络一定不是会频繁断网,或者断网一次需要长时间才可以恢复的,那么今天我们就来了解下网络高可靠性的一个相关技术VRRP的配置. 另外管理系统相关可靠性可以 ...

  8. Scala进阶之路-正则表达式案例

    Scala进阶之路-正则表达式案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 废话不多说,正则大家都很清楚,那在Scala如何使用正则了?我们直接上个案例,如下: 1 /* 2 ...

  9. python编程语法-Python编程入门——基础语法详解(经典)

    今天小编给大家带来Python编程入门--基础语法详解.温馨提示: 亮点在最后! 在这里还是要推荐下我自己建的Python开发学习群:301056051,群里都是学Python开发的,如果你正在学习P ...

最新文章

  1. linux sed命令处理文本文件
  2. 关于mac注册机core keygen在10.12及以上版本不能使用的解决方法
  3. Strange Optimization(扩展欧几里得)
  4. 普通高中段计算机学科知识,高中计算机学科的特点及教学内容浅探
  5. SQL Server 创建表
  6. gis计算机信息技术,信息技术(IT)对GIS的影响
  7. Gmail地址图片注册...
  8. python itertools卡死_python中的itertools的使用详解
  9. LTE下行物理层传输机制(5)-DCI格式的选择和DCI1A
  10. 解决hdfs dfs -mkdir input报错`mkdir`:No such file or directory
  11. 全网最全计算机二级C语言知识总结,还不快来白嫖
  12. Excel如何批量删除所有空格
  13. .so文件(so文件是什么)
  14. linux下ScrollLock键盘灯不亮
  15. 代码本色 processing编程练习
  16. html图片标签 imag
  17. 在word2016中对图片插入题注
  18. 仿真中的连续系统和离散系统
  19. 10款大数据处理编程语言
  20. 好用的开源轻量级DHCP和DNS服务软件“Dual DHCP DNS Server”

热门文章

  1. Sql Server实用操作-存储过程精解
  2. shell编程-条件判断
  3. 深入理解javascript原型和闭包(6)——继承
  4. .NET一个线程更新另一个线程的UI(两种实现方法及若干简化)
  5. [CentOS] CentOS 使用yum安装 php,mysql, apache
  6. 利用libswscale转换yuyv422到yuv422p或rgb之间的转换, 视频翻转
  7. [转载]Eclipse SVN插件比较 Subclipse vs Subversive
  8. 分享一些有趣的面试智力题
  9. Emai乱码——解决的“迂回”战术
  10. (一).NET SubSonic2.0 的配置