立即注册 登录
About云-梭伦科技 返回首页

一颗银杏树的个人空间 https://www.aboutyun.com/?53709 [收藏] [复制] [分享] [RSS]

日志

《快学scala》学习笔记之第五章:类

热度 1已有 1056 次阅读2017-5-16 23:04 |个人分类:scala| getter, setter, 对象私有字段, Bean属性, 辅助构造器

5.1简单类和无参方法
   定义类
   class Counter{ //不声明为public,但仍具有公共可见性
    private var value = 0   //必须初始化字段
    def increment(){value += 1}  //方法是公有的
    def current() = value   //这里也可以定义为 def current = value ,调用时则强制不能带()
   }
   
   构造对象及调用无参方法
   val myCounter = new Counter  //或new Counter()       
   myCounter.increment()      //或myCounter.increment,圆括号可有可无,一般对于改值器使用(),对于取值器去掉()
   println(myCounter.current)  
   
5.2 带getter和setter的属性   
    5.2.1 属性通过setter来设置的好处。
    getter和setter作用在于可以对类的属性做一些限制性措施,防止对属性的任意更改。
    java中:
    public class Test1 {
    private int age;       //test1.age = 10 这样可以设置age属性
    public void setAge(int age){    //同时还可以test1.setAge(10)这样设置age属性。
    this.age = age;
    }
    
    public void setAge(int age) {  //这样就可以对age属性做一些限制,防止属性值设置混乱。
    if (age > 10) {
    this.age = age;
    } else
    this.age = 0;
    }
    
    5.2.2 scala中的setter和getter
    scala中类的每个属性,在编译的时候都会生成一对getter和setter方法,当然也可以重写getter和setter方法,如果属性被定义为private,getter和setter则也是private。
    属性不能被public修饰,因为默认就是public的。当然也可以控制属性不自动生成getter和setter,后面章节会涉及。
    
    class Person {
       var age = 0
    }
    
    hadoop@ubuntu1:~/scalaTest$ javap -private Person           //查过经过编译后的多出来了三项内容,setter和getter,还有个是默认构造器
    Compiled from "Person.scala"
    public class Person {
      private int age;
      public int age();            //getter,
      public void age_$eq(int);    //setter,名字为age_=(),在scala中使用的=号,在jvm中并不支持在方法名中带有=,而被翻译成了$eq    
      public Person();
    }   
    val person = new Person()
    person.age_=(10)  //调用setter方法
    person.age      //调用getter方法
    
    自己重新定义getter和setter方法
    class Person{
    private var privateage =0
    def age = privateAge   //重新定义getter,age没有带括号,调用时只能是person.age
    def age_= (x : Int){   //重新定义setter
    if(x > privateAge) privateAge = x;             //不能变年轻
    }
    }
    
5.3 只带getter的属性
    只允许客户端查看属性,而不能让客户端设置属性
    通过private来限制客户端更改类的属性值,但仍可以在类的内部改变,另一种是用val来让其永不改变。val定义的属性不生成setter。
    class Counter{
    private var value = 0           //private定义的属性会生成私有的setter和getter
    def increment()={value += 1}
    def current = value           //内部作改变成立
    }
    
    val counter1 = new Counter()
    counter1.value_=(10)     //这样则会报错:error: variable value in class Counter cannot be accessed in Counter
    counter1.value           //这样也会报同样的错
    counter1.current         //获取value的值,这样可以看value,就可以只能在客户端看value,而不能改变其value
    
5.4 对象私有字段
    同java一样,scala的方法可以访问该类的所有对象的私有属性。
    class Counter{
    private var value = 0
    def increment(){value += 1}
    def compare(counter:Counter)={counter.value < value}
    }
    
    counter1.compare(counter2)  //新建两个对象,则都可以访问value属性。counter2的value小则返回true
    
    如果这样:则新建的对象counter1、2则不能访问value,报错。
    class Counter{
    private[this] var value = 0             
    def increment(){value += 1}
    def compare(counter:Counter)={counter.value < value}   
    }
    private[this] var value = 0  //这样定义的属性,Counter类的方法只能访问到当前对象的value属性,而不能访问同样是Counter类型的其他对象的该属性。这样的属性被称为对象私有的。
    
5.5 Bean属性
    import scala.beans.BeanProperty
    class Person{
    @BeanProperty var age = 0
    }
    将会生成四个方法:
    hadoop@ubuntu1:~/scalaTest$ javap Person
    Compiled from "person1.scala"
    public class Person { 
      public int age();
      public void age_$eq(int);
      public void setAge(int);
      public int getAge();
      public Person();
    }
    
5.6 辅助构造器
    scala中分主构造器和辅构造器
    辅构造器:与java不同的是名称为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  
    }
    }
5.7 主构造器
    主构造器的参数直接放置在类名之后:
    class Person(val name:String,val age:Int){...}  //如果不定义主构造器,默认为无参的person()
    class Person(val name:String,val age:Int){
    println("Just constructed another person") //主构造器会执行类定义中的所有语句,对象被构造出来后这段代码就会被执行
    }
    class prinvate Person(val name:String,val age:Int){...}   //私有的主构造器,这样的定义方式只有通过辅助构造器来构造person对象
    
5.8 嵌套类
    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
    }
    }
    val chatter = new Network   //在scala中,每个实例都有自己的member类,就跟member属性一样。chatter.Member和myFace.Member是两个不同的两个类
    val myFace = new Network
    
    val fred = chatter.join("Fred")    //向chatter这个network类里添加Fred Member
    val wilma = chatter.join("Wilma")  //
    fred.contacts += wilma  //ok
    
    val barney = myFace.join("Barney")   //类型为myFace.Member
    fred.contacts += barney     //不可以这样做,不能讲myFace.Member添加到chatter.Member元素缓冲中

路过

雷人

握手
1

鲜花

鸡蛋

刚表态过的朋友 (1 人)

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 立即注册

关闭

推荐上一条 /2 下一条