欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Scala学习笔记(9)——面向对象(二)

程序员文章站 2022-06-14 22:26:14
...

一、单例对象(伴生对象)

Scala语言是完全面向对象的语言,所以并没有静态的操作(即在Scala中没有静态的概念)。但是为了能够和Java语言交互(因为Java中有静态概念),就产生了一种特殊的对象来模拟类对象,该对象为单例对象。若单例对象名与类名一致,则称该单例对象这个类的伴生对象,这个类的所有“静态”内容都可以放置在它的伴生对象中声明

1.单例对象语法

1)基本语法

object Person{
	val country:String="China"
}

2)说明
(1)单例对象采用 object 关键字声明
(2)单例对象对应的类称之为伴生类,伴生对象的名称应该和伴生类名一致。
(3)单例对象中的属性和方法都可以通过伴生对象名(类名)直接调用访问。

2. apply 方法

在伴生对象中可以定义一个apply方法,Scala底层对apply方法有特殊支持,使得Student11(“bob”, 19)就代表调用apply方法

object Test11_Object {
  def main(args: Array[String]): Unit = {
    val student2 = Student11.apply("bob", 19)
    student2.printInfo()
    val student3 = Student11("bob", 19)
    student3.printInfo()
  }
}

// 定义类,加上private关键字将构造器方法私有化
class Student11 private(val name: String, val age: Int){
  def printInfo(){
    println(s"student: name = ${name}, age = $age, school = ${Student11.school}")
  }
}

// 伴生对象
object Student11{
  val school: String = "atguigu"
  // 定义一个类的对象实例的创建方法
  def apply(name: String, age: Int): Student11 = new Student11(name, age)
}

二、特质(Trait)

Scala 语言中,采用特质 trait(特征)来代替接口的概念,也就是说,多个类具有相同的特质(特征)时,就可以将这个特质(特征)独立出来,采用关键字 trait 声明。
Scala 中的 trait 中即可以有抽象属性和方法,也可以有具体的属性和方法,一个类可以混入多个特质。这种感觉类似于 Java 中的抽象类。
Scala 引入 trait 特征,第一可以替代 Java 的接口,第二个也是对单继承机制的一种补充

1.特质的基本语法

一个类具有某种特质(特征),就意味着这个类满足了这个特质(特征)的所有要素,所以在使用时,也采用了 extends 关键字,如果有多个特质或存在父类,那么需要采用 with关键字连接。

1)基本语法:
没有父类:class 类名 extends 特质 1 with 特质 2 with 特质 3 …
有父类:class 类名 extends 父类 with 特质 1 with 特质 2 with 特质 3…

2)说明
(1)特质可以同时拥有抽象方法和具体方法
(2)一个类可以混入(mixin)多个特质
(3)所有的 Java 接口都可以当做 Scala 特质使用
(4)动态混入:可灵活的扩展类的功能
(4.1)动态混入:创建对象时混入 trait,而无需使类混入该 trait
(4.2)如果混入的 trait 中有未实现的方法,则需要实现

    // 动态混入
    val studentWithTalent = new Student14 with Talent {
      override def dancing(): Unit = println("student is good at dancing")
      override def singing(): Unit = println("student is good at singing")
    }

特质和抽象类的区别
1.优先使用特质。一个类扩展多个特质是很方便的,但却只能扩展一个抽象类。
2.如果你需要构造函数参数,使用抽象类。因为抽象类可以定义带参数的构造函数,而特质不行(有无参构造)。

2. 特质自身类型

通过特质自身类型可实现依赖注入的功能。

object Test16_TraitSelfType {
  def main(args: Array[String]): Unit = {
    val user = new RegisterUser("alice", "123456")
    user.insert()
  }
}

// 用户类
class User(val name: String, val password: String)

trait UserDao {
  //特质自身类型
  _: User =>

  // 向数据库插入数据
  def insert(): Unit = {
    println(s"insert into db: ${this.name}")
  }
}

// 定义注册用户类
class RegisterUser(name: String, password: String) extends User(name, password) with UserDao

三、扩展

1.类型检查和转换

obj.isInstanceOf[T]:判断 obj 是不是 T 类型。
obj.asInstanceOf[T]:将 obj 强转成 T 类型。
classOf 获取对象的类名。

2.枚举类和应用类

(1) 枚举类:需要继承 Enumeration

object Test {
 def main(args: Array[String]): Unit = {
 println(Color.RED)
 } }
// 枚举类
object Color extends Enumeration {
 val RED = Value(1, "red")
 val YELLOW = Value(2, "yellow")
 val BLUE = Value(3, "blue")
}

(2) 应用类:需要继承 App
可直接运行,App中自带main方法

// 应用类
object Test20 extends App {
 println("xxxxxxxxxxx");
}

3.Type 定义新类型

使用 type 关键字可以定义新的数据数据类型名称,本质上就是类型的一个别名

object TestApp extends App {
  type MyString = String
  val a: MyString = "abc"
  println(a)
}
相关标签: Scala学习笔记