Scala--第七天

一、内部类

  定义:实现一个抽象类 或者 Trait 时 可以通过内部类的方式完成

 1   abstract class Cmx {
 2     def func: Unit
 3 
 4   }
 5 
 6   def main(args: Array[String]): Unit = {
 7     var cmx = new Cmx {
 8       override def func: Unit = {
 9         println("我是内部类")
10       }
11     }
12     cmx.func
13     //我是内部类
14   }

二、特质 Trait

  定义:类似于其它语言的接口

  格式:trait 名称{

      //抽象成员方法或属性

      //普通成员方法或属性

      }

  注意:Trait中的抽象成员 必须全部实现 ,不然程序报错,如果实现不完整 只能称这个类为抽象类 需要加上abstract字段

 1   trait cmx {
 2     //抽象属性和普通属性
 3     var name: String
 4     var age = 10
 5 
 6     //抽象方法和普通方法
 7     def func(): Unit
 8 
 9     def func1(): Unit = {
10       println("我是特质的普通方法")
11     }
12   }
13 
14   class cmx01 extends cmx {
15     override var name = "cmx01"
16 
17     override def func(): Unit = {
18       println("必须重写")
19     }
20   }
21 
22   def main(args: Array[String]): Unit = {
23     var a = new cmx01
24     a.func()
25     println(a.name)
26     //必须重写
27     //cmx01
28   }

  Trait与abstract的区别

  1.  abstract是单根继承体系,只能继承一个父类

       Trait是多继承体系,可以被继承多个父类,使用关键字with
  2.  在实战中,抽象类 表达的是 抽象的概念 名词

           trait 表达的是 抽象的行为 动词

 1   区别一
 2   class Person
 3 
 4   trait Cmx
 5 
 6   trait Cmx01
 7 
 8   class User extends Person with Cmx with Cmx01 {
 9     print("---------")
10   }
11 
12   def main(args: Array[String]): Unit = {
13     var a = new User
14     //主构造器的返回结果
15     //---------
16   }
 1   区别二
 2 //打印日志是实际的动作,是个动词
 3   trait Logger {
 4     def log(msg: String)
 5   }
 6 
 7   class ConsoleLogger extends Logger {
 8     override def log(msg: String): Unit = println(s"---控制台打印日志${msg}---")
 9   }
10 
11   class DBLogger extends Logger {
12     override def log(msg: String): Unit = println("----数据库存储日志----")
13   }
14 
15 
16   def main(args: Array[String]): Unit = {
17     var logger = new ConsoleLogger
18     logger.log("ok")
19     //---控制台打印日志ok---
20   }

  object 继承trait

 1   trait cmx {
 2     def func(): Unit
 3   }
 4 
 5   object A extends cmx {
 6     override def func(): Unit = {
 7       println("单例对象继承特质类")
 8     }
 9   }
10 
11   def main(args: Array[String]): Unit = {
12     A.func()
13     //单例对象继承特质类
14   }

  trait 可以和父类共存,但是注意父类一定要在前面,trait在后面,因为之后trait才能用with关键字

  以下案例,将演示以上的案例,同时演示继承的构造顺序

 1   class Person {
 2     println("执行Person构造器")
 3   }
 4 
 5   trait Cmx {
 6     println("执行Cmx构造器")
 7   }
 8 
 9   trait Cmx01 extends Cmx {
10     println("执行cmx01构造器")
11   }
12 
13   trait Cmx02 extends Cmx {
14     println("执行cmx02构造器")
15   }
16 
17   class User extends Person with Cmx01 with Cmx02  {
18     print("执行User构造器")
19   }
20 
21   def main(args: Array[String]): Unit = {
22     var a = new User
23     //执行Person构造器
24     //执行Cmx构造器
25     //执行cmx01构造器
26     //执行cmx02构造器
27     //执行User构造器
28   }

  对象混入trait

 1   class Cmx() {
 2     def func(): Unit = {
 3       println("我是一个普通的类")
 4     }
 5   }
 6 
 7   trait Cmx01 {
 8     def func1(): Unit = {
 9       println("我是一个特质的类")
10     }
11   }
12 
13   def main(args: Array[String]): Unit = {
14     var a = new Cmx with Cmx01
15     a.func()
16     a.func1()
17     //我是一个普通的类
18     //我是一个特质的类
19   }

  trait 也可以继承class

 1   class Cmx() {
 2     def func(): Unit = {
 3       println("我是一个普通的类")
 4     }
 5   }
 6 
 7   trait Cmx01 extends Cmx {
 8     def func1(): Unit
 9   }
10 
11   class Test extends Cmx01 {
12     override def func1(): Unit = {
13       println("我是一个特质的实现")
14     }
15   }
16 
17   def main(args: Array[String]): Unit = {
18     var a = new Test
19     a.func()
20     a.func1()
21     //我是一个普通的类
22     //我是一个特质的实现
23   }

三、样例类

  定义:一种特殊的类,用来快速定义一个保存数据的类,类似与Java的实体,在后续spark,flink中及其重要

  回顾已经学过的类:类,单例对象,半生对象,抽象类,Trait类,样例类

  语法: case class 类名(属性名:属性类型...){...}        ##这种写法,属性值的修饰符 是 val  ,属性值不可变

      case class 类名(var 属性名:属性类型...){...}   ##这种写法 的属性值可以改变

  注意:样例类使用来存储数据用的,所以没有方法

 1   case class Cmx(var name: String) {
 2 
 3   }
 4 
 5   def main(args: Array[String]): Unit = {
 6     var a = Cmx("cmx")
 7     println(a.name)
 8     //cmx
 9     a.name = "cmx01"
10     println(a.name)
11     //cmx01
12   }

  样例类的隐含方法

  1.apply:快速创建对象,省去new关键字的书写

  2.toString:将对象的内容,自动转换成字符串显示;而普通的类默认输出的是这个对象的地址(包.单利对象$类名@16进制hash码)

 1   //普通类,改写默认方法
 2   class Cmx(name: String) {
 3     override def toString: String = {
 4       return s"name= ${name}"
 5     }
 6   }
 7 
 8   //普通类,为改写默认方法
 9   class Cmx01(name: String) {}
10 
11   def main(args: Array[String]): Unit = {
12     var a = new Cmx("cmx")
13     var b = new Cmx01("cmx01")
14     println(a.toString)
15     //name= cmx
16     println(b.toString)
17     //cmx_test.test2$Cmx01@d041cf   #@符号后的是十六进制的哈希码
18     println(b.hashCode())
19     //13648335   #这个方法返回的是十进制的哈希码
20     println(Integer.toHexString(b.hashCode()))
21     //d041cf    #结果和前面的一样
22   }

  3.equals方法:可以进行样例类,内容的比较

    判断引用的方法eq()

    判断内容的方法 equals(),==

 1   case class Cmx(name: String) {}
 2 
 3   def main(args: Array[String]): Unit = {
 4     var a = Cmx("cmx")
 5     var b = Cmx("cmx")
 6     println(a.equals(b))
 7     //true
 8     println(a.eq(b))
 9     //false
10   }

  4.hascode方法:获取对象的哈希码,用于进行哈希操作,进行去重操作

    注意:每个对象都有哈希码,但是哈希码不能代表对象的唯一标识

       同一个对象的哈希码一定是相同的,不同对象的哈希码有可能是相同的

 1   case class Cmx(name: String) {
 2 
 3   }
 4 
 5   def main(args: Array[String]): Unit = {
 6 
 7     var a = Cmx("cmx")
 8     var b = Cmx("cmx")
 9     println(a.hashCode())
10     println(b.hashCode())
11     println(a.eq(b))
12     //结果验证样例类的哈希码和内容保持一致,说明样例类修改了原来类的hashCode()
13     //-351660709
14     //-351660709
15     //false
16   }

  5.copy方法:快速实现一个相同的对象(指的是数据内容相同)

1   case class Person(name: String, age: Int)
2 
3   def main(args: Array[String]): Unit = {
4     var a = Person("cmx", 11)
5     var b = a.copy("cmx01")
6     print(b.toString)
7     //Person(cmx01,11)
8   }

四、样例对象

  语法: case object 对象名字

  定义枚举 : 一个类型 有有限的对象 (Sex Season ),在scala中通过 trait 和 样例对象 可以配合定义枚举类型

 1   //性别 特质类
 2   trait Sex
 3 
 4   //样例对象 继承性别类
 5   case object Male extends Sex
 6 
 7   case object Female extends Sex
 8 
 9   //样例类 参数性别的类型是Sex
10   case class Person(name: String, sex: Sex)
11 
12 
13   def main(args: Array[String]): Unit = {
14     var p = Person("suns", Male)
15     var p1 = Person("liwj", Female)
16   }

五、模式匹配

  1.基本匹配

  2.类型匹配

  3.if条件判断匹配 守卫

  4.样例类匹配

  5.集合匹配
  6.变量声明中的模式匹配

1     //基本匹配
2     var a = StdIn.readLine()
3     a match {
4       case "cmx" => println("cmx")
5       case "cmx01" => println("cmx01")
6       case _ => println("都不是")
7     }
8     //cmx
 1     //类型匹配
 2     var a: Any = 10
 3     //模式匹配是可以有返回值的
 4     //可以用一个参数代表a的值, 借以使用
 5     var b = a match {
 6       case x: String => s"String${x}"
 7       case x: Int => s"Int${x.toString}"
 8     }
 9     //println(b)
10     //Int10
1     //if 条件判断 守卫
2     var a = 7
3     a match {
4       case _ if a >= 0 && a <= 3 => println("0---3")
5       case _ if a >= 4 && a <= 8 => println("4---8")
6       case _ => println("为匹配")
7     }
8     //4---8
 1     //样例类匹配
 2     case class Cmx(name: String)
 3     case class Cmx01(age: Int)
 4     var m: Any = Cmx("cmx")
 5     var p: Any = Cmx01(20)
 6     p match {
 7       case Cmx(name) => println("cmx类")
 8       case Cmx01(age) => println("cmx01类")
 9     }
10     //cmx01类
 1     //集合匹配
 2     //三种形式
 3     /*
 4       List(1,_*):以1开头的列表
 5       List(1):只有1一个元素的列表
 6       List(1,x,y):以1 开头只有三个元素的列表
 7       */
 8     var a = List(1, 2, 3, 4)
 9     a match {
10       case List(1, _*) => println("该列表是1以开头的")
11       case List(1, x, y, z) => println("该列表共有4个元素")
12       case List(1) => println("该列表只有1 一个元素")
13     }
14     //该列表是1以开头的
1     var a = List(1, 2, 3, 4)
2     a match {
3       case 1 :: x :: y :: Nil => println("三个元素")
4       case 1 :: tail => println("以1开头的列表") // tail 代表尾部 可以用其他代替
5       case 1 :: n if n.length > 0 => println("以1开头的列表1")
6       case _ => println("其他")
7     }
8     //以1开头的列表
 1     //变量声明过程中的模式匹配
 2     //数组形式
 3     var a = (1 to 10).toArray
 4     var Array(_, x, y, _*) = a
 5     println(x, y)
 6     //(2,3)
 7 
 8     //列表形式
 9     var b = (1 to 10).toList
10     //tail也是个定位符,可以换成任意字符
11     var x :: y :: tail = b
12     println(x, y)
13     //(1,2)

  

原文地址:https://www.cnblogs.com/cmxbky1314/p/12300610.html