zoukankan      html  css  js  c++  java
  • 7.Scala-类

    第7章 类

    7.1 简单类和无参方法

    类的定义可以通过 class 关键字实现,如下:

    class Dog {
    
      private var leg: Int = _
    
      def shout(msg: String) = {
        println(msg)
      }
      def currentLeg = leg
    }

    使用这个类:

    val dog = new Dog
    dog shout "wangwang"
    println(dog currentLeg)
    注:在 Scala 中,类并不声明为 Public,一个 Scala 源文件可以包含多个类。所有
    这些类都具有公有可见性。调用无参方法时,可以加(),也可以不加;如果方法
    定义中不带括号,那么调用时就不能带括号。

    7.2 Getter、Setter 方法

    对于 scala 类中的每一个属性,编译后,会有一个私有的字段和相应的
    getter、setter 方法生成,比如: 
    //getter
    println(dog leg)
    
    //setter
    dog.leg_= (10)
    println(dog currentLeg)

     当然,你可以不使用自动生成的方法,自己定义 getter 和 setter 方法

    class Dog2 {
        private var _leg = 4
        def leg = _leg
        def leg_=(newLeg: Int){
            _leg = newLeg
        }
    }

    使用之:

    val dog2 = new Dog2
    dog2.leg_=(10)
    println(dog2.leg)

    尖叫提示:自己动手创建变量的 getter 和 setter 方法需要遵循以下原则:

    1)字段属性名以 "_" 作为前缀,如:_leg

    2)getter 方法定义为:def leg = _leg

    3)setter 方法定义时,方法名为属性名去掉 前缀,并加上后缀发,后缀时:"leg_=",如例子所示

    7.3 对象私有字段

    package unit7
    
    package society {
      package professional{
        class Executive {
          private[professional] var workDetails = null
          private[society] var friends = null
          private[this] var secrets = null
          
          def help(another: Executive) {
            println(another.workDetails)
            println(another.secrets) //报错访问不到
          }
        }   } }

    7.4 Bean 属性

    JavaBeans 规范定义了 Java 的属性是像 getXXX()和 setXXX()的方
    法。许多 Java 工具都依赖这个命名习惯。为了 Java 的互操作性。将 Scala 字
    段加@BeanProperty 时,这样的方法会自动生成。
     
    1)创建一个 Bean,使用@BeanProperty 注解标识某个属性变量
    import scala.beans.BeanProperty
    class Person {
        @BeanProperty var name : String = _
    }
     
    2)通过 getMane、setName 访问属性
    val fred = new Person
    fred.setName("Fred")
    fred.getName
    println(fred.name)

    尖叫提示: 

    Person 将会生成四个方法:
    1、name:String
    2、name_=(newValue:String): Unit
    3、getName():String
    4、setName(newValue:String):Unit 
     

    7.5 构造器

    Scala 的类构造器分为主构造器和辅助构造器。 
     
    1) 主构造器的参数直接放置在类名之后: 
    定义类:
    class ClassConstructor(var name: String, private var price: Double){
        def myPrintln = println(name + "," + price)
    }
    
    执行:
    val classConstructor = new ClassConstructor("hello", 20.5)
    ClassConstructor.myPrintln 
     
     
     
    2) 主构造器会执行类定义中的所有语句: 
    class ClassConstructor2(val name: String = "", val price: Double = 0){
        println(name + "," + price)
    }
    
    执行:
    val ClassConstructor2 = new ClassConstructor2("aa", 20)
    val ClassConstructor2_2 = new ClassConstructor2()
     
     
     
    3) 通过 private 设置主构造器的私有属性: 
    参考1)
     
     
     
    4) 如果不带 val 和 var 的参数至少被一个方法使用,该参数将自动升级为字段,这时,name 和 price 就变成了类的不可变字段,
    而且这两个字段是对象私有的,这类似于 private[this] val 字段的效果。
    否则,该参数将不被保存为字段,即实例化该对象时传入的参数值,不会被保留在实例化后的对象之中。
     
     
     
    主构造器参数 生成的字段/方法
    name: String

    对象私有字段。如果没有使用 name,

    则没有该字段

    private val/var name: String 私有字段,私有的 getting 和 setting 方法
    var name: String 私有字段,公有的 getting 和 setting 方法
    @BeanProperty val/var name: String 私有字段,公有的 Scala版和 Java版的 getting 和 setting 方法
    如果想让主构造器变成私有的,可以在()之前加上 private,这样用户只能通过辅助构造器来造对象了
    class ClassConstructor private (val name:String, val age:Int) {
    
      println(name, age)
    
    }
     
    5) 辅助构造器名称为 this,通过不同参数进行区分,每一个辅助构造器都必须以主构造器
    或者已经定义的辅助构造器的调用开始: 
    class Person{
        private var name = ""
        private var age = 0
    
        def this(name: String){  
            this()
            this.name = name
        }
    
        def this(name: String, age: Int){
            this(name)
            this.age = age
        }
    
         def description = name + "is" + age + "years old"
    }
     
     
     

    7.6 嵌套类

    即,在 class 中,再定义一个class,以此类推。

    Java 中的内部类从属于外部类。Scala中内部类从属于实例。

    1)创建一个嵌套类,模拟局域网的聊天场景

    import scala.collection.mutable.ArrayBuffer
    //嵌套类
    class Network{
        class Member(val name: String){
            val contacts = new ArrayBuffer[Member]
        }
    
        private val members = new ArrayBuffer[Member]
        def join(name: String) = {
            val m = new Member(name)
            members += m
            m
        }
    }

    2)使用该嵌套类

    //创建两个局域网
    val network1 = new Network
    val network2 = new Network
    
    //nick 和 alice 加入局域网1
    val nick = network1.join("Nick")
    val alice = network1.join("Alice")
    
    //jone 加入局域网2
    val jone = network2.join("Jone")
    
    //nick 和 alice 互相添加为好友
    val nick = network1.join("Nick")
    val alice = network1.join("Alice")
    
    //nick.contacts += jone //这样不行,nick 和 jone 不属于同一个局域网,即, nick 和 jone 不是同一个 class Member 实例化出来的对象

    在 Scala 中,每一个实例都有它自己的Menber类,就和他们有自己的 members 字段一样。也就是说,

    network1.Member 和 network2.Member 是不同的两个类。也就是所谓的:

    路径依赖类型,此处需要详细解释。

    如果想让 members 接受所有实例的Member,一般有两种办法:

    1)将 Member 作为Network 的伴生类对象存在

    创建类:

    import scala.collection.mutable.ArrayBuffer
    
    class Network {
    
    
        val contacts = new ArrayBuffer[Network.Member]()
    
    
      //用于存放局域网中的对象
      val members = new ArrayBuffer[Network.Member]()
    
      def join(name: String) = {
        val m = new Network.Member(name)
        members += m
        m
      }
    
    }
    
    
    object Network{
      class Member(name: String){
        //用于存放某个Mem对象的联系人
        val contacts = new ArrayBuffer[Member]()
      }
    }

    2)使用类型投影,注意留意关键符号:"#"

    创建类:

    import scala.collection.mutable.ArrayBuffer
    
    class Network {
    
      class Member(name: String){
        //用于存放某个Mem对象的联系人
        val contacts = new ArrayBuffer[Network#Member]()
      }
    
      //用于存放局域网中的对象
      val members = new ArrayBuffer[Network#Member]()
    
      def join(name: String) = {
        val m = new Member(name)
        members += m
        m
      }
    
    }
  • 相关阅读:
    mysql #与$的区别
    linux连接mysql
    19年春第十三周学习
    第二阶段冲刺-02
    第二阶段冲刺-01
    19年春第十二周学习
    第一阶段SCRUM冲刺-10
    第一阶段SCRUM冲刺-09
    第一阶段SCRUM冲刺-08
    19年春第十一周学习
  • 原文地址:https://www.cnblogs.com/LXL616/p/11123851.html
Copyright © 2011-2022 走看看