zoukankan      html  css  js  c++  java
  • 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)

      

  • 相关阅读:
    时间模块(二)datetime
    xmltodict模块
    C和指针
    C和指针指针
    笔试2
    istream_iterator,ostream_iterator与vector的转换
    C++工厂方法与反射的简单实现
    rpcndr.h和wtypes.h冲突Bug的解决方案
    ubuntu 9.04 安装mysql
    QT in Ubuntu cannot find lfreetype
  • 原文地址:https://www.cnblogs.com/cmxbky1314/p/12300610.html
Copyright © 2011-2022 走看看