【JAVA OOP】Day08 继承、super关键字、方法的重写、final关键字


Day08目标:

  • 理解继承的意义及用法;

  • 掌握super关键字的用法;

  • 理解super在继承中的意义;

  • 理解何时需要重写方法;

  • 掌握方法重写的语法及特点;

  • 掌握final关键字的用法


继承

继承的作用

  • 生活中的继承:

    • 继承财产:钱不用自己挣,自己也能花;

    • 继承皇位:江山不用自己打,自己也能坐;

    • 继承工作:工作不用自己找,自己也能干

    • 继承??:??不用自己?,自己也能?

  • 软件中的继承:

    • 代码不用自己写,自己也能用。
// Student类
class Student{
  String name;
  int age;
  String address;
  String className;
  String syuId;
  void eat(){}
  void sleep(){}
  void study(){}
}

// Teacher类
class Teacher{
  String name;
  int age;
  String address;
  String className;
  String syuId;
  void eat(){}
  void sleep(){}
  void study(){}
}

// Doctor类
class Doctor{
  String name;
  int age;
  String address;
  String className;
  String syuId;
  void eat(){}
  void sleep(){}
  void study(){}
}

这种写法是我们之前用的,我们发现这样太麻烦了,不符合一个优秀程序员的编程要求,于是:

// person类
class Person{
  String name;
  int age;
  String address;
  void eat(){}
  void sleep(){}
}

// Student类继承(extends)Person类
class Student extends Person {
  String className;
  String stuId;
  void study(){}
}

// Teacher类继承(extends)Person类
class Teacher extends Person {
  String salary;
  void teach(){}
}

// Doctor类继承(extends)Person类
class Doctor extends Person {
  String title;
  void cut(){}
}

/*
Student zg = new Student();
zg能访问:Student和Person类中的所有方法
*/

继承

  • 作用:实现代码复用

  • 语法:通过extends实现继承

  • Person这个被继承的类,我们叫:“超类、基类、父类”;去用Person这个类的类叫做“派生类、子类”。

    • 超类、基类、父类:共有的属性和行为;

    • 派生类、子类:特有的属性和行为;

    • 派生类可以访问派生类和超类,超类不能访问派生类;(孩子可以继承父亲,但是父亲不能继承儿子)

  • 单一继承 —— 一个超类可以有多个派生类,但一个派生类只能有一个超类(一个孩子只能有一个亲爹)

  • 泛化:从程序的设计角度而言叫做泛化,从代码实现角度而言叫继承,泛化就是继承

  • 继承要符合is的关系

  • 继承具有传递性

class Aoo {  -------- 可以访问a
  int a;
}
class Boo extends Aoo {  --------- 可以访问b、a
  int b;
}
class Coo extends Boo {  --------- 可以访问c、b、a
  int c;
}
  • 继承的是父类的成员变量和普通方法,不包括构造方法,父类的构造方法是被子类能过super来调用的

super

super关键字

  • 作用:指代当前对象的超类对象,类似this

    • super.成员变量名:访问超类的成员变量
    class Student extends Person{
      String className;
      String stuId;
      Student(String name, int age, String address, String className, String stuId) {
        super.name = name;
        super.age = age;
        super.address = address;
        this.className = className;
        this.stuId = stuId;
      }
    }
    
    • 使用情况:如果子类、父类中有同名变量时,我们要用父类的变量,必须用super,平时用this就可以了,很难出现用到super的情况,因为我们既然父类中已经有这个变量了,何必还要在子类再来一个?

    • super.方法名():调用超累的方法 —— 方法的重写讲,就在这一章

    • super():调用超类的构造方法

super与继承的关系

  • Java规定:构造子类前必须先构造父类!

  • 为了保证这个规定,Java做了两种处理:

    • 在子类的构造方法中若没有调用父类的构造方法,则默认super()调用超类的无参构造方法,无论你在子类是否用到了父类,只要你继承了,父类就必须先走一遍。
      class Aoo{
        Aoo() {
          System.out.println("父类构造方法");
        }
      }
    
      class Boo extends Aoo{
        Boo() {
          // super();
          System.out.println("子类无参构造方法")
        }
      }
    
    • 在子类的构造方法中若自己调用了超类的构造方法,则不再默认提供
      class Coo {
        Coo (int a) {
        }
      }
    
      class Doo extends Coo {
      }
    // 我们发现报错了,可以思考一下报错原因吗
    
      class Coo {
        Coo (int a) {
        }
      }
    
      class Doo extends Coo {
        // 如下代码是默认的但是被隐藏
        Doo { // 如果我们的类中没有构造方法则自动给无参构造
          super(); // 默认一定调用父类构造方法,但是父类的构造方法中有参数,而子类没有给父类值
        }
      }
    // 我们可以改成
    
      class Coo {
        Coo (int a) {
        }
      }
    
      class Doo extends Coo {
        Doo {
          super(5);
        }
      }
    // 现在有参数了,子类Doo自己调用父类Coo
    
  • 接下来我们让这段代码更为简单,在父类构造方法,在子类用super();方法,把活交给父亲干,子类只需要用就可以了!

Person.java

package day08;

// Person类
public class Person {
    String name;
    int age;
    String address;

    Person(){
    }
    Person(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    void eat(){
        System.out.println(name + "正在吃...");
    }
    void sleep(){
        System.out.println(name + "正在睡觉...");
    }
    void sayHi(){
        System.out.println("大家好!我叫" + name + ",今年" + age + "岁了,家住" + address);
    }
}

Student.java

package day08;

// Student类
public class Student extends Person{
    String className;
    String stuId;
    
    Student() {
    }
    Student(String name, int age, String address, String className, String stuId) {
        super(name, age, address);  // 把该父类做的让父类做,子类只需要用
        this.className = className;  // 该子类做的子类还得做
        this.stuId = stuId;
    }

    void study(){
        System.out.println(name + "正在学习...");
    }
}

Teacher.java

package day08;

// Teacher类
public class Teacher extends Person{
    double salary;

    Teacher(){
    }
    Teacher(String name, int age, String address, double salary) {
        super(name, age, address);  // 把该父类做的让父类做,子类只需要用
        this.salary = salary;  // 该子类做的子类还得做
    }

    void teach(){
        System.out.println(name + "正在上课......");
    }
}

Doctor.java

package day08;

// Doctor类
public class Doctor extends Person{
    String title;

    Doctor(){
    }
    Doctor(String name, int age, String address, String title){
        super(name, age, address);  // 把该父类做的让父类做,子类只需要用
        this.title = title;  // 该子类做的子类还得做
    }

    void cut(){
        System.out.println(name + "正在做手术...");
    }
}

新建一个ExtendsTest.java

package day08;

// Extends全系列测试类
public class ExtendsTest {
    public static void main(String[] args) {
        // 实例化:学生对象无参构造
        Student student = new Student();
        student.name = "张禹垚";
        student.age = 21;
        student.address = "齐齐哈尔";
        student.className = "JSD2407";
        student.stuId = "00109320";
        // 调用父类方法及子类方法(子类继承父类)
        student.sayHi();
        student.study();
        student.eat();
        student.sleep();

        System.out.println("-------------------------------------");

        // 实例化:学生对象有参构造
        Student zyy = new Student("张禹垚", 21,
                "齐齐哈尔", "JSD2407",
                "00109320");
        // 调用父类方法及子类方法(子类继承父类)
        zyy.sayHi();
        zyy.study();
        zyy.sleep();
        zyy.eat();

        System.out.println("-------------------------------------");

        // 实例化:Doctor对象有参构造
        Doctor doctor = new Doctor("张禹垚", 21,
                "北京", "院长");
        // 调用父类方法及子类方法(子类继承父类)
        doctor.sayHi();
        doctor.sleep();
        doctor.eat();
        doctor.cut();

        System.out.println("-------------------------------------");

        // 实例化:Teacher对象有参构造
        Teacher teacher = new Teacher("张禹垚", 21,
                "天津", 10000.0);
        // 调用父类方法及子类方法(子类继承父类)
        teacher.sayHi();
        teacher.eat();
        teacher.sleep();
        teacher.teach();

        System.out.println("-------------------------------------");

        // 父类不能访问子类(父亲不能继承儿子)
        // 实例化:Person父类无参构造
        Person person = new Person();
        person.address = "上海";
        person.name = "张禹垚";
        person.age = 21;
        // 调用父类方法(父类不继承):可以!
        person.sayHi();
        person.eat();
        person.sleep();
        // 调用子类方法(父类继承子类):不行!
//      person.cut();  // 编译错误:Cannot resolve method 'cut' in 'Person'
    }
}

方法的重写

方法的重写

方法的重写(Overriding)是面向对象编程中的一个重要概念,尤其在Java中,它体现了多态性。当一个子类继承(或实现)一个父类(或接口)时,可以对父类的某个方法进行重写,以提供自己特定的实现。

说白了,例如这个例子:

  class Restaurant {
      void makeFood () { 
          System.out.println("做中餐");
      }
  }

  // 我继承参观后还是想做中餐 ———————————— 不需要重写
  class Aoo extends Restaurant {
  }

  // 我继承参观后想改做西餐 —————————————— 需要重写
  class Boo extends Restaurant {
      void makeFood() { 
      System.out.println("做西餐");
      }
  }

  // 我继承参观后想在中餐基础上加入西餐 —————————— 需要重写(先super中餐,再加入西餐)  
class Coo extends Restaurant {
      void makeFood() {
          super.makeFood();
          System.out.println("做西餐");
      }
  }

final

  • 表示最终的、不可改变的

  • 特点:

    • 修饰变量:此变量不可改变

    • 修饰方法:方法不能被重写

    • 修饰类:类不能被继承

final修饰变量

  • final修饰变量,表示变量不能被改变。
class Eoo {
    final int a = 5;
    int b = 6;
    void test(){
        a = 55;  // 编译错误,final修饰的变量不能被改变
        b = 66;
    final int c = 8;
        c = 88;  // 编译错误
    }
}
  • final修饰方法,表示方法不能被重写
class Foo {
    final void show() {
        void test() {
        }
    }
}

class Goo extends Foo {
    // void show() {  // 编译错误,final修饰方法不能被重写
    void test() {
    }
}
  • final修饰类,表示类不能被继承
final class Hoo {
}

class Ioo extends Hoo {  // final修饰的类不能被继承
}
  • JDK中一些类被定义为final的:String、Math、Integer、Double等
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值