zoukankan      html  css  js  c++  java
  • Scala:(五) 类、对象、继承、模式匹配和样例类

    一般类名首字母大写 ,方法首字母小写,类和方法命名建议符合驼峰命名法。

    1. scala中的class类默认可以传参数,默认的传参数就是默认的构造函数。重写构造函数的时候,必须要调用默认的构造函数。
    2. 在Scala中,类并不用声明为public。Scala源文件中可以包含多个类,所有这些类都具有公有可见性。
    3. class 类属性自带getter ,setter方法。用val修饰的变量是只读属性,有getter但没有setter(相当与Java中用final修饰的变量);用var修饰的变量既有getter又有setter
    4. 类私有字段,只能在类的内部使用;

    定义一个类

    class Person{
      val name = "zhangsan"
      val age = 18
      def sayName() = {
        "my name is "+ name
      }
    }
    

    构造器

    对象

    定义一个对象
    在Scala中没有静态方法和静态字段,但是可以使用object这个语法结构来达到同样的目的。使用object时,不用new,使用class时要new ,并且new的时候,class中除了方法不执行,其他都执行。

    1.存放工具方法和常量
    2.高效共享单个不可变的实例
    3.单例模式

    object Lesson_Class {
       def main(args: Array[String]): Unit = {
        val person = new Person()
        println(person.age);
        println(person.sayName())
      }
    }
    

    伴生对象

    如果在同一个文件中,object对象和class类的名称相同,则这个对象就是这个类的伴生对象(在Scala的类中,与类名相同的对象叫做伴生对象),这个类就是这个对象的伴生类。可以互相访问私有变量。

    
    // 类
      class Car{
      // 私有属性
        private var name = "laosiji"
    
        def printName(): Unit ={
          //在Dog类中可以访问伴生对象Dog的私有属性
          println(Car.myCar + name )
        }
      }
    
    // 与类同名的,伴生对象
      object Car {
        //伴生对象中的私有属性
        private val myCar = "老司机,来开车啦: "
    
        def main(args: Array[String]) {
          val car = new Car
          //可以访问私有的字段name
          car.name = "老老司机"
          // 调用其方法
          car.printName()
        }
      }
    

    应用程序对象

    Scala程序都必须从一个对象的main方法开始,可以通过扩展App特质,不写main方法

    object AppObjectDemo extends App{
      //不用写main方法
      println("I love you Scala")
    }
    

    继承

    在Scala中扩展类的方式和Java一样都是使用extends关键字,在Scala中重写一个非抽象的方法必须使用override修饰符
    类型检查和转换

    Scala Java
    obj.isInstanceOf[C] obj.instanceof( C)
    obj.asInstanceOf[C] (C)obj
    classOf[C] C.class

    代码直接看下面trait中菜鸟教程的代码即可

    Trait

    Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。与接口不同的是,它还可以定义属性和方法的实现
    这里的trait字面意思是特质或者特征,这个词翻译成特征比较合适。它的意义和java,c#中接口很类似。但是trait支持部分实现,也就是说可以在scala的trait中可以实现部分方法。
    一般情况下Scala的类可以继承多个Trait,从结果来看就是实现了多重继承。Trait(特征) 定义的方式与类类似,但它使用的关键字是 trait。
    继承的多个trait中如果有同名的方法和属性,必须要在类中使用“override”重新定义。
    trait中不可以传参数

    trait Read {
      val readType = "Read"
      val gender = "m"
      def read(name:String){
    	println(name+" is reading")
      }
    }
    
    trait Listen {
      val listenType = "Listen"
      val gender = "m"
      def listen(name:String){
    	println(name + " is listenning")
      }
    }
    
    class Person() extends Read with Listen{
      override val gender = "f"
    }
    
    object test {
      def main(args: Array[String]): Unit = {
        val person = new Person()
        person.read("zhangsan")
        person.listen("lisi")
        println(person.listenType)
        println(person.readType)
        println(person.gender)
        
      }
    }
    

    一下引用菜鸟教程的部分内容,原文摘录:

    /* 文件名:Test.scala
     * author:菜鸟教程
     * url:www.runoob.com
     */
    trait Equal {
      def isEqual(x: Any): Boolean
      def isNotEqual(x: Any): Boolean = !isEqual(x)
    }
    
    class Point(xc: Int, yc: Int) extends Equal {
      var x: Int = xc
      var y: Int = yc
      def isEqual(obj: Any) =
        obj.isInstanceOf[Point] &&
        obj.asInstanceOf[Point].x == x
    }
    
    object Test {
       def main(args: Array[String]) {
          val p1 = new Point(2, 3)
          val p2 = new Point(2, 4)
          val p3 = new Point(3, 3)
    
          println(p1.isNotEqual(p2))
          println(p1.isNotEqual(p3))
          println(p1.isNotEqual(2))
       }
    }
    

    执行结果为:

    false
    true
    true
    

    模式匹配

    Scala有一个十分强大的模式匹配机制,可以应用到很多场合:如switch语句、类型检查等。并且Scala还提供了样例类,对模式匹配进行了优化,可以快速进行匹配
    一个模式匹配包含了一系列备选项,每个都开始于关键字 case。
    每个备选项都包含了一个模式及一到多个表达式。箭头符号 => 隔开了模式和表达式。

    object BasicTest {
      def main(args: Array[String]): Unit = {
        val tuple = Tuple6(1, 2, 3f, 4, "abc", 55d)
        // 可以使用 Tuple.productIterator() 方法来迭代输出元组的所有元素
        val tupleIterator = tuple.productIterator
        while (tupleIterator.hasNext) {
          matchTest(tupleIterator.next())
        }
      }
      /**
       * 注意点:
       * 1.模式匹配不仅可以匹配值,还可以匹配类型
       * 2.模式匹配中,如果匹配到对应的类型或值,就不再继续往下匹配
       * 3.模式匹配中,都匹配不上时,会匹配到 case _ ,相当于default
       */
      def matchTest(x: Any) = {
        x match {
          case x: Int => println("type " + x +" is Int" )
          case 1 => println("result " + x +" is 1")
          case 2 => println("result " + x +" is 2")
          case 3 => println("result " + x +" is 3")
          case 4 => println("result " + x +" is 4")
          case x: String => println("type " + x +"  is String")
          case _ => println(x + " no match")
        }
      }
    }
    

    样例类

    样例类可简单理解为就是一个Java中的实体类,只不过其默认实现了无参和全参的构造器(当然如果参数有默认值的话,使用的地方有默认值的参数可不传)。
    其使用时可以不用new关键字(实现了apply方法);其内val定义的变量默认实现getter方法;var定义的变量默认实现get和set方法;还默认实现了tostring,eques等方法
    case class是多例的,case object是单例的
    借用小伙伴的一段代码来表示其使用:
    定义了一个样例类

    case class DPISrcDataStatistic( prov_id : String , prov_id1 : String = "j") {
      //统计字段记录数
      var total_count   = 1L
      //统计字段异常或空值记录数
      var device_number_exce   = 0L
      var lac_exce             = 0L
    

    使用该样例类

    val tmp = DPISrcDataStatistic(provId)
        lineArray.indices.foreach(x => {
          x match {
            case 0 =>  if(lineArray(x).isEmpty) tmp.device_number_exce   = 1
            case 1 =>  if(lineArray(x).isEmpty) tmp.lac_exce             = 1
            case 2 =>  if(lineArray(x).isEmpty) tmp.ci_exce              = 1
            case _  => log.warn(s"省份: ${provId} 原数据: ${lineArray.mkString("|")}   问题列: ${lineArray(x)}")
          }
        })
    
  • 相关阅读:
    5.24Java对象流
    6.1Java多线程抢票龟兔赛跑
    5.29把分散的文件合并
    6.2Java静态代理设计模式
    5.31Java多线程继承
    5.31Java多线程开篇>java.thread
    6.1JavaStartThread
    命令行查看java classpath设置
    文本自动与不自动换行
    Tomcat 6 虚拟目录配置方法
  • 原文地址:https://www.cnblogs.com/missedyou/p/13276761.html
Copyright © 2011-2022 走看看