Scala—— 4.类

Java时面向对象的编程语言,由于历史原因,Java中还存在着非面向对象的内容:基本类型,null,静态方法等。Scala语言来自于Java,所以天生就是面向对象的语言,而且Scala时纯粹的面相对象的语言,即在Scala中,一切皆为对象。类是抽象的,概念的代表一类事物,比如人类。对象是具体的,实际的,代表一个具体事物。 类是对象的模版,对象是类的一个个体,对应一个实例。

1.类定义

语法
[修饰符] class 类名 {
类体
}

2.创建对象

语法
val | var 对象名 [: 类型] = new 类型[()]
不改变对象的引用(即:内存地址),应该声明为val性质的,否则声明为var,Scala设计者推荐使用val,因为一般来说,在程序中,通常只是改变对象属性的值,而不是改变对象的引用。
Scala在声明对象变量时,可以根据创建对象的类型自动推断,所以类型声明可以省略,但当类型和后面new对象类型有继承关系时即多态,就必须写了。

object boke_demo01 {
   
  def main(args: Array[String]): Unit = {
    val emp = new Emp // emp 类型就是Emp
    //如果希望将子类对象,交给父类的引用,这时就需要写上类型
    val emp2: Person = new Emp
 
  }
}
 
class Person {
 
}
 
class Emp extends Person {
   
}
class Person2 {
  var name = ""
  var age: Int = _ //如果是用 _ 方式给默认值,则属性必须指定类型
}
3.方法

语法
def 方法名[: 返回值类型] = {
方法体
}

4.构造方法

Scala构造对象需要调用构造方法,并且可以有任意多个构造方法(即Scala中构造器也支持重载),Scala类的构造器包括:主构造器和辅助构造器。
语法
class 类名(形参列表) { //主构造器
def this(形参列表){ //辅助构造器
}
def this(形参列表){ //辅助构造器可以有多个…
}
}

object boke_demo01 {
 
  def main(args: Array[String]): Unit = {
    //    val p1 = new Person("Jack", 20)
    //    println(p1)
 
    //下面这句话就会调用def this(name:String)
    val p2 = new Person("Tom")
    println(p2)
  }
}
 
//构造器的快速入门
//创建Person对象的同时初始化对象的age属性值和name属性值
class Person(inName: String, inAge: Int) {
  var name: String = inName
  var age: Int = inAge
  age += 10
  println("~~~~~~~~~~")
 
  //重写了toString,便于输出对象的信息
  override def toString: String = {
    "name=" + this.name + "\t age" + this.age
  }
 
  println("ok~~~~~")
  println("age=" + age)
 
  def this(name: String) {
    //辅助构造器,必须在第一行显式调用主构造器(可以是直接,也可以是间接)
    this("Jack", 10)
    //this
    this.name = name //重新赋值
  }
}

Scala构造器的作用是完成对新对象的初始化,构造器没有返回值。 主构造器的声明直接放置于类名之后。主构造器会执行类定义中的所有语句,这里可以体会到Scala的函数式编程和面向对象编程融合在一起,即:构造器也是方法(函数),传递参数和使用方法和前面的函数部分内容没有区别。如果主构造器没有参数,小括号可以省略,构建对象时调用的构造方法的小括号也可以省略

class AA {
 
}
 
val a = new AA
val b = new AA()

辅助构造器名称为this(这个和Java是不一样的),多个辅助构造器通过不同参数列表进行区分,在底层就是构造器重载。
如果想要主构造器编程私有的,可以在()之前加上private,这样用户只能通过辅助构造器来构造对象了,比如: class Person2 private(){}
辅助构造器的声明不能和主构造器的声明一致,会发生错误(即构造器名重复)。

object boke_demo01 {
 
  def main(args: Array[String]): Unit = {
 
    val p1 = new Person2("jack")
    p1.showInfo()
  }
}
 
//定义了一个Person类
//Person 有几个构造器 4
class Person2 private() {
  var name: String = _
  var age: Int = _
 
  def this(name: String) {
    //辅助构造器无论是直接或间接,最终都一定要调用主构造器,执行主构造器的逻辑
    //而且需要放在辅助构造器的第一行[这点和java一样,java中一个构造器要调用同类的其它构造器,也需要放在第一行]
    this() //直接调用主构造器
    this.name = name
  }
 
  //辅助构造器
  def this(name: String, age: Int) {
    this() //直接调用主构造器
    this.name = name
    this.age = age
  }
 
  def this(age: Int) {
    this("匿名") //调用主构造器,因为 def this(name : String) 中调用了主构造器!
    this.age = age
  }
 
  def showInfo(): Unit = {
    println("person信息如下:")
    println("name=" + this.name)
    println("age=" + this.age)
  }
}
5.构造器参数

Scala类的主构造器的形参未用任何修饰符修饰,那么这个参数是局部变量。如果参数使用val关键字声明,那么Scala会将参数作为类的私有只读属性使用。如果参数使用var关键字声明,那么Scala会将参数作为类的成员属性使用,并会提供对应的xxx()[类似getter]/xxx_$eq()[类似setter]方法,即这时的成员属性是私有的,但是可读写。

object boke_demo01 {
 
  def main(args: Array[String]): Unit = {
 
    val worker = new Worker("smith")
    worker.name //不能访问 inName
 
    val worker2 = new Worker2("smith2")
    worker2.inName  //可以访问 inName
    println("hello!")
 
    val worker3 = new Worker3("jack")
    worker3.inName = "mary"
    println(worker3.inName)
  }
}
 
//如果 主构造器是Worker(inName: String) ,那么 inName就是一个局部变量
class Worker(inName: String) {
  var name = inName
}
//如果 主构造器是Worker2(val inName: String) ,那么 inName就是Worker2的一个private的只读属性
class Worker2(val inName: String) {
  var name = inName
}
 
// 如果 主构造器是Worker3(var inName: String) ,那么 inName就是Worker3的一个
// 一个private 的可以读写属性
class Worker3(var inName: String) {
  var name = inName
}

将Scala字段加@BeanProperty时,这样会自动生成规范的setXxx/getXxx方法。这时可以使用 对象.setXxx()和对象.getXxx()来调用属性。给某个属性加入@BeanPropetry注解后,会生成getXxx和setXxx的方法,并且对原来底层自动生成类似xxx(),xxx_$eq()方法,没有冲突,二者可以共存。

import scala.beans.BeanProperty
 
object boke_demo01 {
 
  def main(args: Array[String]): Unit = {
    val car = new Car
    car.name = "a"
    println(car.name)
 
    //使用 @BeanProperty 自动生成 getXxx 和 setXxx
    car.setName("b")
    println(car.getName())
  }
}
 
class Car {
  @BeanProperty var name: String = null
}

————Blueicex 2020/2/15 18:06 [email protected]

发布了55 篇原创文章 · 获赞 0 · 访问量 1949

猜你喜欢

转载自blog.csdn.net/blueicex2017/article/details/104338813