继承

继承

继承的概述:

  • 父类怎么形成的:我们的定义了多个类,发现这些类中有很多重复性的代码,我们就定义了一个父类,将相同的代码抽取出来放到父类中,其他的类直接继承这个父类,就可以直接使用父类中的内容了

  • 怎么去继承: extends
    子类 extends 父类

继承的特点:

1.继承只支持单继承,不能多继承
public class A extends B,C{} -> 错误
2.继承支持多层继承
public class A extends B{}
public class B extends C{}
3.一个父类可以有多个子类
public class A extends C{}
public class B extends C{}

4.构造方法不能继承,也不能重写
私有方法可以继承,但是不能被重写
静态方法可以继承,但是不能被重写

  • 注意:

    • 子类可以继承父类中私有和非私有成员,但是不能使用父类中私有成员
    • 构造方法不能继承
  • 继承怎么学:

    • 继承不要从是否"拥有"方面来学习
      要从是否能"使用"方面来学习

继承的使用:

  • 定义一个父类,在其中定义重复性的代码
  • 定义一个子类继承父类 -> extends
    子类 extends 父类
  • 创建子类对象,直接使用父类中非私有成员

例子:

/*
    java提供了一个关键字表示继承, extends
    class 子类 extends 父类{

    }

    class A extends B{

    }

    A:子类,派生类
    B:父类,超类,基类
 */
class Person2{
    String name;
    int age;

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

    public void study(){
        System.out.println("学习");
    }
}

class Student2 extends Person2{
//    String name;
//    int age;
//
//    public void eat(){
//        System.out.println("吃饭");
//    }
//
//    public void study(){
//        System.out.println("学习");
//    }
}

class Teacher2 extends Person2{

}




public class PersonDemo2 {
    public static void main(String[] args) {
        Student2 student2 = new Student2();
        student2.name = "张三";
        student2.age = 18;
        System.out.println(student2.name+"--"+student2.age);
        student2.eat();
        student2.study();
    }
}

使用继承的注意事项

使用继承的注意事项:
    1、不要有一点相同的部分就使用继承
        class A{
            fun1();
            fun2();
            fun3();
        }

        class B{
            fun2();
            fun5();
            fun6();
        }

       什么时候使用继承呢?两个类之间满足英语语法上的is a关系就可以了。

    2、子类无法继承父类中的私有成员【私有的成员变量或私有的成员方法】
    3、构造方法无法继承
    4、子类继承父类之后,子类中可以编写自己特有的功能和属性
    5、一个类同一时刻只能继承一个类,不允许一次继承多个类,但是可以多重继承,形成继承体系

例子:

class Fu {
    int a = 10;
    static int b = 20;
    private int c = 30;

//    Fu(){
//
//    }

    public void show1(){
        System.out.println("这是父类中的成员方法show1");
    }

    public static void show2(){
        System.out.println("这是父类中的成员方法show2");
    }
    private void show3(){
        System.out.println("这是父亲私有的成员方法show3");
    }
}

class Zi extends Fu {
    //int a = 10;
    //static int b = 20;
    int d = 100;

//    public void show1(){
//        System.out.println("这是父类中的成员方法show1");
//    }
//
//    public static void show2(){
//        System.out.println("这是父类中的成员方法show2");
//    }

//    Fu(){
//
//    }
    public void fun1() {
        System.out.println(a);
        System.out.println(b);
        show1();
        show2();
//        show3();
//        System.out.println(c);
    }
}

public class ExtendsDemo1 {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.fun1();

//        zi.show1();
//        Zi.show2();
    }
}

super

super的概述:java提供了一关键字super可以在子类中使用直接父类中的非私有的成员【成员变量,构造方法,成员方法】

继承中构造方法的特点

1.注意:new子类对象时,会先初始化父类(先走父类无参构造方法)
2.原因:
每个构造方法的第一行,默认都会有一个super(),不写jvm自动提供一个
super()代表的是父类无参构造

public class Fu {
    public Fu(){
        System.out.println("我是父类中的无参构造");
    }
}

public class Zi extends Fu{
    public Zi(){
        //super();
        System.out.println("我是子类中的无参构造");
    }

    public Zi(int i){
        //super();
        System.out.println("我是子类中的有参构造");
    }
}
public class Test {
    public static void main(String[] args) {
        Zi zi = new Zi();
        System.out.println("===========");
        Zi zi1 = new Zi(10);
    }
}

super的使用

1.概述:代表的是父类引用
2.作用:可以调用父类中的成员
3.使用:
  a.调用父类构造方法-> 在子类中的构造中写
    super() -> 调用父类无参构造
    super(实参)  -> 调用父类有参构造
      
  b.调用父类成员变量:
    super.成员变量名
        
  c.调用父类成员方法:
    super.成员方法名(实参)
public class Fu {
    int num = 10;
    public Fu(){
        System.out.println("无参构造");
    }

    public Fu(int data){
        System.out.println("有参构造");
    }

    public void method(){
        System.out.println("我是父类中的method方法");
    }
}

public class Zi extends Fu{
    int num = 100;
    public Zi(){
        super();//调用父类中的无参构造
        System.out.println("无参构造");
    }

    public Zi(int num){
        super(10);//调用父类的有参构造
        System.out.println("有参构造");
    }

    public void method(){
        super.method();//调用父类的method方法
        System.out.println("我是子类中的method方法");
        System.out.println(num);//子类自己的
        System.out.println(super.num);//调用父类的num
    }
}

public class Test01 {
    public static void main(String[] args) {
        Zi zi = new Zi();
        System.out.println("============");
        Zi zi1 = new Zi(10);
        System.out.println("============");
        Zi zi2 = new Zi();
        zi2.method();

    }
}

注意:

子类的每个构造方法中均有默认的super(),调用父类的空参构造。手动调用父类构造会覆盖默认的super()。

super() 和 this() 都必须是在构造方法的第一行,所以不能同时出现。

super(…)是根据参数去确定调用父类哪个构造方法的。

继承和构造方法的关系:

​ 1、子类的构造方法第一句默认会有一个super(), 调用的是父亲中的无参构造方法
​ 2、要想初始化子类,必须先初始化其父类
​ 3、无论子类构造方法第一句话调用的是父类中有参构造方法还是无参构造方法,都是对父亲的初始化
​ 4、java中的类不允许多次初始化
​ 5、子类构造方法中对父亲初始化的代码必须是第一句话

继承和成员方法的关系:

​ 方法的重写:在继承关系中,子类中的方法声明【返回值类型,方法名,参数列表】与父类中的一模一样,只是方法实现不一样,这个现象成为方法的重写
​ 方法的重载:在同一个类中,方法名一样,参数列表不同现象,方法的重载,与返回值无关。

面试题:方法的重载和重写什么区别?

注意:并不是所有的方法子类都能重写?

​ 1、父类中静态的方法子类无法重写。可以继承使用父亲的静态成员,不能重写。
​ 2、父类中的私有方法子类无法重写,私有的都无法继承,更不用想重写了。
​ 3、重写和权限有关系吗? public protected 默认的 private
​ 子类重写的方法权限不能比父亲的还要低 可以是大于等于,推荐除特殊要求外,保持一致

例子

class Fu6{
    protected void fun1(){
        System.out.println("这是父类中的fun1方法");
    }

    public static void fun2(){
        System.out.println("这是父类中的静态的fun2方法");
    }

    private void fun3(){
        System.out.println("这是父类中的私有的fun3方法");
    }

}

class Zi6 extends Fu6{
//    public void fun1(){
//        System.out.println("这是父类中的fun1方法");
//    }

    @Override
    protected void fun1(){
        System.out.println("好好学习,天天向上!");
    }

    //无法重写
//    public static void fun2(){
//        System.out.println("数加666");
//    }
//
//    @Override
//    private void fun3(){
//        System.out.println("数加666");
//    }

    public void show1(){
        fun1();
    }

    public int show1(String n){
        return 10;
    }
}

public class ExtendsDemo5 {
    public static void main(String[] args) {
        Zi6 zi6 = new Zi6();
        zi6.show1();
        zi6.fun1();
    }
}

子类可以重写父类中非私有,非静态的方法

    新需求:只允许子类使用父类中的非私有,非静态的方法,不允许重写,一旦重写就会报错

    java提供了一个关键字给我们使用final
    final: 最终的,不可改变的
    可以修饰类,变量,成员方法
    修饰成员方法:方法不能被重写,可以被继承使用
    修饰成员类:被final所修饰的类,类不能被继承
    修饰变量:被final所修饰的变量,变量变常量,不能修改变量的值。

    final修饰的变量赋值的时机:必须在构造方法完毕之前赋值,否则程序报错。

例子

class Fu7{
    public final void show(){
        System.out.println("这是父类中的非私有,非静态的方法show");
    }
}

class Zi7 extends Fu7{
    final int A = 11;

    public void fun1(){
//        A = 12;
        System.out.println(A);
    }

//    @Override
//    public void show(){
//        System.out.println("已重写父亲的方法show");
//    }
}

class Demo2{
    int a = 10;
}

class Demo3{
    final int a;

    //使用构造代码块给final修饰的变量赋值,优先于构造方法执行
//    {
//        a =100;
//    }

    //可以在构造方法执行过程中进行赋值
    Demo3(){
        a = 200;
    }

}

public class ExtendsDemo6 {
    public static void main(String[] args) {
//        Zi7 zi7 = new Zi7();
//        zi7.show();
//        zi7.fun1();
//        Math.PI

//        final Demo2 d1 = new Demo2(); // 修饰引用数据类型变量,指的是地址值不能被修改
//        System.out.println(d1.a);
//        d1.a = 100;
//        System.out.println(d1.a);
//        d1 = new Demo2();

    }
}

posted @   09250327  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示