抽象类//

抽象类

|-------------|----------------------------------------------------------|
| 1 | 定义抽象类:abstract class Person{} //通过 abstract 关键字标记抽象类 |
| (2) | 定义抽象属性:val|var name:String //一个属性没有初始化,就是抽象属性 |
| (3) | 定义抽象方法:def hello():String //只声明而没有实现的方法,就是抽象方法 |

继承 & 重写

|-------------------------------------------------|
| 1. 如果父类为抽象类,那么子类需要将抽象的属性和方法实现,否则子类也需声明为抽象类 |
| 1. 重写非抽象方法需要用 override 修饰,重写抽象方法则可以不加 override。 |
| 1. 子类中调用父类的方法使用 super 关键字 |
| 1. 子类对抽象属性进行实现,父类抽象属性可以用 var 修饰; |
| 子类对非抽象属性重写,父类非抽象属性只支持 val 类型,而不支持 var。 |

单例对象(伴生对象)

1) 基本语法

object Person{

val country:String="China"

}

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

6.6.2 apply 方法

|-----|------------------------------------------------------------------------------|
| (1) | 通过伴生对象的 apply 方法,实现不使用 new 方法创建对象。 |
| (2) | 如果想让主构造器变成私有的,可以在()之前加上 private。 |
| (3) | apply 方法可以重载。 |
| (4) | Scala 中 obj(arg)的语句实际是在调用该对象的 apply 方法,即 obj.apply(arg)。用以统一面向对象编程和函数式编程的风格。 |
| (5) | 当使用 new 关键字构建对象时,调用的其实是类的构造方法,当直接使用类名构建对象时,调用的其实时伴生对象的 apply 方法。 |

6.7 特质(Trait)

Scala 语言中,采用特质 trait(特征)来代替接口的概念,也就是说,多个类具有相同的特质(特征)时,就可以将这个特质(特征)独立出来,采用关键字 trait 声明。

Scala 中的 trait 中即可以有抽象属性和方法,也可以有具体的属性和方法,一个类可以混入(mixin)多个特质。这种感觉类似于 Java 中的抽象类。

Scala 引入 trait 特征,第一可以替代 Java 的接口,第二个也是对单继承机制的一种补充。

6.7.1 特质声明

trait 特质名 { trait 主体

}

6.7.2 特质基本语法

|------------|------------|---------|------|---|---|------|----------|------|--------------|
| 没有父类:class | 类名 extends | 特质 1 | with | 特质 2 || with | 特质 3 ... | | |
| 有父类:class | 类名 | extends | 父类 | with || 特质 1 | with | 特质 2 | with 特质 3... |
| (1) ||||| 类和特质的关系:使用继承的关系。 |||||
| (2) ||||| 当一个类去继承特质时,第一个连接词是 extends,后面是with。 |||||
| (3) ||||| 如果一个类在同时继承特质和父类时,应当把父类写在 extends 后 |||||
| | | | | | | | | | |

特质叠加

由于一个类可以混入(mixin)多个 trait,且 trait 中可以有具体的属性和方法,若混入的特质中具有相同的方法(方法名,参数列表,返回值均相同),必然会出现继承冲突问题。冲突分为以下两种

第一种,一个类(Sub)混入的两个 trait(TraitA,TraitB)中具有相同的具体方法,且两个 trait 之间没有任何关系,解决这类冲突问题,直接在类(Sub)中重写冲突方法

|---|------------------------------------------------------------|
| |
| | |

第二种,一个类(Sub)混入的两个 trait(TraitA,TraitB)中具有相同的具体方法,且两个 trait 继承自相同的 trait(TraitC),及所谓的"钻石问题",解决这类冲突问题,Scala 采用了特质叠加的策略

6.7.4 特质叠加执行顺序

结论: (1) 案例中的 super,不是表示其父特质对象,而是表示上述叠加顺序中的下一个特质,即,MyClass 中的 super 指代 Color,Color 中的 super 指代Category,Category 中的super指代Ball。

(2) 如果想要调用某个指定的混入特质中的方法,可以增加约束: super[],例如

super[Category].describe()。

6.7.5 特质自身类型

自身类型可实现依赖注入的功能。

6.7.6 特质和抽象类的区别

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

而特质不行(有无参构造)。

6.8 扩展

6.8.1 类型检查和转换

(1) obj.isInstanceOf[T]:判断 obj 是不是T 类型。

(2) obj.asInstanceOf[T]:将 obj 强转成 T 类型。

(3) classOf 获取对象的类名。

6.8.2 枚举类和应用类

枚举类:需要继承 Enumeration

应用类:需要继承App

6.8.3 Type 定义新类型

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

集 合

|------------------------------------------------------------------------------|
| (1) Scala 的集合有三大类:序列 Seq、集Set、映射 Map,所有的集合都扩展自 Iterable |
| 特质。 |
| 2) 对于几乎所有的集合类,Scala 都同时提供了可变和不可变的版本,分别位于以下两个包 |
| 不可变集合:scala.collection.immutable 可变集合: scala.collection.mutable |
| 3) Scala 不可变集合,就是指该集合对象不可修改,每次修改就会返回一个新对象, 而不会对原对象进行修改。类似于 java 中的 String 对象 |
| 4) 可变集合,就是这个集合可以直接对原对象进行修改,而不会返回新的对象。类似于 java 中 StringBuilder 对象 |

7.1.1 不可变集合继承图

|---|------------------------------------------------------------|
| |
| | |

  1. Set、Map 是 Java 中也有的集合
  2. Seq 是 Java 没有的,我们发现 List 归属到Seq 了,因此这里的 List 就和 Java 不是同一个概念了
  3. 我们前面的for 循环有一个 1 to 3,就是 IndexedSeq 下的 Range 4)
  4. String 也是属于 IndexedSeq
  5. 我们发现经典的数据结构比如 Queue 和 Stack 被归属到 LinearSeq(线性序列)
  6. 大家注意Scala 中的 Map 体系有一个 SortedMap,说明 Scala 的 Map 可以支持排序
  7. IndexedSeq 和LinearSeq 的区别:

(1) IndexedSeq 是通过索引来查找和定位,因此速度快,比如String 就是一个索引集

合,通过索引即可定位

(2) LinearSeq 是线型的,即有头尾的概念,这种数据结构一般是通过遍历来查找

可变集合继承图

\

|---|------------------------------------------------------------|
| |
| | |

    1. 数组
      1. 不可变数组

第一种方式定义数组

定义:val arr1 = new Array[Int](10)

(1)new 是关键字

(2)[Int]是指定可以存放的数据类型,如果希望存放任意数据类型,则指定Any

(3)(10),表示数组的大小,确定后就不可以变化

第二种方式定义数组val arr1 = Array(1, 2)

(1) 在定义数组时,直接赋初始值

(2) 使用apply 方法创建数组对象

      1. 可变数组

定义变长数组

val arr01 = ArrayBuffer[Any](3, 2, 5)

(1)[Any]存放任意数据类型

(2)(3, 2, 5)初始化好的三个元素

(3)ArrayBuffer 需要引入 scala.collection.mutable.ArrayBuffer

不可变数组与可变数组的转换

arr1.toBuffer //不可变数组转可变数组

arr2.toArray //可变数组转不可变数组

    1. arr2.toArray 返回结果才是一个不可变数组,arr2 本身没有变化
    2. arr1.toBuffer 返回结果才是一个可变数组,arr1 本身没有变化
相关推荐
渣渣盟18 小时前
Flink Table API与SQL流数据处理实战
大数据·sql·flink·scala
howard20054 天前
1.5 掌握Scala内建控制结构
scala·内建控制结构
howard20054 天前
1.1.2 Windows上安装Scala
scala·windows版本
allway24 天前
Debian Regular Expressions
运维·debian·scala
、BeYourself6 天前
Scala 字面量
开发语言·后端·scala
、BeYourself14 天前
Scala 数据类型
开发语言·后端·scala
howard200514 天前
1.2 Scala变量与数据类型
scala·变量·数据类型·常量
渣渣盟14 天前
Flink定时器实战:处理时间与事件时间
大数据·flink·scala