类的继承

44 阅读5分钟

(一)继承的概念和基本语法

定义:在原有类的基础上定义一个新类,原有类称为父类,新类称为子类。class 子类名 extends 父类名 { 类体 }

语法: 假设定义Parents为父类,C1为子类,通过关键字extends子类便可以继承父类的特性

package level02
/**
 * 1. 类和对象(一个类,多个对象)
 * 2. new
 * 3. 构造函数,构造器
 * 4. 辅助构造器
 * 5. private, override, tostring, equals, this
 * 6. apply 单例模式
 * 7. 伴生类 伴生对象
 * 8. 多个类
 *  9.继承
 *    class子类 extends 父类
 *  10.好处: 不劳而获 子类可以直接使用父类的属性和方法
 */


object class09 {
  //
  class Animal(val name:String="") {

    val age:Int = 10

    def eat():Unit = {
      println("animal eat ....")
    }

    def run():Unit = {
      println("animal run .....")
    }
  }

  //
  class Dog() extends Animal(){

  }

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

}

1:继承的方法重写

package level02

/** 1. 类和对象(一个类,多个对象)
 * 2. new
 * 3. 构造函数,构造器
 * 4. 辅助构造器
 * 5. private, override, tostring, equals, this
 * 6. apply 单例模式
 * 7. 伴生类 伴生对象
 * 8. 多个类
 *  9.继承
 *    class子类 extends 父类
 *  10.好处: 不劳而获 子类可以直接使用父类的属性和方法*
 *  11. 子类对父类的方法的 重写.
 *  在子类中,通过override 覆盖(重写)父类的同名方法
 *
 *
 **/


object class10 {
  //
  class Parent() {
    def run():Unit = {
      println("run .....")
    }
  }

  //
  class son() extends Parent(){
    //
    def run1 ():Unit = {}

    override def run():Unit = {
      println("开自动驾驶的车  run...")
    }

  }

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

}

1-1:在子类的内部,使用super来访问父类

package level02

/**
 * 1. 类和对象(一个类,多个对象)
 * 2. new
 * 3. 构造函数,构造器
 * 4. 辅助构造器
 * 5. private, override, tostring, equals, this
 * 6. apply 单例模式
 * 7. 伴生类 伴生对象
 * 8. 多个类
 *  9.继承
 *    class子类 extends 父类
 *  10.好处: 不劳而获 子类可以直接使用父类的属性和方法
 *
 *  11. 子类对父类的方法的 重写.
 *  在子类中,通过override 覆盖(重写)父类的同名方法
 *
 *  12.super.在子类中访问父类
 *
 *
 **/


object class10 {
  //
  class Parent() {
    val name:String = ""
    def run():Unit = {
      println("run .....")
    }
  }

  //
  class son() extends Parent(){
    //如果希望对父类的方法进行改进:觉得不好
    def run1 ():Unit = {}

    override def run():Unit = {
      super.run()  //super.run在子类中,调用父类的方法
      println("开自动驾驶的车  run...")
    }

  }

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

}

(二):继承与多态

面向对象的三个特点:_封装  继承 多态 。同一操作作用于不同的对象, 可以有不同的解释,产生不同的执行结果,这就是多态性。

package level02

/**
 * 1. 类和对象(一个类,多个对象)
 * 2. new
 * 3. 构造函数,构造器
 * 4. 辅助构造器
 * 5. private, override, tostring, equals, this
 * 6. apply 单例模式
 * 7. 伴生类 伴生对象
 * 8. 多个类
 *  9.继承
 *    class子类 extends 父类
 *  10.好处: 不劳而获 子类可以直接使用父类的属性和方法
 *
 *  11. 子类对父类的方法的 重写.
 *  在子类中,通过override 覆盖(重写)父类的同名方法
 *
 *  12.super.在子类中访问父类
 *
 *
 **/


object class11 {
  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:构造器的调用

package level02

/**
 * 1. 类和对象(一个类,多个对象)
 * 2. new
 * 3. 构造函数,构造器
 * 4. 辅助构造器
 * 5. private, override, tostring, equals, this
 * 6. apply 单例模式
 * 7. 伴生类 伴生对象
 * 8. 多个类
 *  9.继承
 *    class子类 extends 父类
 *  10.好处: 不劳而获 子类可以直接使用父类的属性和方法
 *
 *  11. 子类对父类的方法的 重写.
 *  在子类中,通过override 覆盖(重写)父类的同名方法
 *
 *  12.super.在子类中访问父类
 *  13.面向对象编程的三大特征: 封装;--继承---;__多态___
 *  14. 构造器的调用顺序: 先调用父类的,在调用子类的
 *
 *
 **/


object class12 {
  class Father() {
      println("Father 的构造器 .....")
  }

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


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

  }
}

(三)处理构造器的调用顺序

代码验证调用顺序:父类的主构造器->子类主构造器->子类的辅助构造器

package level02

/**
 * 1. 类和对象(一个类,多个对象)
 * 2. new
 * 3. 构造函数,构造器
 * 4. 辅助构造器
 * 5. private, override, tostring, equals, this
 * 6. apply 单例模式
 * 7. 伴生类 伴生对象
 * 8. 多个类
 *  9.继承
 *    class子类 extends 父类
 *  10.好处: 不劳而获 子类可以直接使用父类的属性和方法
 *  11. 子类对父类的方法的 重写.
 *  在子类中,通过override 覆盖(重写)父类的同名方法
 *
 *  12.super.在子类中访问父类
 *  13.面向对象编程的三大特征: 封装;--继承---;__多态___
 *  14. 构造器的调用顺序: 先调用父类的,在调用子类的
**/


object class13 {
  //
  class Animal(val name:String,val age:Int) {
    println(s"父类的构造器被调用.... ${name}, ${age}")
    def say():Unit = {
      println(s"animal ${name},${age} ")
    }
  }

  //子类
  class Dog(name:String,age:Int, var color:String) extends  Animal (name, age){
    println(s"子类的构造器被调用....${name}, ${age}, ${color}")
    override def say():Unit = {
      super.say()
      println(s"狗狗....,我的颜色是${color}")
    }
  }

  def main(args: Array[String]): Unit = {
    val d1 = new Dog("旺财",1 ,"黑色")
    d1.say()
  }
}