zoukankan      html  css  js  c++  java
  • Scala-Unit5-Scala面对对象与模式匹配

      Java中的面向对象:万物皆对象。

      我们要封装数据,定义模板等操作,素以我们需要面向对象。

    =========================================================================

    一、Scala中的单例对象

      在java中用static关键字修饰方法或成员变量,作用是可以直接通过"类名."的方式调用方法或变量

      在Scala中没有static关键字,Scala给我们提供了单例对象的模式来实现,关键字是object

    object Person {
      //定义成员变量
      val name:String = "Hunter"
      //定义类方法
      def sleep(str:String):Unit= {
        println(str)
      }
    }
    
    object ScalaDemo{
      def main(args: Array[String]): Unit = {
        print(Person.name)
        Person.sleep("睡得很香")
      }
    }
    

      在Scala中的object是一个单例对象,object中定义的方法和成员变量都是静态的,在其他的单例对象中可以直接通过“类名.”的方式进行调用。

      main方法也只能定义在object中,因为java中main方法为静态方法。

      通过class创建的类中定义的方法和对象不能直接调用,不许构造函数对象后才可调用。

    二、Scala类与构造器的使用

      1.类的定义和使用,例子:

    class Person1 {
      //定义成员变量姓名、年龄
      var name:String = _
      var age:Int = _
      //注释:_的意思是不给定,可以在其他类或单例对象中调用赋值,所以用var定义
    }
    
    //继承App特质,可以不写main方法,类似java的Test/Before
    object Test1 extends App{
      val p  = new Person1
      p.name = "reba"
      p.age = 18
      println(p.name + p.age + "岁")
    }
    

      2.主构造器:写在类名后面的构造器是主构造器 

    class Person2 (name:String,age:Int){
    
    }
    
    object Test2 extends App{
      val p = new Person2("yangmi",24)
      println(p)
      println(p.toString)     //这两行输出的都是地址,原因见辅助构造器
    }
    

      注意:主构造器里的变量没有var,val修饰不能被调用

      3.辅助构造器:定义在类内部的构造器,一个类中可以有多个辅助构造器

    class Person3 (var name:String,age:Int){
      var high:Int = _
      var weight:Int = _
    
      //定义辅助构造器
      def this(name:String,age:Int,high:Int){
        this(name,age)
        this.high = high
      }
    
      //辅助构造器可以定义多个
      def this(name:String,age:Int,high:Int,weight:Int){
        this(name,age)
        this.high = high
        this.weight = weight
      }
    }
    
    object Test3 extends App{
      val p = new Person3("Hunter",34,180,140)
      p.weight = 150
      println(p.name + "身高:" +p.high + ",体重:" + p.weight)
    }
    

      注意:(1)辅助构造器内必须先声明主构造器中的所有变量,在声明自己的变量

         (2)Scala中主构造器中的变量如果没有被val、var修饰的话,是不能被访问的,
             相当于java没有给这个变量get/set方法;
             如果主构造器中的变量被val修饰,相当于提供了java中的get方法,
             如果主构造器中的变量被var修饰,相当于提供了java中的get和set方法。

      4.构造器的访问权限:private

        在主构造器或辅助构造器前添加private关键字修饰,即可限制其访问权限

    //定义私有主构造器
    class Person4 private(var name:String,age:int){
      var high:Int = _
      //定义私有辅助构造器
      private def this(name:String,age:Int,high:Int){
        this(name,age)
        this.high = high
      }
    }
    
    
    object ScalaDemo{
      def mian(args:Array[String]):Unit ={
        val p = new Person4("h",88)
        val p1 = new Person3(name = "r",age =18)
        println(p.name)
      }
    
    }
    

     注意:编译时Idea不报错,运行时才会报错;

        但是编程时如果主构造器不是私有的,定义时会出现变量名的提示(如Person3,而Person4没有提示)

      5.类的访问权限,在类前添加private修饰

      测试:

      //测试封装类如下,[this]会根据情况变化为无、[scala04]父包、[demo]子包

    private[this] class Person5(var name:String,age:Int) {
      var high:Int = _
    
      def this(name:String,age:Int,high:Int){
        this(name,age)
        this.high = high
      }
    }
    

      //测试运行单例对象如下:

    object ScalaDemo  {
      def main(args: Array[String]): Unit = {
        val p = new Person5("h",18,182)
        println(p.name)
      }
    }
    

         1>>封装类在父包,省略this,测试类在父包       √
         2>>封装类在父包,省略this,测试类在子包       √
         3>>封装类在父包,添加this,测试类在子包       √
         4>>封装类在父包,添加this,测试类在父包     √
         5>>封装类在父包,添加demo,测试类在父包    ×
         6>>封装类在父包,添加demo,测试类在子包       ×
         7>>封装类在父包,添加scala04,测试类在子包   √
         8>>封装类在父包,添加scala04,测试类在父包   √
       
         1>>封装类在子包,省略this,测试类在子包      √
         2>>封装类在子包,省略this,测试类在父包      ×
         3>>封装类在子包,添加this,测试类在父包      ×
         4>>封装类在子包,添加this,测试类在子包      √
         5>>封装类在子包,添加Scala04,测试类在子包    √
         6>>封装类在子包,添加Scala04,测试类在父包    √
         7>>封装类在子包,添加demo,测试类在父包     ×
         8>>封装类在子包,添加demo,测试类在子包     √

       总结:(1)private[this]修饰类表示当前包下及其子包都可以访问,[this]可以省略;

          (2)若在子包中定义private类,只能子包访问,如想父包访问,需要在private后添加[父包名]

          (3)若在父包中定义private类,且添加[子包名],则父包与子包都无法访问该类

    三、伴生对象:

      定义:在同一个类文件中,单例对象名与类名相同的两个单例对象和类,称之为伴生对象。

    class Person6 (private var name:String,age:Int){
      var high:Int = _
    
      def this (name:String,age:Int,high:Int){
        this(name,age)
        this.high = high
      }
    }
    
    object Person6{
      def main(args: Array[String]): Unit = {
        val p = new Person6("hunter",30)
        println(p.name)
      }
    }
    

      注意:单例对象可以访问其伴生对象类的私有成员变量和方法,

           但伴生对象他们必须在同一个类文件中。

    四、Scala特质和混入特质

      特质:相当于java中的接口

      混入特质:相当与实现多个接口

    trait Animal {
      //定义未实现方法
      def eat(name:String)
    
      //定义实现的方法
      def sleep(name:String):Unit={
        println(s"$name 在睡觉")
      }
    }
    
    trait Running {
      def how(str:String)
    }
    
    object Pig extends Animal with Running {
      override def eat(name: String): Unit = {
        println(s"$name 在吃鸡")
      }
    
      override def how(str: String): Unit = {
        println(f"$str 在奔跑")
      }
    
      def main(args: Array[String]): Unit = {
        Pig.sleep("reba")
        Pig.eat("wyh")
        Pig.how("hunter")
      }
    }
    

      注意:(1)Scala中没有implement,只有extends

         (2)Idea中ctrl+i与ctrl+o的区别:

            ctrl+i:实现未实现的方法

            ctrl+o:重写已经实现的方法

    五、Scala抽象类

    abstract class AbstractDemo {
      def eat(food:String)
    
      def sleep(how:String):Unit={
        println(s"$how->很香")
      }
    }
    
    object AbstractImpl extends AbstractDemo {
      override def eat(food: String): Unit = {
        println(s"hunter is eating $food")
      }
    
      override def sleep(how: String): Unit ={
        println(s"hunter 睡得$how")
      }
    
      def main(args: Array[String]): Unit = {
        AbstractImpl.eat("大猪蹄子")
        AbstractImpl.sleep("很香")
      }
    }
    

      注意:Scala中可以先继承抽象类在继承特质,但是抽象类必须写在前面!!

    六、模式匹配(match/case)

      以下为三个模式匹配的例子,分别匹配了字符串、数组、元祖三种类型:

    object MatchTest {
      def main(args: Array[String]): Unit = {
        def strMatch(str:String):Unit = str match {
          case "Hunter" => println("很帅?")
          case "reba" => println("真的美")
          case _ => println("what?")
        }
    
        strMatch("Hunter")
        strMatch("hunter")
    
        def ArrayMatch(arr:Any):Unit = arr match {
          case Array(1) => println("只有一个元素的数组")
          case Array(1,2) => println("有两个元素的数组")
        }
    
        ArrayMatch(Array(1))
    
        def tupleMatch(tuple:Any):Unit = tuple match {
          case (1,_) => println("元祖第一个元素为1,第二个元素为任意类型")
          case ("hunter",34) => println("这哥们老帅了")
        }
        tupleMatch(("hunter",34))
      }
    }
    
  • 相关阅读:
    net core 使用 rabbitmq
    asp.net core WebApi 返回 HttpResponseMessage
    asp.net core 2.1 WebApi 快速入门
    JQuery EasyUI combobox动态添加option
    php截取字符去掉最后一个字符
    JQuery EasyUI Combobox的onChange事件
    对于不返回任何键列信息的 selectcommand 不支持 updatecommand 的动态 sql 生成
    Access2007 操作或事件已被禁用模式阻止解决办法
    Easyui 中 Tabsr的常用方法
    Win 7 IE11不能下载文件,右键另存为也不行
  • 原文地址:https://www.cnblogs.com/HelloBigTable/p/10275550.html
Copyright © 2011-2022 走看看