Scala的 类的继承

42 阅读2分钟

继承的基本概念

定义:在原有类的基础上定义一个新类,原有类称为父类,新类称为子类。

class 子类名 extends 父类名 { 类体 }

好处:复用代码和实现多态。复用代码:子类可以继承父类的特性。多态: 子类可以在自己内部实现父类没有的特性。

继承的基本代码

/**
 * 1. 类和对象(一个类,多个对象)
 * 2. new
 * 3. 构造函数,构造器
 * 4. 辅助构造器
 * 5. private,override,toString,equals,this
 * 6. apply 单例模式
 * 7. 伴生类 伴生对象
 * --------------------------------------------------------------
 * 8. 多个类
 * 9. 继承
 *    class 子类 extends 父类
 */

object class11 {
  //动物
  class Aniaml() {
    def eat():Unit={
      println("animal eat....")
    }
  }
  class Dog() extends Aniaml() {

  }

  def main(args: Array[String]): Unit = {
    val d1=new Dog
    d1.eat()
  }
}

继承的好处

  1. 好处:不劳而获。 子类可以直接使用父类的属性和方法

基本代码

/**
 * 10. 好处:不劳而获。 子类可以直接使用父类的属性和方法
 */

object class12 {
  //动物
  class Aniaml() {
    def eat():Unit={
      println("animal eat....")
    }
    def run():Unit={
      println("animal run....")
    }
  }

  //狗
  class Dog() extends Aniaml() {

  }

  def main(args: Array[String]): Unit = {
    val d1=new Dog
    d1.eat()
    d1.run()
  }
}

继承的方法重写

  1. 子类对父类方法的 重写

在子类中,通过override 覆盖(重写) 父类的同名方法

  1. super. 在子类中访问父类

基本代码

/**
 * 11. 子类对父类方法的 重写
 *     在子类中,通过override 覆盖(重写) 父类的同名方法
 * 12. super. 在子类中访问父类
 */

object class13 {
  class Parent() {
    val name:String=""
    def run():Unit={
      println("run....")
    }
  }
  class Son extends Parent(){
    //如果希望对父类的方法进行改进:觉得不好
    override def run():Unit={
      super.run()  //super.run 在子类中,调用父类的方法
      println("开自动驾驶的车 run....")
    }
  }

  def main(args: Array[String]): Unit = {
    val s1=new Son()
    s1.run()
  }
}

继承与多态

  1. 面向对象编程的三大特征:封装 继承 多态

基本代码

/**
 * 13. 面向对象编程的三大特征:封装  继承  多态
 */

object class14 {
  class Fruit() {
    def eat():Unit={
      println("eat....")
    }
  }
  class Apple extends Fruit{
    override def eat(): Unit = {
      println("吃掉果皮,中间不能吃")
    }
  }
  class Watermelon extends Fruit{
    override def eat(): Unit = {
      println("削皮,中间最好吃")
    }
  }

  def main(args: Array[String]): Unit = {
    //参数类型:父类
    def test(fruit: Fruit):Unit={
      fruit.eat()
    }
    val a1=new Apple()
    test(a1)  //传入子类

    val w1=new Watermelon()
    test(w1)
  }
}

处理构造器的调用顺序

  1. 构造器的调用顺序:先调用父类,再调用子类

基本代码

/**
 *14. 构造器的调用顺序:先调用父类,再调用子类
 */

object class15 {
  class Father() {
    println("Father 的构造器...")
  }
  class Son extends Father(){
    println("Son 的构造器...")
  }

  def main(args: Array[String]): Unit = {
    // 创建一个子类对象时
    //先调用父类的构造器 → 子类的构造器
    new Son()
  }
}