Scala面向对象

定义类

//不用修饰符
class HelloWorld{
    //定义一个私有的field 
    private var name = "CZM"
    def fun(){
        //这是一个带参数的方法
    }

    def getName = name
    //定义一个不带参数的方法

建立对象

val helloWorld = new HelloWorld     //括号无关紧要

调用方法

//能够不写*()*
helloWorld.fun()

//不能写*()*
helloWorld.getName

getter和setter方法

  • 定义不带private的var field Scala生成面向JVM的类时,会定义成private的字段,并提供Public的getter和setter (也就是说,你在用对象调用这个值的时候,底层转换为使用pubic的getter/setter方法访问)
  • 定义带private的field,则生成的getter和setter方法也是private的,外部不能调用,只能经过暴露的方法获得
  • 定义成val field时,只会生成getter方法
  • 若是不但愿生成getter和setter方法,则将field声明成privete[this]
//自动生成的getter和setter方法,经过 val var private private[this]
var name = "CZM"
/*自动生成以下代码
//getter
def name = name

//setter
def name_ = (new_name:String)
*/

//手动getter和setter
private var name= "CZM"
def name = "Your name is "+name     //错误,由于这样至关于两次定义了name

class HelloWorld {
  private var old_name= "CZM"
    def name = "Your name is "+old_name     //正确:old_name 做为类中的私有feild,仅仅提供私有的getter和setter方法,而name做为一个提供了public的getter和setter方法的feild ==> var name并重写了public的getter和setter
    def name_=(new_name: String) {      //须要注意的是这里的语法规则,**=号先后不容许有空格**
    old_name = new_name
    print("Your new name is " + old_name)
  }
}

//调用getter和setter
var helloWorld = new HelloWorld()
helloWorld.name //geter 
helloWorld.name_= "asd" //正儿八经setter
helloWorld.name = "asd" //新型setter,将name做为返回,买一送一

privete[this]的使用

class Student{
    private var myAge = 0
    //private[this] var myAge = 0 //调用getter方法会报错,即便定义了getter和setter方法

    def age = myAge
    def age_=(newValue:Int){
        if (newValue<0){println("illegal gar!!")}
        else{myAge = newValue}
    }
    def older(s:Student){
        myAge > s.myAge 
    }
}

怀旧党专用,使用类JAVA的getter和setter方法

@BeanProperty var age = 0
@BeanProperty var age:Int = _   //使用占位符须要声明类型

//同时拥有两种调用方式
s1.getAge
s1.age

构造函数constructor

主constructor

  • 主构造函数就是与类名在一块儿的构造函数,关键问题是,当主构造函数定义了以后,就不能调用无参构造函数了,也就是说,主构造函数定义了最少参数的构造函数,之后就只有更多参数的了
  • 主constructor中定义的参数,若是被使用到,则会被声明成privat[this] var name
  • 若是类中没有使用到这个参数,则不会被声明,并不会有这个feild
//固然,能够设置默认参数 
class Student(name:String,age:Int){}

辅助constructor

class Student(){
    private var name = ""
    private var age = 0

    def this(name:String){
        this()      //若是不相互调用,必须调用**主构造函数**,且要在**首行 == JAVA**
        this.name = name
    }

    def this(name:String,age:Int){
        this(name)
        this.age = age
    }
}

内部类

与JAVA不一样的是,Scala中的外部类的对象的内部类都是不一样的类java

import scala.collection.mutable.ArrayBuffer

class Class {

  class Student(name: String) {}

  val students = new ArrayBuffer[Student]()

  def getStudent(name: String) = {
    new Student(name)
  }
}

val c1 = new Class
val c2 = new Class

val s1 = c1.getStudent("CZM")       //s1: c1.Student = Class$Student@1d3f8af1
val s2 = c2.getStudent("czm")       //s2: c2.Student = Class$Student@73589106

c1.students += s1   //正确
c1.students += s2   //错误,每个内部类都是属于对象的,而不是独立存在的

/*错误信息
Error:(21, 24) type mismatch;
found   : c2.Student
required: c1.Student
c1.students += s2
*/

object对象

因为类中定义的feild都是属于对象的,并无属于类的字段,在JAVA中使用Static定义的字段做为全部对象共用的类的字段,在scala中提供了object来存放。spring

  • object 也有constructor(不属于方法的代码都是静态加载),只在第一次被调用时执行一次,不能定义带参数的constructor
  • object一般用做单例模式(只有本身一个对象),或者做为伴生对象存放静态成员,静态工具方法
  • 与class相比,object仅仅是不能定义带参数的constructor,其余都是同样的,能继承其余方法
//定义object对象
object Person {     //不能有括号,不能定义带参数的constructor
  private var name = ""
  println("This is constructor!")
  def getName = name
  println("This is constructor too!")
}
Person.getName

//让object继承抽象类
abstract class Hello {
  def syaHello(name: String): Unit
}

object HelloObject extends Hello {
  override def syaHello(name: String): Unit = {
    println("Implement from Hello, your name is " + name)
  }
}

HelloObject.syaHello("CZM")

伴生对象和伴生类

  • 在同一个.scala文件中。同名的class和object,称object为class的伴生对象,class称为object的伴生类
  • 伴生对象和伴生类之间能够相互访问private的feild
  • class中的一切属于对象
  • object中的一切属于类
class Person(name: String, age: Int) {
  def sayHello = {
    println("Hello " + name + " you are " + age + " years old, and you must have " + Person.legNum + "legs")    //须要加上Object名访问object对象变量(即便不是私有的)
  }
}

object Person {
  private var legNum = 2    def getLegNum = legNum }

val p1 = new Person("czm", 18)
p1.sayHello

Apply方法(容许重载?)

  • apply方法中通常作什么?建立一个对象,并返回对象
  • 为何要Apply方法?让建立类对象来的更简单,直接使用 类名()便可
  • 为何要在伴生对象中建立apply方法?由于这是一个工具方法,不该该属于对象,应该用类名调用
class Person(name: String)

object Person {
  def apply(name: String): Person = new Person(name)
}
Person("你好")

main方法

  • 为何要main方法?做为函数的入口
  • 为何要定义在object中?由于main是public static的,须要被JVM使用类名调用

方法1

//注意文件名与类名相同
object HelloWorld {
  def main(args: Array[String]) {
    if (args.length != 0) {
      println("Hello " + args(0))
    } else {
      println("Hello World!")
    }
  }
}

方法2:继承APP Trait

继承APP Trait,而后将须要在main中运行的代码,直接在constructor中编写。直接使用args接收传入的参数黑人问号脸??:这里的参数是来自父类APP Trait的父类DelayedInit Trait的Main方法中的args数组

  • 工做原理:APP Trait 继承自DelayedInit Trait 编译时会将object中的constructor中的代码放到DelayedInit Trait的delayedInit方法中执行。DelayedInit的main方法将会调用delayedInit方法(为了懒加载?)
object HelloWorld extends App{
    if (args.length != 0) {
      println("Hello " + args(0))
    } else {
      println("Hello World!")
    }
}

使用object实现枚举

  • 枚举是什么:枚举是一个特殊的类,就是固定的多个常量对象的集合
  • Scala没有提供相似JAVA中的Enum这样的枚举特性,可使用object继承Enumeration类,而且调用Value方法来初始化枚举值
  • 调用时,直接使用Season(0),为何,不会跟apply冲突吗?继承了Enumeration,Enumeration中的apply方法是final的,子类不容许再定义apply只能继承Enumeration的apply(详情亲看源码)

scala实现枚举

object Season extends Enumeration{
  val SPRING,SUMMER,AUTUMN,WINTER = Value   //Value方法继承于Enumeration
  //能够自定义Value的元素
  val SPRING = Value(0,"spring")
  ...
}

//调用
//Enumeration的apply方法返回一个Value对象                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
Season(0)
res0: Season.Value = SPRING

Season("spring")

java中的枚举

enum Weeday{
    SUNDAY,MONDAY.TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY;
}

//在底层
//建立了一个final的Weeday类继承Enum
//实例化各个字段为 public final static 的 Weekday 对象,存在数组$VALUES中
//定义了一个values方法,用于返回数组      //Weekday.values()
//定义了一个valueOf方法,用于返回           //Weekday.valueof("SUNDAY")
相关文章
相关标签/搜索