继承

封装

对象代表什么,就得封装对应的数据,并提供数据对应的行为

继承

Java中提供一个关键字extends,用这个关键字,我们可以让一个类和另外一个类建立起继承关系


public class Student extends Person{}


Student称为子类(派生类) ,Person称为父类(基类或超类)

构建基础的核心:

1.共性内容抽取

2.子类是父类的一种

书写代码:从上往下

父类的父类Animal


package com.cjj.a01extendsDemo01;

public class Animal {
    //权限修饰符
    //private:子类无法访问
    //私有,只能在本类中访问
    
      
    //注意事项
    //子类只能访问父类中非私有的成员

    public void eat(){
        System.out.println("吃饭");
    }
    public void drink(){
        System.out.println("喝水");
    }
}


猫:父类


package com.cjj.a01extendsDemo01;

public class Cat extends Animal{
    public void catchMouse(){
        System.out.println("抓老鼠");
    }
}


狗:父类


package com.cjj.a01extendsDemo01;

public class Dog extends Animal{
    public void protectHome(){

    }
}


猫:子类


package com.cjj.a01extendsDemo01;

public class Ragdoll extends Cat{

}


猫:子类


package com.cjj.a01extendsDemo01;

public class ChineseLiHua extends Cat{
}


狗:子类


package com.cjj.a01extendsDemo01;

public class Huskie extends Dog{
    public void breakHome(){
        System.out.println("哈士奇在拆家");
    }
}


狗:子类


package com.cjj.a01extendsDemo01;

public class Teddy extends Dog{
    public void touch(){
        System.out.println("泰迪在蹭老吊的腿");
    }
}


使用继承的好处

可以把多个子类中重复的代码抽取到父类中了,提高代码的复用性。

子类可以在父类的基础上,增加其他的功能,使子类更加强大。

什么时候使用继承

当类与类之间,存在相同(共性)的内容,并且满足子类是父类的一直,就可以考虑使用继承,来继承代码。

继承的特点

java只支持单继承:一个子类只能继承一个父类

不支持多继承:一个子类不能同时继承多个父类

但支持多层继承:子类A继承父类B,父类B可以继承父类C

每一个类都之间或间接的继承object

子类只能访问父类中非私有的成员


public class A extends B{}
//默认继承
public class Object{}


子类到底能继承父类中的那些内容

构造方法 非私有 不能 private不能

构造方法是否可以被继承:父类的构造方法不能被子类继承


package com.cjj.a02extendsdemo02;

public class Test {
    public static void main(String[] args) {
        //利用空参构造创建子类对象
        Zi z1 = new Zi();
        //利用带参构造子类对象
        Zi z2 = new Zi("zhangsan",23);//会出现报错:Create constructor,


    }
}
    class Fu{
        String name;
        int age;
        
        public Fu(){
        }

        public Fu(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
     class Zi extends Fu{
         //如果一个类中没有构造方法,虚拟机会自动添加一个空参构造
        
    
}


成员变量 非私有 能 private 能

成员变量是否可以被继承 能

private修饰的能继承但是不可以直接使用

成员方法 非私有 能 private 不能

继承中:成员变量的访问特定

就近原则:现在局部位置找,本类成员位置找,父类成员位置找,逐级往上


package com.cjj.a03extendsDemo03;

public class Test {
    public static void main(String[] args) {
        Zi z = new Zi();
        z.zishow();
    }
}
class ye{
    String name = "ye";
}
class fu extends ye{
    String name = "fu";
}
class Zi extends fu{
    String name = "zi";
    public void zishow(){
        String name = "zishow";
        System.out.println(name);//就近原则
        System.out.println(this.name);//到本类的成员中找
        System.out.println(super.name);//直接从父类找
    }
}


继承中:成员方法的访问特点

直接调用满足就近原则:谁离我近,我就用谁

super调用,直接访问父类


package com.cjj.a05extendsDemo05;

public class Test {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.lunch();
        OverseaStudent s2 = new OverseaStudent();
        s2.lunch();
    }
}
class Person{
    public void eat(){
        System.out.println("吃米饭,吃菜");
    }
    public void drink(){
        System.out.println("喝白开水");
    }
}
class OverseaStudent extends Person{
    public void lunch(){
        this.eat();
        this.drink();

        super.eat();
        super.drink();
    }
    public void eat(){
        System.out.println("吃意大利面");
    }
    public void drink(){
        System.out.println("喝冰水");
    }
}
class Student extends Person{
    public void lunch(){
        //先在本类中查看eat和drink方法,就会调用子类的,如果没有,就会调用从父类中继承下来的eat和drink方法
        eat();
        drink();
        //直接调用父类
        super.eat();
        super.drink();
    }
}


方法的重写:当父类的方法不能满足子类现在的需求时,需要进行方法重写

书写格式:在继承体系中,子类出现了和父类一模一样的方法声明,我们就称这个子类就是方法的重写

@Override重写注释:1.@Override是放在重写后的方法上,校验子类重写时语法是否正确。

2.加上注解后如果有红色波浪线,表示语法错误

3.建议重写方法都加上@Override注解,代码安全,优雅!


//应用场景:当父类中的方法,不能满足子类现在的需求时,我们就需要把这个方法进行重写
    //注意:子类重写的方法上面需要加上@Override
    @Override
    public void eat(){
        System.out.println("吃意大利面");
    }
    @Override
    public void drink(){
        System.out.println("喝冰水");
    }
}


如果发生了重写,则会覆盖。

方法重写注意事项和要求:

1.重写方法的名称,形参列表必须与父类中的一致

2.子类重写父类方法时,访问权限子类必须大于等于父类

3.子类重写父类方法时,返回值类型子类必须小于等于父类

4.建议:重写的方法尽量与父类保持一致

5.私有方法不能被重写

6.子类不能重写父类的静态方法,如果重写会报错

7.只有添加到虚方法表中的方法才能被重写

继承中:构造方法的特点

1.父类中的构造方法捕获被子类继承

2.子类当中所有的构造方法默认先访问父类中的无参构造,再执行自己

为什么:1.子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据

2.子类初始化之前,一定要调用父类构造方法先完成父类数据空间的初始化

怎么调用父类构造方法?

1.子类构造方法的第一行语句默认都是:super(),不写也存在,且必须在第一行

2.如果想调用父类有参构造,必须手动写super进行调用。


package com.cjj.a07extendsDemo07;

public class Person {
    String name;
    int age;


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

    public Person() {
        System.out.println("父类的无参构造");
    }
}


package com.cjj.a07extendsDemo07;

public class student extends Person {
    public student() {
        //子类构造方法中有隐藏的super()去访问父类的无参构造
        super();
        System.out.println("子类的无参构造");
    }

    public student(String name, int age) {
        super(name,age);
    }
}


package com.cjj.a07extendsDemo07;

public class Test {
    public static void main(String[] args) {
        //创建学生对象
        student s = new student("zhansgna",23);
        System.out.println(s.name+","+s.age);

    }
}


总结:

1.子类不能继承父类的构造方法,但是可以通过super调用

2.子类构造方法的第一行,有一个默认的super()

3.默认先访问父类中的无参构造,在执行自己

4.如果想要方法文父类有参构造,必须手动书写

this,super使用总结

this:理解为一个变量,表示当前方法调用者的地址值

super:代表父类存储空间


public class Student {
    String name;
    int age;
    public void show(Student this){
        sout(this.name+","+this.age)
    }
}


关键字

访问成员变量

访问成员方法

访问构造方法

this

this.成员变量 访问本类成员变量

this.成员方法(···) 访问本类成员方法

this(····) 访问本类构造方法

super

super.成员变量 访问父类成员变量

super.成员方法(····) 访问父类成员方法

super(·······) 访问父类构造方法

小结

什么是继承,继承的好处?

继承是面向对象三大特征之一,可以让类与类之间产生父子关系。

可以把多个子类中重复的代码抽取到父类中,子类可以直接使用,减少代码冗余,提高代码的复用性

继承的格式


public class 子类 extends 父类{}


继承后子类的特点

子类可以得到父类的属性和行为,子类可以使用。

子类可以在父类的基础上新增其他功能,子类更强大。