scala和Java一样,使用extends关键字来实现继承
eg1:实现简单继承
class Person1 {
var name = "super"
def getName = this.name
}
class Student1 extends Person1
object Main1 {
def main(args: Array[String]): Unit = {
val p1 = new Person1()
val p2 = new Student1()
p2.name = "张三"
println(p2.getName)
}
}
eg2:单例对象实现继承
class Person2 {
var name = "super"
def getName = this.name
}
object Student2 extends Person2
object Main2 {
def main(args: Array[String]): Unit = {
println(Student2.getName)
}
}
override 和 super
- 如果子类要覆盖父类中的一个非抽象方法,必须要使用override关键字
- 可以使用override关键字来重写一个val字段
- 可以使用super关键字来访问父类的成员
class Person3 {
val name = "super"
def getName = name
}
class Student3 extends Person3 {
// 重写val字段
override val name: String = "child"
// 重写getName方法
override def getName: String = "hello, " + super.getName
}
object Main3 {
def main(args: Array[String]): Unit = {
println(new Student3().getName)
}
}
//输出 : hello, child
isInstanceOf和asInstanceOf :
isInstanceOf 判断对象是否为指定类的对象
asInstanceOf 将对象转换为指定类型
Java Scala 判断对象是否是C类型 obj instanceof C obj.isInstanceof[C] 将对象强转成C类型 (C ) obj obj.asInstanceof[C] 获取类型为T的class对象 C.class classOf[C]
class Person4
class Student4 extends Person4
object Main4 {
def main(args: Array[String]): Unit = {
val s1:Person4 = new Student4
// 判断s1是否为Student4类型
if(s1.isInstanceOf[Student4]) {
// 将s1转换为Student3类型
val s2 = s1.asInstanceOf[Student4]
println(s2)
}
}
}
//输出 : com.jicheng.Student4@47f37ef1
getClass和classOf :
isInstanceOf 只能判断出对象是否为指定类以及其子类的对象,而不能精确的判断出,对象就是指定类的对象。如果要求精确地判断出对象就是指定类的对象,那么就只能使用 getClass 和 classOf
对象.getClass可以精确获取对象的类型 -- p.getClass
classOf[x]可以精确获取类型 --- classOf[Person5]
使用==操作符就可以直接比较 --- p.getClass == classOf[Student5]
object Student5{
def main(args: Array[String]) {
val p:Person5=new Student5
//判断p是否为Person5类的实例
println("p.isInstanceOf[Person5] = "+p.isInstanceOf[Person5])//true
//判断p的类型是否为Person5类
println(p.getClass == classOf[Person5])//false
//判断p的类型是否为Student5类
println(p.getClass == classOf[Student5])//true
}
}
//输出 :
p.isInstanceOf[Person5] = true
false
false
访问控制符:
- private[this] : 被修饰的成员只能在当前类中被访问 ; 只能通过this. 来访问
- protected[this] : 被修饰的成员只能在当前类和当前子类中被访问 ; 当前类通过this.访问或者子类通过this.访问
- 任何没有被标为private或protected 的成员都是公共的(没有public)
eg1: private使用
class Person6 {
// 只有在当前对象中能够访问
private[this] var name = "super"
def getName = this.name // 正确!
def sayHelloTo(p:Person6) = {
println("hello" + p.name) // 报错!无法访问
}
}
object Person6 {
def showName(p:Person6) = println(p.name) // 报错!无法访问
}
eg2 : protected 使用
class Person7 {
// 只有在当前对象以及继承该类的当前对象中能够访问
protected[this] var name = "super"
def getName = {
// 正确!
this.name
}
def sayHelloTo1(p:Person7) = {
// 编译错误!无法访问
println(p.name)
}
}
object Person7 {
def sayHelloTo3(p:Person7) = {
// 编译错误!无法访问
println(p.name)
}
}
class Student7 extends Person7 {
def showName = {
// 正确!
println(this.name)
// 正确
println(name)
}
def sayHelloTo2(p:Person7) = {
// 编译错误!无法访问
println(p.name)
}
}
调用父类的constructor
实例化子类对象,必须要调用父类的构造器 ;在scala中,只能在子类的
主构造器
中调用父类的构造器 ,如下:class Student8(name:String, var clazz:String) extends Person8(name)
class Person8(var name:String){
println("name:"+name)
}
// 直接在父类的类名后面调用父类构造器
class Student8(name:String, var clazz:String) extends Person8(name)
object Main8 {
def main(args: Array[String]): Unit = {
val s1 = new Student8("张三", "三年二班")
println(s"${s1.name} - ${s1.clazz}")
}
}
//输出 :
name:张三
张三 - 三年二班
抽象类:
如果类的某个成员在当前类中的定义是不包含完整的,它就是一个抽象类
不完整定义有两种情况:1.方法没有方法体 2.变量没有初始化
抽象方法、抽象字段、抽象类 : 没有方法体的方法称为抽象方法,没有初始化的变量称为抽象字段。定义抽象类和Java一样,在类前面加上abstract关键字就可以了
//抽象类
abstract class Person9(val name:String) {
//抽象方法
def sayHello:String
def sayBye:String
//抽象字段
val address:String
}
class Student9(name:String) extends Person9(name){
//重写抽象方法
def sayHello: String = "Hello,"+name
def sayBye: String ="Bye,"+name
//重写抽象字段
override val address:String ="beijing "
}
object Main9{
def main(args: Array[String]) {
val s = new Student9("tom")
println(s.sayHello)
println(s.sayBye)
println(s.address)
}
}
匿名内部类:
匿名内部类是没有名称的子类,直接用来创建实例对象。Spark的源代码中有大量使用到匿名内部类。
abstract class Person10 {
//抽象方法
def sayHello:Unit
}
object Main10 {
def main(args: Array[String]): Unit = {
// 直接用new来创建一个匿名内部类对象
val p1 = new Person10 {
override def sayHello: Unit = println("我是一个匿名内部类")
}
p1.sayHello
}
}