Skip to content

类-Class

Scala中定义类和Java样,都是使用class关键字,使用时使用new关键字创建对象,定义Person类代码如下所示:

scala
class Person {
    var name = "星空小屋"
    def sayHellp() {
        println("Hello," + name)
    }
    def getName = name
}

在Scala中,如果在定义方法时指定了(),则调用时可以省略();如果没有指定(),则调用时必须不带()

scala
val p = new Person()
p.sayHellp
println(p.getName)
println(p.getName())  // 报错,不可以这样使用

构造函数

Scala类中的构造函数可以分为主构造函数和辅助构造函数。主构造函数类似于Java的默认构造函数,而辅助构造函数可以有多个参数,用于重载构造函数。

先来看主构造函数,主构造函数可以指定默认值,和函数类似:

scala
class Student(val name:String, val age: Int = -1) {
    println("name = " + name + ", age = " + age)
}

// 创建对象
scala> var stu1 = new Student("张三")
name = 张三, age = -1

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

scala
class Student {
    var name = "jack"
    var age = 10
    def this(name: String) {
        this() // 第一行必须调用主构造函数
        this.name = name
    }
    def this(name: String, age: Int) {
        this(name)
        this.age = age
    }
}

还有这种写法,注意此时调用主构造函数需要传递两个参数:

scala
class Student(val name:String, val age: Int = -1) {
    var name = name
    var age = age
    def this(name: String) {
        this(name, -1) // 第一行必须调用主构造函数
        this.name = name
    }
}

Object对象

在Scala中,可以像定义类一样直接定义一个object。object相当于class的单个实例,通常用于存放静态的字段或方法。

  • object只能定义无参数的构造函数
  • 当第一次调用object的方法时,会执行object的构造函数,但只会执行一次。
  • object通常用于实现单例模式或存放类的静态成员,如工具方法。
  • object可以直接使用,不能new
  • 创建一个object对象,使用object关键字
scala
object Person {
    var age = 1
    println("this Person object!")
    def getAge = age 
}

使用方式也很简单,直接使用即可

scala
scala> Person.getAge
this Person object! // 输出语句全局指挥输出一句
res4: Int = 1

scala> Person.getAge
res5: Int = 1

scala> Person.age
res6: Int = 1

伴生对象

如果有一个class,还有一个与class同名的object,那么就称这个object是class的伴生对象 ,class是object的伴生类。

scala
object Person {
    private val money = 1
    def getMoney = money
}
class Person(val name: String, age: Int) {
    def sayHello = println("name="+name+" age="+age+" monet="+Person.money)
}

使用:

scala
scala> new Person("Scala", 28).sayHello
name=Scala age=28 monet=1 // 说明:在Person类可以直接访问伴生类的private变量

scala> Person.money
<console>:13: error: value money is not a member of object Person
       Person.money
              ^

TIP

注意:伴生类和伴生对象必须存放在一个.scala文件之中,伴生类和伴生对象最大特点在于可以互相访问private field

apply

apply是Object类中一个非常重要的特殊方法,通常在伴生对象中实现。在伴生对象的apply方法中,可以实现构造对象的功能。这样,在创建对象时,就不需要使用传统的new Class的方式,而是可以直接使用Class()的方式来隐式调用伴生对象的apply方法,从而使得对象的创建更加简洁。

举个例子,Array类的伴生对象就实现了apply方法,它接收可变数量的参数,并创建一个Array对象。下面是使用这种方式创建Array对象的示例代码:

scala
val array = Array(1, 2, 3, 4, 5)

通过这种方式,我们可以直接使用Array类来创建一个包含指定元素的数组对象,而无需显式地调用构造函数或使用new关键字。这种简洁的语法使得代码更加易读和易于理解。下面是定义一个伴生类和伴生对象:

scala
class Person(val name: String) {
    println("my name is " + name)
}
object Person {
    def apply(name: String) = {
        println("apply exec……")
        new Person(name)
    }
 }

使用方式:

scala
scala> new Person("Tom")
my name is Tom
res5: Person = Person@7d8d671b

scala> Person("Tom")  // 一般这种方式更简单
apply exec……
my name is Tom
res6: Person = Person@468646ea

接口-trait

类似于Java中的interface,在trait中可以定义抽象方法。

  • 类可以使用extends关键字继承trait,无论继承类还是trait统一都是使用extends这个关键字。
  • 类继承trait后,必须实现trait中的抽象方法,实现时不需要使用override关键字。
  • Scala不支持对类进行多继承,但是支持对trait进行多重继承,使用with关键字即可。
scala
object MainDemo {
    def main(args: Array[String]): Unit = {
        println("Hello Scala~~")
    }
}

trait HelloTrait {
    def sayHello(name: String)
}

trait MakeFriendsTrait {
    def makeFriends(p: Person)
}

class Person(val name: String) extends HelloTrait with MakeFriendsTrait {
    override def sayHello(name: String) = println("Hello, " + name)
    override def makeFriends(p: Person) = println("Hello, my name is " + name + ", your" + p.name)
}