继承

12 阅读2分钟

继承

    1. 类和对象(一个类 多个对象)
    1. new
    1. 构造函数 构造器
    1. 辅助构造器
    1. private override toString equals this
    1. apply 单列模式
    1. 伴生类 伴生对象

    1. 多个类
    1. 继承 : class 子类 extend 父类
    1. 好处:不劳而获。 子类可以直接使用父类的属性和方法
    1. 子类对父类方法的 重写 : 在子类中通过override 覆盖(重写)父类的同名方法
    1. super 在子类中访问父类
    1. 面向对象编程的三大特征: 封装,继承,多态
    1. 构造器的调用顺序:先调用父类的 再调用子类的

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

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

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

继承的特点:Dog就直接具备了animal的功能eating。

代码演示:

 
class Animal() {
  def eat(): Unit = {
    println("animal eat...")
  }
}
class Dog() extends Animal() {

}

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

运行结果:

(二)继承的好处

好处:复用代码和实现多态。不劳而获:子类可以直接使用父类的属性和方法

复用代码:   子类可以继承父类的特性。

多态:   子类可以在自己内部实现父类没有的特性。

代码演示:


// 动物
class Animal(var 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()
}

(三)继承的方法重写

子类对父类方法的 重写:在子类中通过override 覆盖(重写)父类的同名方法
super 在子类中访问父类

代码演示:


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

class Son extends Parent(){

  // 如果希望对父类的方法进行改进: 觉得不好
  def run1():Unit = {
    println("开自动驾驶的车 run...")
  }

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

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

代码说明:在子类的内部,使用super来访问父类

(四)继承与多态

面向对象的三个特点:封装  继承 多态

代码演示:


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

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

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

代码演示:

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

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

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