zoukankan      html  css  js  c++  java
  • Scala入门系列(五):面向对象之类

    定义类

    // 定义类,包含field以及method
    class HelloWorld {
    private var name = "Leo"
    def sayHello() { println("Hello" + name)}
    def getName = name
    }
    defined class HelloWorld
    // 创建类对象,并调用其方法
    scala> val helloworld = new HelloWorld
    helloworld: HelloWorld = HelloWorld@4f49f6af
    scala> helloworld.sayHello() // 也可以不加括号
    HelloLeo
    scala> print(helloworld.getName) // 不能加括号,因为定义方法的时候没有加括号
    Leo

    封装(setter与getter)

    • 定义不加参数的var filed,Scala会将该字段定义为private,并提供public的getter和setter方法
    • 如果使用private修饰field, 则生成的getter和setter也是private的
    • 如果定义val field, 则只会生成getter方法
    • 如果使用private[this]修饰field,则不会生成getter和setter方法 
      总结:Scala提供的四种修饰符:var、val、private、private[this]
    class Student {
    var name = "sparks"
    }
    defined class Student
    scala> val spark = new Student
    spark: Student = Student@6337c201
    // 调用自动生成的setter和getter方法
    scala> print(spark.name)
    sparks
    scala> spark.name = "hahah"
    spark.name: String = hahah

    如果希望能够自己对getter和setter进行控制,则可以自定义getter与setter方法,使用field和fild_=的方式。

    class Student{
    private var myName = "Sparks"
    def name = "Your name is" + myName
    def name_=(newName: String) {
    myName = newName
    }
    }
    val spark = new Student
    print(spark.name)
    spark.name = "Leo"

    注意:自义定setter方法一定要注意scala的语法限制,签名、_=参数间不能有空格。

    private[this]的详解

    如果字段是private修饰的,那么代码这个字段时私有的,在类的方法中,可以直接访问类的其他对象的private field。 
    例如:

    class Student {
    private var myAge = 0
    def age_=(newValue: Int){
    if(newValue>0) { myAge = newValue}
    else print("illegal age!")
    }
    def age = myAge
    def older(s: Student) = {
    myAge > s.myAge // 调用另一个对象s的私有字段并不报错
    }
    }

      
    但是如果是用private[this]修饰,那么意味着该对象私有字段只有本对象内才可以访问,上面的代码就会报错

    <console>:16: error: value myAge is not a member of Student
    myAge > s.myAge // 调用另一个对象s的私有字段并不报错

    Java风格的getter和setter方法

    如果要让scala自动生成java风格的getter和setter方法,只要给field添加@BeanProperty注解即可。 
    此时会生成4个方法,name: String、 name_=(newValue: String): Unit、 getName(): String、 setName(newValue: String): Unit

    // 定义类
    import scala.reflect.BeanProperty
    class Student{
    @BeanProperty var name: String = _
    }
    defined class Student
    // 测试类
    scala> val s = new Student
    s: Student = Student@5f303ecd
    scala> s.setName("leo")
    scala> s.getName()
    res9: String = leo
    scala> s.name
    res10: String = leo
    scala> s.name = "spark"
    s.name: String = spark
    scala> s.getName()
    res11: String = spark
    // 定义Java风格类的第二种方式
    class Student(@BeanProperty var name: String)

    构造函数

    主构造函数

    在Scala中,主constructor是与类名放在一起的,而且类中没有定义在任何方法或者是代码块之中的代码,就是主constructor的代码,这点很新颖,但感觉没有java清晰。

    class Student(val name: String, val age: Int) {
    println("your name is " + name + ", your age is " + age)
    }
    defined class Student
    scala> val s = new Student("spark", 30)
    your name is spark, your age is 30
    s: Student = Student@43b40233
    // 还可以使用默认参数
    class Student(val name: String = "leo", val age: Int = 30) {
    println("your name is " + name + ", your age is " + age)
    }
    defined class Student
    // 这样新建对象时就不用传递参数了
    scala> val s = new Student
    your name is leo, your age is 30

    注意:如果主constucutor传入的参数什么修饰都没有,比如name: String, 那么如果类内部的方法使用到了,则会生命为private[this] name; 否则没有该field,就只能被constructor代码使用而已。

    辅助构造函数(this)

    Scala中,可以给类定义多个辅助constructor,类似于java中的构造函数重载 
    辅助constructor之间可以互相调用,而且必须第一行调用主constructor

    // 定义类
    class Student{
    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
    }
    }
    defined class Student
    // 测试类
    scala> val s1 = new Student
    s1: Student = Student@387bf2d9
    scala> val s2 = new Student("sparks")
    s2: Student = Student@5e746d37
    scala> val s3 = new Student("spark", 23)
    s3: Student = Student@5524b72f

    类部类

    在Scala中,同样可以在类中定义内部类;但是与java不同的是,每个外部类对象的内部类,都是不同的类

    // 定义内部类
    import scala.collection.mutable.ArrayBuffer
    class Class{
    class Student(val name: String){}
    val students = new ArrayBuffer[Student]
    def getNewStudent(name: String) = {
    new Student(name)
    }
    }
    defined class Class
    scala> val c1 = new Class
    scala> val s1 = c1.getNewStudent("spark")
    scala> c1.students += s1
    scala> val c2 = new Class
    scala> val s2 = c2.getNewStudent("leo")
    scala> c1.students += s2
    // 出错,因为每个外部类对象的内部类都是不同的类
    <console>:15: error: type mismatch;
    found : c2.Student
    required: c1.Student
    c1.students += s2
    ^
  • 相关阅读:
    GIT → 04:Git与代码托管平台
    GIT → 03:Git的下载和安装
    GIT → 02:Git和Svn比较
    GIT → 01:学习版本控制的原因
    GIT → 00:GIT学习大纲
    GIT → 10:基于IntelliJ IDEA的Git 操作
    GIT → 11:Git 工作流与实战演练
    GIT → 09:TortoiseGit 图形化工具
    亚马逊服务器搭建pptp方法
    Safari获取UDID需要安装.mobileconfig文件,
  • 原文地址:https://www.cnblogs.com/LiCheng-/p/8022251.html
Copyright © 2011-2022 走看看