前言
day05-scala学习之类的定义、属性的getter和setter方法、类的构造器、类的apply方法,我们学习了scala中类的定义、属性的getter和setter方法、类的构造器、类的apply方法。今天学习scala中类的继承、抽象类、trait、包及包对象。
scala的继承
scala的继承和java中的继承是一样的,都是使用extends关键字。
scala中还存在抽象属性,如果定义了属性,但是没有进行赋值,那这个属性就是抽象属性,像如下的Person中的name、age属性。
如果子类继承了父类,必须把父类中的抽象属性及抽象方法进行override。
/**
* 继承
* 父类 Person 人
* 子类 Emplee 员工
*/
//定义父类
class Person(val name:String,val age:Int) {
//定义函数
def sayHello():String = "Hello " + name + " and age is " + age
}
/**
* 定义子类 使用extends继承父类,并且要传入父类的主构造器的参数,extends Person(name,age)
* 使用override关键字,用子类的属性覆盖父类的属性
* 对于方法,在子类中也可以使用override关键字覆盖父类的方法
*/
class Emplyee(override val name:String,
override val age:Int,
val salary:Int) extends Person(name,age){
override def sayHello(): String = "子类中的sayHello"
}
object Demon1 {
def main(args: Array[String]): Unit = {
//创建Person对象
var p1 = new Person("Tom", 20)
println(p1.sayHello())
//创建子类对象
var p2: Person = new Emplyee("Mike", 20, 1000)
println(p2.sayHello())
//通过匿名子类来实现继承:没有名字的子类
var p3: Person = new Person("Mary", 20){
override def sayHello(): String = "匿名子类中的sayHello"
}
println(p3.sayHello())
}
}
上面代码的运行结果如下:
抽象类
在实际中,要继承的父类一般是抽象类或接口,下面的介绍scala的抽象类
在scala中,abstract只能修饰类;对于函数,没有实现的函数(函数体)就是抽象函数;对于属性,没有赋值的属性就是抽象属性。
/**
* 父类:抽象类 交通工具类
* 抽象类要使用 abstract 进行修饰
* abstract只能修饰类,
*/
abstract class Vehicle {
//抽象属性,没有赋值的属性就是抽象属性
var name : String
//定义抽象方法,在scala中没有实现的函数就是抽象函数
def checkType() : String
}
//子类,自行车、汽车 从父类继承
class Car extends Vehicle{
override var name: String = "汽车"
override def checkType(): String = "I am a Car"
}
class Bike extends Vehicle{
override var name: String = "自行车"
override def checkType(): String = "I am a Bike"
}
object Demo2{
def main(args: Array[String]): Unit = {
var v1 : Vehicle = new Car
println(v1.checkType())
println(v1.name)
var v2 : Vehicle = new Bike
println(v2.checkType())
println(v2.name)
}
}
上面代码的运行结果如下截图:
trait
trait本质是一个抽象类。
trait跟抽象类最大的区别:trait支持多重继承。
如下是trait的小实例代码:
//trait本质是一个抽象类
trait Human {
//抽象字段
val id : Int
val name: String
}
//trait本质是一个抽象类
trait Action{
//抽象方法
def kiss():String
}
trait A{
def a():String
}
//定义一个子类,多继承的时候要使用with关键字
class Student(val id:Int,val name:String) extends Human with Action with A {
//实现父类的抽象函数
override def kiss(): String = "去上学!"
override def a(): String = "多继承"
}
object Demon3{
def main(args: Array[String]): Unit = {
val s1 = new Student(1,"SJR")
println(s1.kiss())
}
}
包与包对象
Scala的包和Java中的包或者是c++中的命名空间的目的是相同的,管理大型程序中的名称。
包的定义:package
包的引入:Scala中依然使用import作为引用包的关键字。
Scala中的import可以写在任意地方,在实际spark开发中会发现有些地方在要使用某个对象的地方才import进来,而不是在代码的头部import。
包可以包含类、对象和特质,但不能包含函数或者变量的定义。很不幸,这是Java虚拟机的局限。把工具函数或者常量添加到包而不是某个Utils对象,这是更加合理的做法。Scala中,包对象的出现正是为了解决这个局限。
Scala中的包对象:常量,变量,方法,类,对象,trait(特质)。
package object test {
//常量
val a:String = "a"
//变量
var b = "b"
//方法
def c():String = "C"
//类
class D{
}
//object
object E{
}
}
object Demo5{
def main(args: Array[String]): Unit = {
//调用包对象中的对象时,使用 包对象.其实的对象
println(test.a)
}
}