抽象类
- 抽象方法:指一些只有方法声明,而没有具体方法体的方法。
- 抽象字段:定义了field,但是没有给出初始值,则此field为抽象field
- 抽象类:如果一个类中有抽象字段或者抽象方法的类一定是抽象类,抽象类中不一定有抽象方法或者抽象字段,只需要用abstract 修饰
- 抽象类:不可以实例化的,子类继承抽象类必须实现抽象类中的成员
- 子类在实现父类的抽象字段或者抽象方法的时候,不使用override
- 子类在覆盖(重写)父类的字段或者方法的时候,一定使用override
- 重写字段的实质是在重写字段的setter、getter方法
abstract class Person(val name: String) {
def sayHello
val age: String
}
class Student(name: String) extends Person(name) {
def sayHello: Unit = println("Hello, " + name)
val age: String = "leo"
}
匿名子类
- 在Scala中,匿名子类是非常常见,而且非常强大的。Spark的源码中也大量使用了这种匿名子类
- 匿名子类:定义一个类的没有名称的子类,并直接创建其对象。(通过new 父类名 进行创建,可以同时重写父类中的成员)
- 可以将对象的引用赋予一个变量
object test {
def main(args: Array[String]): Unit = {
class Person(protected val name: String) {
def sayHello = "Hello, I am " + name
}
val p = new Person("leo") { //匿名子类(创建匿名子类的同时直接创建匿名子类的对象p)
override def sayHello = "Hi, I'm " + name //重写父类中的方法
}
def greeting(s:Person) { //将该匿名子类的对象传递给其他函数
println(s.sayHello)
}
greeting(p)
}
}
内部类
- 内部类是隶属于对象而不是隶属于类本身
- 创建内部类的实例:需要先创建外部类的实例,在创建内部类的实例。如:
- val outer1= new OutClass
- val inner1= new outer1.InnerClass
- 直接调用内外部类的属性的方式
- 使用this的方式调用:OutClass.this.name ()表示外部类 this.name和name表示内部类
- 使用别名的方式调用:outer.name表示外部类 (outer表示外部类对象的别名)
class OutClass(val name:String) { outer=>
class InnerClass(val name:String){
def info1=println("外部类:"+OutClass.this.name+"内部类:"+this.name) //第一种方法this的形式调用
def info2=println("外部类:"+outer.name+"内部类:"+name) //第二种方法调用,别名调用外部类
}
}
object printOut{
def main(args: Array[String]): Unit = {
val outer= new OutClass("out")
val inner= new outer.InnerClass("inner")
inner.info1
inner.info2
}
}