zoukankan      html  css  js  c++  java
  • Scala 学习 (六) 面向对象

    一,scala单例对象

    二,scala类

      2.1 类定义,主构造器,赋值构造器

      2.2 访问权限

      2.3 伴生类,apply方法

    三,特质

    四,抽象类

    五,继承

      5.1 final关键字

      5.2 type关键字

    六,样例类,样例对象

    七,匹配模式

      7.1 匹配字符串,类型,守卫

      7.2 匹配数组

      7.3 匹配集合

      7.4 匹配元组

      7.5 匹配样例类,样例对象

    正文

    一,scala单例对象 

      在 Scala 中,是没有 static 这个东西的,但是它也为我们提供了单例模式的实现方法,那就是使用关键字 object, object 对象不能带参数

      如下实例:

    /** * 单例对象
    */
    
    object ScalaSingleton {
      def saySomething(msg: String) = {
        println(msg)   } } object test {   def main(args: Array[String]): Unit
    = {
        ScalaSingleton.saySomething("滚犊子....")
        println(ScalaSingleton)
        println(ScalaSingleton)     
    // 输出结果:     // 滚犊子....     // cn.demo.ScalaSingleton$@28f67ac7     // cn.demo.ScalaSingleton$@28f67ac7   } }

    二,scala类

      2.1 类定义,主构造器,赋值构造器

      定义类,和一些注意事项:

    /*
    *    在 Scala 中,类并不用声明为 public。
    *    如果你没有定义构造器, 类会有一个默认的空参构造器
    *    var 修饰的变量, 这个变量对外提供 getter setter 方法
    *    val 修饰的变量, 对外提供了 getter 方法,没有 setter
    **/
    
    class Student {
        // _ 表示一个占位符, 编译器会根据你变量的具体类型赋予相应初始值
        // 注意: 使用_ 占位符是, 变量类型必须指定
        var name: String=_
        var age: Int=_
        //    错误代码, val 修饰的变量不能使用占位符
        //    val age: Int = _  因为val修饰的不变的变量
        val school: String = "beida"
    }
    
    object Test{
        var name="zhangsan"
        def main(args: Array[String]): Unit = {
            //    调用空参构造器,可以加() 也可以不
            var stu = new Student()
    
            //    类中使用 val 修饰的变量不能更改
            //    student.school = "nanda"
            stu.name = "laowang"
            println(s"student.name is ${stu.name}") // student.name is laowang
            println(s"test.name is ${Test.name}") // test.name is zhangsan
        }
    }

      定义在类后面的为类主构造器, 一个类可以有多个辅助构造器

    /*
    *    Student1(val name: String, var age: Int)
    *    定义个 2 个参数的主构造器
    **/
    
    class Student1 (val name: String, var age: Int) {
        var gender: String = _
        // 辅助构造器, 使用 def this   
        // 在辅助构造器中必须先调用类的主构造器
        def this(name: String, age:Int, gender: String){ 
            this(name, age)
            this.gender = gender
        }
    }
    
    object Test1{
        def main(args: Array[String]): Unit = {
            // 调用主构造器
            val s = new Student1("laoduan", 38)
            println(s"${s.name} ${s.age}")
            
            // 调用的是辅助构造器
            val s1 = new Student1("laoYang", 18, "male")
            println(s"${s1.gender}")
        }
    }        

      2.2 访问权限

      构造器访问权限

      

    /*
    *    Student1(val name: String, var age: Int)
    *    定义个 2 个参数的主构造器
    *   private 加在主构造器前面标识这个主构造器是私有的, 外部不能访问这个构造器
    *   这里的外部是值只有在本类才可以调用,即本类的辅助构造器才能调用。还有伴生类也可以访问
    **/
    
    class Student1 private (val name: String, var age: Int) {
        var gender: String = _
        // 辅助构造器, 使用 def this
        // 在辅助构造器中必须先调用类的主构造器
        def this(name: String, age:Int, gender: String){
            this(name, age) // 这里调用了主构造器
            this.gender = gender
        }
    }
    
    object Test1{
        def main(args: Array[String]): Unit = {
            // 调用主构造器,若主构造器加上private,这里调用会报错
            val s = new Student1("laoduan", 38)
            println(s"${s.name} ${s.age}")
    
            // 调用的是辅助构造器
            val s1 = new Student1("laoYang", 18, "male")
            println(s"${s1.gender}")
        }
    }

      成员变量访问权限

    /*
    *    private 加在主构造器前面标识这个主构造器是私有的, 外部不能访问这个构造器
    *    private var age
    *    age 在这个类中是有 getter setter 方法的
    *    但是前面如果加上了 private 修饰, 也就意味着, age 只能在这个类的内部以及其伴生类对象中可以访问修改
    *    其他外部类不能访问
    **/
    
    class Student2 private (val name: String, private var age: Int){
        var gender: String = _
    
        def this(name: String, age: Int, gender: String){
            this(name, age)
            this.gender = gender
        }
    
        // private[this]关键字标识该属性只能在类的内部访问, 伴生类不能访
        private [this] val province: String = "北京"
    
        def getAge = 18
    }
    
    //
    // 类的伴生对象
    object Student2{
        def main(args: Array[String]): Unit = {
            //伴生对象可以访问类的私有方法和属性
            var s2 = new Student2("老王", 18)
            s2.age = 19
            println(s"${s2.age}")
            // println(s"${s2.province}") 伴生类不能访问
        }
    }

      类包的访问权限

    /*
    *    private[包名] class 放在类声明最前面, 是修饰类的访问权限, 也就是说类在某些包下不可见或不能访问
    *    private[sheep] class 代表 student3 在 sheep 包下及其子包下可以见, 同级包中不能访问
    *
    * */
    
    private [this] class Student3(val name: String, private var age: Int){
        var xx: Int = _
    }
    
    object Student3{
        def main(args: Array[String]): Unit = {
            var s3 = new Student3("wallace", 16)
            println(s"${s3.name}")
        }
    }

      2.3 伴生类,apply方法

      在 Scala 中, 当单例对象与某个类共享同一个名称时,他被称作是这个类的伴生对象。必须在同一个源文件里定义类和它的伴生对象。类被称为是这个单例对象的伴生类。类和它的伴生对象可以互相访问其私有成员。

    三,特质

      Scala Trait(特质) 相当于 Java 的接口,实际上它比接口还功能强大。与接口不同的是,它还可以定义属性和方法的实现。一般情况下 Scala 的类只能够继承单一父类,但是如果是 Trait(特质) 的话就可以继承多个,实现了多重继承。使用的关键字是trait .

    trait TDemo2 {
        // 特质属性
        var className: String = "牛B班"
        
        // 特质无实现方法
        def teacherSay(name: String)
        
        // 特质有实现方法
        def doSomeThing()={
            print("aaaa")
        }
    
    }

    四,抽象类

      在scala中,使用abstract修饰的类为抽象类,在抽象类中可以定义属性,未实现的方法和已实现的方法。

      如下实例:

    abstract class AbsDemo1 {
        // 抽象类属性
        var className: String = "牛B班"
    
        // 抽象类未实现方法
        def teacherSay(name: String)
    
        // 抽象类已实现方法
        def doSomeThing()={
            print("aaaa")
        }
    }

    五,继承

      继承是面向对象的概念,用于代码的可重用性,被扩展的类称为超类或父类,扩展的类称为派生类或子类。Scala可以通过使用extends关键字来实现继承获其他类获特质。

      父类:

    abstract class Animal {
        // 定义一个name属性
        val name: String = "animal"
        // 没有任何实现的方法
        def sleep()
        // 带有实现的方法
        def eat(f: String)={
            println("$f")
        }
    }

      子类:

    class Dog extends Animal {
        /*
        * with 后面只能是特质
        * 父类已经实现了的功能, 子类必须使用 override 关键字重写
        * 父类没有实现的方法,子类必须实现
        * */
        override val name: String = "Dog"
    
        override def sleep(): Unit = {
            println("躺着睡。。。。")
        }
    }

      5.1 final关键字

      被 final 修饰的类不能被继承;
      被 final 修饰的属性不能重写;
      被 final 修饰的方法不能被重写

      5.2 type关键字

      Scala 里的类型,除了在定义 class,trait,object 时会产生类型,还可以通过 type 关键字来声明类型。

      type 相当于声明一个类型别名:

      父类:

    trait StudentTrait {
    
        type T
    
        def learn(s: T) = {
            println(s)
        }
    
    }

      子类:

    object Student1 extends StudentTrait{
        override type T = String
    
        def main(args: Array[String]): Unit = {
            Student1.learn("String")
        }
    }
    
    object Student2 extends StudentTrait {
        override type T = Int
    
        def main(args: Array[String]): Unit = {
            Student2.learn(100)
        }
    }

    六,样例类,样例对象

    /*
    * 样例类,使用 case 关键字 修饰的类, 其重要的特征就是支持模式匹配
    * 样例类默认是实现了序列化接口的
    * */
    case class Message(msgContent: String)
    /*
    * 样例 object, 不能封装数据, 其重要特征就是支持模式匹配
    **/
    case object CheckHeartBeat
    object TestCaseClass  extends App{
        // 可以使用 new 关键字创建实例, 也可以不使用
        val msg = Message( "hello")
        println (msg .msgContent)
    }

    七,匹配模式

      7.1 匹配字符串,类型,守卫

    val arr = Array ( "YoshizawaAkiho", "YuiHatano", "AoiSola")
    val i = Random.nextInt( arr .length)
    println ( i )
    val name = arr ( i )
    println ( name )
    name h match {
        case " "YoshizawaAkiho" => println (" " 吉泽老师 ...")
        case " "YuiHatano" => {
            println (" " 波多老师 ...")
        }
        case _ => println (" " 真不知道你们在说什么 ...")
    }
    
    println ( "----------- 骚气的分割线 -----------")
    //定义一个数组
    
    val arr :Array[Any] = Array ( "hello123", 1, 2.0, CaseDemo02, 2L)
    //取出一个元素
    val elem = arr (3)
    
    elem h match {
        case x: Int => println (t "Int " " + x)
        case y: Double if(y >= 0) => println ("Double " "+ y) // if 守卫
        case z: String => println (g "String " " + z)
        case w: Long => println (g "long " " + w)
        case CaseDemo02 => {
            println ("case o demo 2")
            //throw new Exception("not match exception")
        }
        case _ => { // 其他任意情况
            println ( "no")
            println ( "default")
        }
    }

      7.2 匹配数组

    val arr = Array (1, 1, 7, 0, 2,3)
    arr h match {
        case Array (0, 2, x, y) => println (x + " " " " + y)
        case Array (2, 1, 7, y) => println (y "only 0 0 " " + y)
        case Array (1, 1, 7, _*) => println (0 "0 ...") // _* 任意多个
        case _ => println (g "something else")
    }

      7.3 匹配集合

    val lst = List(0, 3, 4)
    println(lst.head)
    println(lst.tail)
    lst match {
        case 0 :: Nil => println ("only 0")
        case x :: y :: Nil => println (s"x $x y $y" ")
        case 0 :: a => println (s"value: $a")
        case _ => println ("something else")
    }

      7.4 匹配元组

    val tup = (1, 3, 7)
    tup match {
        case (3, x, y) => println (s"hello 123 $x,$y")
        case (z, x, y) => println (s"$z,$x,$y")
        case (_, w, 5) => println (w)
        case _ => println("else")
    }

      7.5 匹配样例类,样例对象

    //样例类,模式匹配,封装数据(多例),不用 new 即可创建实例
    case class SubmitTask(id: String, name: String)
    case class HeartBeat(time: Long)
    //样例对象,模式匹配(单例)
    case object CheckTimeOutTask
    val arr = Array (CheckTimeOutTask, new HeartBeat(123), HeartBeat (88888), new HeartBeat(666), SubmitTask ("0001","task-0001"))
    val i = Random.nextInt( arr .length)
    val element = arr ( i )
    println( element )
    element match {
        case SubmitTask (id, name) => {
            println (s"$id,$name")
        }
        case HeartBeat (time) => {
            println (time)
        }
        case CheckTimeOutTask => {
            println ("check")
        }
    }
  • 相关阅读:
    golang 反射和利用反射取结构体值
    golang 实现Lru
    跨域
    JS原型链
    cookie 、sessionStorage与localStorage的区别
    计算真实div盒子的宽度和高度
    div水平垂直居中
    清除浮动的几种方法
    JS中for循环和定时器的小问题
    转换字符串和转换数字类型
  • 原文地址:https://www.cnblogs.com/tashanzhishi/p/10959226.html
Copyright © 2011-2022 走看看