← 返回首页
Scala面向对象
发表时间:2023-09-08 01:07:18
Scala面向对象

Scala也是一门面向对象的编程语言,本小节我们探讨下Scala的面向对象特征。

1.Scala的面向对象基本特征

Scala中类和java中的类基本是类似的。 Scala中的对象时需要定义的,而java中的对象是通过class new出来的。 Scala中的接口是trait,java中的接口是interface。

2.类-class

首先看一下类,Scala中定义类和Java一样,都是使用 class 关键字。和Java一样,使用new关键字创建对象。

那下面来看一个具体案例,定义Person类,创建对象并调用其方法。

class Person{
    var name = "scala"
    def sayHello(){
        println("Hello,"+name)
    }
    def getName= name
}

注意:如果在定义方法的时候指定了(),那么在调用的时候()可写可不写,如果在定义方法的时候没指定(),则调用方法时肯定不能带()。

scala> val p = new Person()
p: Person = Person@23b8d9f3

scala> p.sayHello()
Hello,scala

scala> p.sayHello
Hello,scala

scala> println(p.getName)
scala

scala> println(p.getName())
<console>:10: error: not enough arguments for method apply: (index: Int)Char in class StringOps.
Unspecified value parameter index.
              println(p.getName())

3.constructor

Scala类中的构造函数可以分为主构造函数和辅助构造函数。

这两种构造函数有什么区别呢? - 主constructor:类似Java的默认构造函数 this() - 辅助constructor:类似Java的重载构造函数 this(name,age)

1).主constructor

Scala的主constructor是与类名放在一起的,与Java不同,Java中的构造函数是写在类内部的。

注意:在类中,没有定义在任何方法或者是代码块之中的代码就是主constructor的代码。

先定义一个Student类

class Student(val name:String,val age:Int){
    println("your name is " + name + ", your age is " + age)
}

创建对象

scala> new Student("zs",19)
your name is zs, your age is 19
res8: Student = Student@3134153d

在创建对象的时候,类中的println语句执行了,说明这个语句属于主构造函数中的代码。 主constructor中还可以通过使用默认参数,来给参数设置默认值。

class Student(val name:String = "jack",val age:Int = 20){
    println("your name is " + name + ", your age is " + age)
}

创建对象

scala> new Student()
your name is jack, your age is 20
res10: Student = Student@7ddd84b5

scala> new Student("tom",18)
your name is tom, your age is 18
res11: Student = Student@a09303

2).辅助constructor

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

来看一个案例:给学生指定姓名和年龄信息。

class Student(){
  println("a students is created...")

  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
  }

  def sayHello(){
    println("my name is :"+this.name+",age is :"+this.age)
  } 
}

执行

scala> val s = new Student("tom")
a students is created...
s: Student = Student@1a538ed8

scala> s.sayHello()
my name is :tom,age is :10

scala> val s = new Student("mick",30)
a students is created...
s: Student = Student@319642db

scala> s.sayHello()
my name is :mick,age is :30

scala> val s = new Student()
a students is created...
s: Student = Student@1ef4179

scala> s.sayHello()
my name is :jack,age is :10

4.对象-object

前面我们学习的scala中的class和java中的class是类似的,下面来看一个java中没有的内容,叫Object 那大家可能有疑问了,Java中也有object,通过class就可以创建object,但是注意了,在scala中,我们可以直接定义一个object,就像定义class一样。

object:相当于class的单个实例,通常在里面放一些静态的field或者method。 object不能定义带参数的constructor,只有空参的constructor。第一次调用object的方法时,会执行object的constructor,也就是执行object内部不在任何方法中的代码,因为它只有空参的构造函数。

但是注意,object的constructor的代码只会在他第一次被调用时执行一次,以后再次调用就不会再执行了

object通常用于作为单例模式的实现,或者放class的一些静态成员,比如工具方法。object可以直接使用,不能new。创建一个object,使用object关键字。

object Person {
  var age = 1
  println("this Person object!")
  def getAge  = age 
}

执行,直接通过Object的名称调用属性或者方法即可,类似于Java中的静态类。

scala> Person
this Person object!
res18: Person.type = Person$@73e776b7

scala> Person.age
res19: Int = 1

scala> Person.getAge
res20: Int = 1

5.伴生对象

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

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

创建一个Person object和Person class

object Person {
  private val fdNum= 1
  def getFdNum = fdNum
}
class Person(val name: String, val age: Int) {
  def sayHello = println("Hi, " + name + ",you are " + age + " years old!" + ", and you  have " + Person.fdNum+ " friend.")
}

执行

scala> new Person("tom",20).sayHello
Hi, tom,you are 20 years old!, and you  have 1 friend.

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

scala> Person.getFdNum
res26: Int = 1

6.apply

apply是object中非常重要的一个特殊方法,通常在伴生对象中实现apply方法,并在其中实现构造伴生类对象的功能。在创建对象的时候,就不需要使用new Class的方式,而是使用Class()的方式,隐式调用伴生对象的apply方法,这样会让对象创建更加简洁。

例如:Array的伴生对象的apply方法就实现了接收可变数量的参数,以及会创建一个Array对象 val a = Array(1, 2, 3, 4, 5)

下面我们来自己定义一个伴生类和伴生对象。

class Person(val name: String){
  println("my name is,"+name)
}

object Person {
  def apply(name: String) = {
    println("apply exec...")
    new Person(name)
  }
}

执行

scala> new Person("tom")
my name is,tom
res29: Person = Person@63917fe1

scala> Person("tom")
apply exec...
my name is,tom
res30: Person = Person@35e74e08

注意:在这里new Person(“zhang”) 等于 Person(“zhang”),都是获取Person的对象。 只不过Person(“zhang”)是用的object中apply方法,而new Person(“zhang”)是直接基于class创建的。