大数据学习14之Scala面向对象--至简原则
1.类和对象
1.1基本概念
面向对象(Object Oriented)是一种编程思想,面向对象主要是把事物给对象化,包括其属性和行为。面向对象编程更贴近实际生活的思想,总体来说面向对象的底层还是面向过程,面向过程抽象成类,然后封装,方便使用就是面向对象(万物皆对象)。
1.2特征:
对象唯一性;
抽象性(封装性);
继承性;
多态(多样);
1.3类:
类是数据结构(属性)和行为(操作)的集合,是一个抽象的概念。
包括方法和属性;
1.4对象:
类的具体实现;
面向对象的三大特征:封装、继承、多态。
1.5创建类和对象:
Scala 中创建类和对象可以通过 class 和 new 关键字来实现。用 class 创建类,用 new 创建对象。
1.6成员属性:
一个类会有自己的属性,例如:人类有姓名、年龄等。接下来我们学习如何在类中定义和访问成员属性。
1.7构造器:
当创建对象的时候,会自动调用类的构造器。
1.8单例对象:
单例对象表示全局仅有一个对象,也叫孤立对象。定义单例对象和定义类很像,就是把 class 换成 object。
1.9伴生对象:
一个 class 和 一个 object 具有相同的名字时,这个 object 就被称为伴生对象,这个 class 被称为伴生类。
2.继承
2.1语法格式
class | object A类 extends B类{ }
2.2类继承
学生类和老师类都继承人类;
2.3. 单例继承
// 定义单例对象继承父类
object Student extends Person {}
// 单例对象无需 new,直接调用属性和方法
Student.name = "李四"
Student.age = 18
Student.sayHello()
2.4. 方法重写
改写父类的方法就是方法重写。方法用ovrride标识就是说该方法是重写方法。
2.5. 类型判断
对象 . isInstanceOf[类] 判断前面的对象属不属于后面的类。
3. 抽象类
Scala 也支持定义抽象类,使用 abstract 关键字来实现。如果类中有抽象属性或者抽象方法,那么该类就是抽象类。
3.1. 语法格式
abstract class 抽象类名{
val| var 抽象属性名:类型
def 方法名(参数):返回类型
}
3.2. 抽象属性
抽象类中没有初始化值的变量就是抽象属性;
abstract class Person {
// 定义抽象属性
val name: String
// 定义抽象方法
def sayHello(): Unit
}
4. 匿名类
匿名内部类是继承了某个类的匿名的子类对象,它可以直接用来创建实例对象。Spark 的源码中大量使用了匿名内部类,学习该知识对我们查看 Spark 底层源码非常有帮助。
4.1. 语法格式
new 类名() {
// 重写父类中所有的抽象内容
}
4.2. 使用场景
当对象方法仅调用一次的时候;
作为方法的参数进行传递时。
5. 特质
在不影响当前继承体系的情况下,对某些类或者某些对象的功能进行增强。
例如:有猴子类和大象类,牠们都有姓名,年龄,以及吃的功能,但是部分猴子经过马戏团的训练后,学会了骑独轮车。如果把骑独轮车的功能定义到动物类或者猴子类中,那所有继承了该类的子类都拥有了该功能,显然是不合理的。这时就需要用到特质了,Scala 中特质的关键字为 trait 。
5.1. 特点
特质可以提高代码的复用性
特质可以提高代码的扩展性和可维护性
类与特质之间是继承关系,只不过类与类之间只支持单继承,但是类与特质之间可以多继承
特质中可以有具体的属性、抽象属性、具体的方法以及抽象方法
5.2. 语法格式
定义特质。
class 类 extends 特质1 with 特质2 {
// 重写抽象属性
// 重写抽象方法
}
继承特质。
class 类 extends 特质1 with 特质2 {
// 重写抽象属性
// 重写抽象方法
}
注意:
Scala 中不管是类还是特质,都使用继承 extends 关系,特质支持多继承;
如果要继承多个特质,则特质之间使用 with 关键字隔开。
6. 包
实际开发中,我们肯定会遇到同名的类,例如两个 Person 类,那如何在不改变类名的情况下区分它们呢?这就要使用包 package 了。
包就是文件夹的意思,用关键字 package 修饰,通过包可以区分同名的类,开发时一般将相同功能的代码放到同一个包中,以便后期维护和管理。
7. 样例类
case class 样例类名(val|var 成员属性1:类型1, 成员属性2:类型2, ...) {}
8.至简原则(重点掌握)
Scala 希望大家编写优雅的代码,所以核心思想就是能省则省,下面我们一起总结一下 Scala 的至简原则:
方法和函数不建议写 return 关键字,Scala 会使用函数体的最后一行代码作为返回值;
方法的返回值类型如果能够推断出来,那么可以省略,如果有 return 则不能省略返回值类型,必须指定;
因为函数是对象,所以函数有类型,但函数类型可以省略,Scala 编译期可以自动推断类型;
如果方法明确声明了返回值为 Unit,那么即使方法体中有 return 关键字也不起作用;
如果方法的返回值类型为 Unit,可以省略等号 = ;
如果函数的参数类型能够推断出来,那么可以省略;
如果方法体或函数体只有一行代码,可以省略花括号 {} ;
如果方法无参,但是定义时声明了 () ,调用时小括号 () 可省可不省;
如果方法无参,但是定义时没有声明 () ,调用时必须省略小括号 () ;
如果不关心名称,只关心逻辑处理,那么函数名可以省略。也就是所谓的匿名函数;
如果匿名函数只有一个参数,小括号 () 和参数类型都可以省略,没有参数或参数超过一个的情况下不能省略 () ;
如果参数只出现一次,且方法体或函数体没有嵌套使用参数,则参数可以用下划线 _ 来替代。