scala面向对象编程之继承

简介: scala使用extends关键字来实现继承。可以在子类中定义父类中没有的字段和方法,或者重写父类的方法。示例1:实现简单继承

@[TOC]

1、继承extends

scala使用extends关键字来实现继承。可以在子类中定义父类中没有的字段和方法,或者重写父类的方法。
示例1:实现简单继承

class Person1 {
  var name = "super"

  def getName: String = 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)
    println(p1.getName)
  }
}

在这里插入图片描述

示例2:单例对象实现继承

class Person2 {
  var name = "super"

  def getName = this.name
}

object Student2 extends Person2

object Main2 {
  def main(args: Array[String]): Unit = {
    println(Student2.getName)
  }
}

在这里插入图片描述

2、override和super

如果子类要覆盖父类中的一个非抽象方法或者属性时,覆盖属性必须要使用override关键字重写一个val字段,覆盖方法再前面加上override。同时可以使用super关键字来访问父类的成员

示例1:class继承class

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)
  }
}

在这里插入图片描述

3、isInstanceOf和asInstanceOf

我们经常要在代码中进行类型的判断和类型的转换。在Java中,我们可以使用instanceof关键字、以及(类型)object来实现,在scala中如何实现呢?
scala中对象提供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]

例子:

object Main4 {
  def main(args: Array[String]): Unit = {
    val s1:Person4 = new Student4

    // 判断s1是否为Student4类型
    if(s1.isInstanceOf[Student4]) {
      // 将s1转换为父类Person4类型
      val s2 = s1.asInstanceOf[Person4]
      println(s2)
    }

  }
}

在这里插入图片描述

4、getClass和classOf

isInstanceOf 只能判断出对象是否为指定类以及其子类的对象,而不能精确的判断出,对象就是指定类的对象。如果要求精确地判断出对象就是指定类的对象,那么就只能使用 getClass 和 classOf 。
对象.getClass可以精确获取对象的类型classOf[x]可以精确获取类型使用操作符可以直接对比

示例:

object Student5{
  def main(args: Array[String]) {
    val p:Person5=new Student5
    //判断p是否为Person5类的实例
    println(p.isInstanceOf[Person5])
    println(p.isInstanceOf[Student5])

    //判断p的类型是否为Person5类
    println(p.getClass == classOf[Person5])

    //判断p的类型是否为Student5类
    println(p.getClass == classOf[Student5])
  }
}

在这里插入图片描述

5、访问修饰符

Java中的访问控制,同样适用于scala,可以在成员前面添加private/protected关键字来控制成员的可见性。但在scala中,没有public关键字,任何没有被标为private或protected的成员都是公共的。

1、private[this]修饰符

被修饰的成员只能在当前类中被访问。或者可以理解为:只能通过this.来访问(在当前类中访问成员会自动添加this.)。
例子:

class Person6 {
  // 只有在当前对象中能够访问
  private[this] var name = "super"

  var sg = "sg"

  def getName = this.name    // 正确!

  // 传入一个Person6对象
  def sayHelloTo(p: Person6) = {
    println("hello" + p.name)     // 报错!无法访问
  }
}

object Person6 {
  def showName(p:Person6) = println(p.name)  // 报错!无法访问
}
2、protected[this]修饰符

被修饰的成员只能在当前类和当前子类中被访问。也可以理解为:当前类通过this.访问或者子类通过this.
访问示例

class Person7 {
  // 只有在当前类以及继承该类的当前对象中能够访问
  protected[this] var name = "super"

  def getName = {
    // 正确!
    this.name
  }

  def sayHelloTo1(p:Person7) = {
    // 编译错误!无法访问
    println(p.name)
  }
}

object Person7 {
  def sayHelloTo2(p:Person7) = {
    // 编译错误!无法访问
    println(p.name)
  }
}

class Student7 extends Person7 {
  def showName = {
    // 正确!
    println(this.name)
  }

  def sayHelloTo3(p:Person7) = {
    // 编译错误!无法访问
    println(p.name)
  }
}
6、调用父类的constructor(构造器)

java实例化子类对象,会自动调用父类的构造器,在scala中,只能在子类的主构造器中调用父类的构造器
示例

class Person8(var name:String){
  println("name:"+name)
}

// 直接在父类的类名后面调用父类构造器
class Student8(name:String, var age:String) extends Person8(name)

object Main8 {
  def main(args: Array[String]): Unit = {
    val s1 = new Student8("李四", "12")
    println(s"${s1.name} - ${s1.age}")
  }
}

在这里插入图片描述

7、抽象类

如果类的某个成员在当前类中的定义是不包含完整的,它就是一个抽象类
不完整定义有两种情况:
1.方法没有方法体
2.变量没有初始化
没有方法体的方法称为抽象方法,没有初始化的变量称为抽象字段。抽象类的定义和Java一样,在类前面加上abstract关键字就可以了
示例

abstract class Person9(val name:String) {
  //抽象方法
  def sayHello:String
  def sayBye:String
  //抽象字段
  val age:String
}

class Student9(name:String) extends Person9(name){
  //重写抽象方法
  def sayHello: String = "Hello,"+name
  def sayBye: String ="Bye,"+name
  //重写抽象字段
  override val age:String ="18"
}

object Main9{
  def main(args: Array[String]) {
    val s = new Student9("Bob")
    println(s.sayHello)
    println(s.sayBye)
    println(s"我${s.age}啦!")
  }
}

在这里插入图片描述

8、匿名内部类

匿名内部类是没有名称的子类,直接用来创建实例对象。Spark的源代码中有大量使用到匿名内部类。
例子:

abstract class Person10 {
  //抽象方法
  def sayHello:Unit
}

object Main10 {
  def main(args: Array[String]): Unit = {
    // 直接用new来创建一个匿名内部类对象
    val p1 = new Person10 {
      def sayHello: Unit = println("这是一个匿名内部类")
    }
    p1.sayHello
  }
}

在这里插入图片描述

目录
相关文章
|
6月前
|
Java Scala
165 Scala 继承
165 Scala 继承
18 0
|
5天前
|
Java Scala
scala中的面向对象编程
scala中的面向对象编程
10 3
|
Java Scala
Scala快速入门-7-继承
继承类 extends 重写方法时必须用override 只有主构造器可以调用超类的主构造器 重写字段 抽象类、字段
|
Java Scala
scala面向对象编程之类与对象
scala是支持面向对象的,也有类和对象的概念。 示例:定义一个User类,并添加成员变量/成员方法,创建一个Main object,添加一个main方法,并创建Customer类的对象,并给对象赋值,打印对象中的成员,调用成员方法
86 0
scala面向对象编程之类与对象
|
Java Scala
scala面向对象编程之trait特质
特质就像是java的implement,是scala中代码复用的基础单元,它可以将方法和字段定义封装起来,然后添加到类中与类继承不一样的是,类继承要求每个类都只能继承一个超类,而一个类可以添加任意数量的特质。特质的定义和抽象类的定义很像,但它是使用trait关键字
88 0
scala面向对象编程之trait特质
|
Scala 开发者
Scala 的继承注意事项|学习笔记
快速学习 Scala 的继承注意事项。
74 0
Scala 的继承注意事项|学习笔记
|
Java Scala 开发者
Scala 的继承快速入门|学习笔记
快速学习 Scala 的继承快速入门。
73 0
Scala 的继承快速入门|学习笔记
|
Java Scala Python
Java,Python,Scala比较(二)类与继承
UML图如下: 完整的Java代码如下: SimpleGeometricObject.java public class SimpleGeometricObject { private String col...
897 0
|
Java Scala 编译器