java基础——day07-1 继承、super、this、抽象类

java基础——day07-1 继承、super、this、抽象类

继承

概述

  多个类中存在相同的属性和行为,将这些内容抽取到单独的一类中,那么多个类无需再定义这些属性和行为,只需要继承单独抽象出来的那个类即可。

例如:生活中的继承

java基础——day07-1 继承、super、this、抽象类

 

 

   从图中,我们可以了解到,兔子和羊属于食草类动物,狮子和豹子属于食肉类动物,而食肉动物和食草动物又属于动物类

 

 

  其中,多个类可以称为子类,单独那一个类成为父类、超类(superclass)或者基类

 

 java基础——day07-1 继承、super、this、抽象类

 

定义

  继承:就是子类继承父类的属性行为,使得子类对象具有与父类相同的属性(成员变量)、相同的行为(成员方法)。子类可以直接访问父类中的非私有的属性和行为。(例如父亲的姓名、父亲会打球 你不能继承)

好处

  1、提高代码复用性

  2、类与类之间产生了关系,是多态的前提

继承的格式

  通过extends关键字,可以声明一个子类继承一个父类,例如:

 

   java基础——day07-1 继承、super、this、抽象类

 

  演示:

  

java基础——day07-1 继承、super、this、抽象类
package day07.demo01;
//父类 -- 员工
public class Employee {
    //定义员工类
    //成员变量
    String name;
    int age;
    //成员方法
    public void work(){
        System.out.println("方法执行");
    }
}
定义一个父类-员工 java基础——day07-1 继承、super、this、抽象类
package day07.demo01;
//定义了一个员工的子类:教师 其继承父类 extends
public class Teacher extends Employee {

}
定义教师类 继承员工类 java基础——day07-1 继承、super、this、抽象类
package day07.demo01;

public class Assistant extends Employee {
    //定义员工的另一个子类 -助教

}
定义员工第二个子类--助教 java基础——day07-1 继承、super、this、抽象类
package day07.demo01;

/**
 * 子类就是父类 is-a 教师就是员工
 */
public class day07_1 {

    public static void main(String[] args) {
        //创建子类对象
        Teacher teacher = new Teacher();
        //子类继承了父类"工作"的成员方法
        teacher.work();
        //创建员工另外一个对象--助教
        Assistant assistant = new Assistant();
        //助教调用员工(父类)的工作(成员)方法
        assistant.work();
    }
}
main函数

  特点:提高代码的复用性

  关系:is -a

  java基础——day07-1 继承、super、this、抽象类

 继承后的特点——成员变量

1.成员变量不重名

  如果子类和父类中出现不重名的成员变量,这时访问是没有影响的,例如:

java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo02;

public class Fu {
    //创建父类成员变量
    int numFu = 10;
}
Fu java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo02;
//创建子类—Zi 继承父类—Fu
public class Zi extends Fu {
    //定义子类的成员变量
    int numZi = 20;
    /**
     * 此处子类含有两个成员变量
     * 一个是自己定义的numZi
     * 一个是继承Fu的numFu
     */

}
Zi java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo02;

public class demo01 {
    public static void main(String[] args) {
        //创建一个父类对象
        Fu fu = new Fu();
        System.out.println(fu.numFu); //只能使用父类的东西,没有任何子类的东西
        //创建一个子类对象
        Zi zi = new Zi();
        System.out.println(zi.numFu);//可以访问父类的成员变量
        System.out.println(zi.numZi);//也可以访问自定义的成员变量

    }
}
main

2.成员变量重名

  如果子类和父类中出现重名的成员变量,这时访问是有影响的。例如:

java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo03;

public class Fu {
    int num = 10;
    public void methodFu(){
        //访问的是父类中的num
        System.out.println("fu:"+num);
    }
}
Fu java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo03;
//创建子类—Zi 继承父类—Fu
public class Zi extends Fu {
    int num = 20;
    public void methodZi(){
        //访问的是子类的num  因为num里面有
        System.out.println("zi:"+num);
    }
    public void show(){
        //访问父类中的num
        System.out.println("子类访问父类的num:"+super.num);
        //访问子类自己的num
        System.out.println("子类访问自己的num:"+this.num);
    }
}
Zi java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo03;

/**
 * 子父类成员变量重名情况
 * 直接:等号左边是谁,没有则向上找
 * 间接:该方法属于谁 就优先用谁 没有则向上找
 */
public class demo {
    public static void main(String[] args) {
        Fu fu = new Fu();
        fu.methodFu();
        Zi zi = new Zi();
        System.out.println(zi.num); //直接访问子类 子类优先 20 没有则找父类的
        zi.methodZi();
        System.out.println("---------------------");
        zi.show();

    }
}
main

  注意:子父类出现同名成员变量时,在子类中访问父类中非私有成员变量时,要使用super关键字,修饰父类成员变量,类似与this关键字。

  使用格式:super.父类成员变量名(子父类同名变量名)

3.访问private修饰的父类成员变量

  当使用private(私有)修饰父类成员变量,那么如何访问父类私有成员变量

java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo04;

public class Fu {
    //使用private修饰父类成员变量
    private String name = "张若筠";
    private int age = 28;
    //这时需要通过get and set方法访问
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
Fu java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo04;
//子类继承父类
public class Zi extends Fu {

    public void show(){
        //访问父类的Name成员变量(属性)
        System.out.println(this.getName());
        //访问父类的name成员变量(属性)
        System.out.println(this.getAge());
    }
    public void setFu(){
        //修改父类的姓名属性(一般不建议)
        this.setName("海燕");
        this.setAge(40);
    }


}
Zi java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo04;

public class demo {
    public static void main(String[] args) {
        //创建一个子类对象
        Zi zi = new Zi();
        //调用子类访问父类的成员方法
        zi.show();
        //调用子类修改父类的成员方法
        zi.setFu();
        //打印修改后的父类
        zi.show();
    }
}
main

  我们可以通过getter and setter去访问父类的私有成员变量,但是关于setter要根据事情进行添加

继承后的特点——成员方法

1.成员方法不重名

  如果子类和父类中出现不重名的成员方法,这时调用不会有影响

java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo05;

public class Fu {
    //子父类成员方法不重名
    public void method(){
        System.out.println("我是父类中的成员方法");
    }
}
Fu java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo05;
//继承
public class Zi extends Fu{
    public void methodZi(){
        System.out.println("我是子类中的成员方法");
    }
}
Zi java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo05;
//子类和父类的成员方法 不重名
public class demo {
    public static void main(String[] args) {
        Zi zi = new Zi();
        //子类调用父类的成员方法
        zi.method();
        //子类调用自己的成员方法
        zi.methodZi();
    }
}
main

2.成员方法重名——重写(override)

  如果子类和父类中出现重名的成员方法,这时访问是一种特殊情况,叫做方法重写(override)

  方法重写:子类中出现和父类一模一样的方法时(返回值类型,方法名和参数列表相同),会出现覆盖效果,也称为重写复写声明不变,重新实现

  特点:创建的是子类对象,则优先用子类方法(创建的是父类对象 则优先用父类的方法) 

java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo06;

public class Fu {
    //创建父类的成员方法
    public void method(){
        System.out.println("我是父类中的方法");
    }
}
Fu java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo06;
//继承
public class Zi extends Fu {
    //定义子类中的成员方法 方法重写
    public void method(){
        System.out.println("我是子类中的成员方法--override");
    }
}
Zi java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo06;

public class demo {
    public static void main(String[] args) {
        //创建一个子类对象
        Zi zi = new Zi();
        //特点:创建的是子类对象,所以优先选择子类的方法 所以输出override
        zi.method();
        //创建一个父类对象
        Fu fu = new Fu();
        fu.method(); // 创建的是一个父类对象 优先选择父类的方法
    }
}
main

  对比:

  方法重写(override):发生在继承关系中,方法名称一样,参数列表也一样

  方法重载(overload):方法名称一样,参数列表不一样

重写的应用(完善父类的缺陷)

  子类可以根据需求,定义特定自己的行为。比如手机增加来电显示头像的功能

java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo07;
//创建手机 父类
public class phone {
    //创建父类的发送短信的功能
    public void SendMessage(){
        System.out.println("发短信");
    }
    public void call(){
        System.out.println("打电话");
    }
    public void showNum(){
        System.out.println("来电显示");
    }
}
父类-phone java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo07;
//继承父类 phone
public class newPhone extends phone {
    //新增来电显示姓名和头像
    //重载phone的电话功能
    @Override
    public void call(){
        //调用父类原始的大电话功能
        super.call();
        //增加自己新的功能——显示姓名和头像
        System.out.println("显示来电姓名");
        System.out.println("显示来电头像");
    }
}
子类-newPhone java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo07;

public class demo {
    public static void main(String[] args) {
        //创建一个newphone对象
        newPhone iphone = new newPhone();
        iphone.SendMessage();//子类调用父类发短信功能
        iphone.showNum();//子类调用父类 打电话的功能
        iphone.call();//子类调用重写功能
    }
}
main

  注意事项:

  1.子类覆盖父类方法时,必须保证权限小于等于父类权限

  2.子类覆盖父类方法,返回值类型、函数名和参数列表要一模一样

继承后的特点——构造方法

构造方法的格式和定义:

  格式:

    public 构造方法名(){}  //无参数的构造方法

  1.子类构造方法当中有一个默认隐含的“super()”调用,所以一定是先调用父类构造,后执行子类构造。

  2.子类构造可以通过super关键字调用父类重载构造(例如一个无参一个有参的构造方法)

  3.super的父类构造调用,必须是子类构造方法的第一个语句。即一个子类构造不能多次super构造

父类无参构造:

java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo08;

public class Fu {
    //定义父类无参构造方法
    public Fu(){
        System.out.println("父类的构造方法");
    }
}
Fu java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo08;
//继承
public class Zi extends Fu{
    //定义子类无参数构造方法
    public Zi(){
        System.out.println("this is Zi constractor");
    }
}
Zi java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo08;

public class demo {
    //继承中的构造方法
    public static void main(String[] args) {
        //创建子类对象
        Zi zi = new Zi();
        //发现其先执行了父类的构造方法 再执行子类的构造方法
    }
}
main

父类含参构造:

java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo08;

public class Fu {
    //定义父类无参构造方法
    public Fu(){
        System.out.println("父类的无参构造方法");
    }
    public Fu(int num){
        System.out.println("父类有参构造方法");
        System.out.println(num);
    }
}
含参-Fu java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo08;
//继承
public class Zi extends Fu{
    //定义子类无参数构造方法
    public Zi(){
        super(10); //调用父类有参构造方法
        System.out.println("this is Zi constractor");
    }
}
Zi java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo08;

public class demo {
    //继承中的构造方法
    public static void main(String[] args) {
        //创建子类对象
        Zi zi = new Zi();
        //发现其先执行了父类的构造方法 再执行子类的构造方法

    }
}
main

super和this

父类空间优先于子类对象的产生

  在首次创建子类对象时,先初始化父类空间,再创建其子类本身。目的在于子类对象包含了其对应的父类空间,所以先创建父类空间,子类就能获得父类的成员、方法。

  若父类成员非private修饰,则子类可以随意使用父类成员。代码体现在子类的构造方法调用时,一定会先调用父类的构造方法。(比如说:没有爹 哪来的儿子能继承的财产)

super和this的含义

  super:代表父类的存储空间标识(可以理解为父亲的引用)

        this:代表当前对象的引用(谁调用代表谁)

super和this的用法

1.访问成员

  this.成员变量   //本类的

  super.成员变量  //父类的

  this.成员方法名()  //本类的

  super.成员方法名()  //父类的

2.例如

java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo09;

public class Animal {
    //定义动物类的成员变量
    String name;
    int age;

    //定义动物类的成员方法
    public void eat(){
        System.out.println("Animal:eat");
    }
}
动物类 java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo09;
//定义猫类 继承父类 Animal
public class Cat extends Animal{
    //eat方法重载

    @Override
    public void eat() {
        //方法重载
        System.out.println("eat fish");
    }

    //定义猫类自己的成员方法
    public void eatTest(){
        super.eat();//---super调用父类的方法
        this.eat();//----this调用本类的方法

    }

}
猫类 java基础——day07-1 继承、super、this、抽象类
package day07.demo01.demo09;

public class demo {
    public static void main(String[] args) {
        //实例化一个Cat对象
        Cat cat = new Cat();
        //继承的成员变量
        cat.name = "小咪";
        cat.age = 2;
        //调用eatTest方法
        cat.eatTest();
    }
}
main

3.访问构造方法

  this(....)  ----本类的构造方法(具体查看上述手机案例)

  super(.....)   ----父类的构造方法

  1.子类的每个构造方法中均有默认的super()——调用父类的无参构造。

  2.手动调用父类构造方法会覆盖默认的super()

  3.super()和this()都必须是在构造方法的第一行,所以不能同时出现(例如不能出现两个super这样会报错)。

继承的特点

  1.一个类只能有一个父类,不可以有多个父类(一个孩子 只能有一个爹)

  class C extends A{}   //right

  class C extends B,C{} //error

  2.java支持多层次继承(继承体系[孩子只能有一个爹 一个爹能有多个孩子])

  class Fu{}

  class A extends Fu{}

  class B extends Fu{}

  注:*父类是Object类,所有的类默认继承Object,作为父类

  3.子类和父类是一种相对的概念

 

上一篇:java多态


下一篇:Java类WebServer及中间件拿webshell方法总结