返回顶部
首页 > 资讯 > 后端开发 > Python >Java中的重要核心知识点之继承详解
  • 638
分享到

Java中的重要核心知识点之继承详解

2024-04-02 19:04:59 638人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录一、继承1、概念2、语法3、父类成员的访问(1)子类中访问父类成员变量(2)子类中访问父类成员方法4、super关键字5、子类构造方法6、super和this7、代码块执行顺序8

一、继承

1、概念

继承(inheritance)机制:是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特 性的基础上进行扩展,增加新功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构, 体现了由简单到复杂的认知过程。
继承主要解决的问题是:共性的抽取,实现代码复用。

例如:狗和猫都是动物,分别定义一个猫类和狗类,他们都是动物,让他们来继承动物类,那么我们就可以将共性的内容进行抽取,然后采用继承的思想来达到共用。


// Dog.java
public class Dog{
string name;
int age;
float weight;
public void eat(){
System.out.println(name + "正在吃饭");
}
public void sleep(){
System.out.println(name + "正在睡觉");
}
void Bark(){
System.out.println(name + "汪汪汪~~~");
}
}
// Cat.Java
public class Cat{
string name;
int age;
float weight;
public void eat(){
System.out.println(name + "正在吃饭");
}
public void sleep()
{
System.out.println(name + "正在睡觉");
}
void mew(){
System.out.println(name + "喵喵喵~~~");
}
}

在这里插入图片描述

2、语法

在Java中如果要表示类之间的继承关系,需要借助extends关键字,具体如下:


修饰符 class 子类 extends 父类 {
// ...
}

那么对于猫和狗的场景,我们让猫类和狗类均继承自动物类:


public class Animal{
String name;
int age;
public void eat(){
System.out.println(name + "正在吃饭");
}
public void sleep(){
System.out.println(name + "正在睡觉");
}
}
// Dog.java
public class Dog extends Animal{
void bark(){
System.out.println(name + "汪汪汪~~~");
}
}
// Cat.Java
public class Cat extends Animal{
void mew(){
System.out.println(name + "喵喵喵~~~");
}
}
// TestExtend.java
public class TestExtend {
public static void main(String[] args) {
Dog dog = new Dog();
// dog类中并没有定义任何成员变量,name和age属性肯定是从父类Animal中继承下来的
System.out.println(dog.name);
System.out.println(dog.age);
// dog访问的eat()和sleep()方法也是从Animal中继承下来的
dog.eat();
dog.sleep();
dog.bark();
}
}

注意事项:
1、子类会将父类中的成员变量或成员方法继承到子类中去。
2、子类中一定要含有与父类不同的成员方法或者成员变量,体现出与父类的不同,否则继承就失去了意义。

3、父类成员的访问

(1)子类中访问父类成员变量

第一种情况:子类和父类不存在同名成员变量


public class Base {
    int a;
    int b;
}
public class Derived extends Base {
    int c;
    int d;

    public void method(){
        a=10;//访问的是从父类继承下来的成员变量a
        b=20;//访问的是从父类继承下来的成员变量b
        c=30;//访问的是子类自己的成员变量c
        d=40;//访问的是子类自己的成员变量d
    }
}

第二种情况:子类和父类成员变量有同名


public class Base {
    int a;
    int b;
}
public class Derived extends Base {
    int b;
    int c;

    public void method(){
        a=10;
        b=20;//此时访问的是父类中的b还是子类中的b?
        c=30;
        //d=40; 编译报错,因为在子类和父类中都不存在成员变量d
    }
}

注意事项:
在子类方法中或者通过子类对象访问成员变量时:
1、如果访问的成员变量子类中有,优先访问自己的成员变量。
2、如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。
3、如果访问的成员变量与父类中成员变量同名,则优先访问自己的,即:子类将父类同名成员隐藏了。

(2)子类中访问父类成员方法

第一种情况:子类和父类中不存在同名成员方法


public class Base {
    public void methodA(){
        System.out.println("我是父类成员方法");
    }
}
public class Derived extends Base {
    public void methodB(){
        System.out.println("我是子类成员方法");
    }

    public void methodC(){
        methodA();//访问继承自父类成员方法
        methodB();//访问子类自己的成员方法
        //methodD(); 编译报错,在继承体系中没有methodD方法
    }
}

第二种情况:子类和父类中存在同名方法


public class Base {
    public void methodA(){
        System.out.println("我是父类成员方法methodA");
    }
    public void methodB(){
        System.out.println("我是父类成员方法methodB");
    }
}
public class Derived extends Base {
    public void methodA(int a){
        System.out.println("我是子类成员方法methodA");
    }

    public void methodB(){
        System.out.println("我是子类成员方法methodB");
    }

    public void methodC(){
        methodA(1);//带参的methodA方法,访问的是子类的方法
        methodA();//无参的methodA方法,访问的是父类的方法
        methodB();//直接访问methodB,访问到的是子类的方法
    }
}

注意事项:
1、通过子类对象或方法访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到则访问,否则编译报错。
2、通过子类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同,根据调用方法时传递的参数选择合适的方法访问,如果没有则报错;如果父类和子类同名方法的原型一致,则只能访问到子类的,父类的无法通过派生类对象直接访问到。

咦????那么问题来了,如果想要访问与子类方法同名且原型一致的父类方法时该怎么访问呢?——super关键字

4、super关键字

当子类和父类中存在同名且原型一致的方法时,我们想要调用父类的该方法时发现不能直接访问,而在Java中提供了super关键字,该关键字的主要作用就是:在子类方法中访问父类成员。


public class Base {
    int a;
    int b;

    public void methodA(){
        System.out.println("我是父类成员方法methodA");
    }
    public void methodB(){
        System.out.println("我是父类成员方法methodB");
    }
}
public class Derived extends Base {
    int a;//与父类同名成员
    String b;//与父类同名成员的类型不同

    // 与父类中methodA()构成重载
    public void methodA(int a){
        System.out.println("我是子类成员方法methodA");
    }
    //重写父类中的methodB方法
    public void methodB(){
        System.out.println("我是子类成员方法methodB");
    }

    public void methodC(){
        a=100;
        super.a=110;
        b="abc";
        super.b=100;

        methodA(1);//带参的methodA方法,访问的是子类的方法
        methodA();//无参的methodA方法,访问的是父类的方法
        methodB();//直接访问methodB,访问到的是子类的方法
        super.methodB();//通过super关键字调用的是父类的methodB
    }
}

注意事项:

1、只能在非静态方法中使用。

在这里插入图片描述

2、用于在子类方法中,访问父类的成员变量和方法。

5、子类构造方法

子类对象构造时,需要先调用基类构造方法,然后执行子类的构造方法。


public class Base {
   public Base(){
       System.out.println("我是父类构造方法");
   }
}
public class Derived extends Base {
    public Derived(){
        // super();
        // 注意子类构造方法中默认会调用基类的无参构造方法:super()
        //当用户没有写时编译器自动添加
        //且super()必须是第一条语句,且只能出现一次
        System.out.println("我是子类构造方法");
    }

    public static void main(String[] args) {
        Derived a=new Derived();
    }
}

说明:在子类构造方法中,并没有写任何关于基类构造的代码,但是在构造子类对象时,先执行基类的构造方法,然后执行子类的构造方法,因为:子类对象是一个父类对象,在构造子类对象时,先要将从父类继承下来的成员初始化完整,然后再初始化子类自己新增加的成员。
从对象模型的角度来看:

在这里插入图片描述

注意事项:
1、若父类显式定义无参或者默认的构造方法,编译器会给子类生成一个默认的构造方法,且在子类构造方法第一行默认有隐含的super()调用,即调用基类构造方法。
2、如果父类构造方法是带有参数的,此时编译器不会再给子类生成默认的构造方法,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败。
具体看如下代码:


public class Base {
    int a;
    int b;
   public Base(int a){ //父类中带参数的构造方法
       this.a=a;
   }
}
public class Derived extends Base {
    public Derived(int a,int b){ //此时需要在子类中自定义构造方法
        super(a);//选择合适的父类构造方法调用
        this.b=b;
    }

    public static void main(String[] args) {
        Derived a=new Derived(10,20);
        System.out.println(a.a);
        System.out.println(a.b);
    }
}

3、在子类构造方法中,super(…)调用父类构造时,必须是子类构造函数中第一条语句。
4、super(…)只能在子类构造方法中出现一次,并且不能和this同时出现。

6、super和this

相同点:
1、都是Java中的关键字
2、只能在类的非静态方法中使用,用来访问非静态成员方法和字段
3、在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在,如下图所示:

在这里插入图片描述

不同点:
先给一段代码


public class Base {
    int a;
    int b;
}
public class Derived extends Base {
    int c;
    int d;
    public void method(){
        super.a=10;
        super.b=20;

        this.c=30;
        this.d=40;
    }
    public static void main(String[] args) {
        Derived d=new Derived();
        d.method();
    }
}

1、 this是当前对象的引用,当前对象即调用实例方法的对象,super相当于是父类对象的引用。针对上述代码,如下图所示:

在这里插入图片描述

2、在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性。上图也可以进行说明。
3、this是非静态成员方法的一个隐藏参数,super不是隐藏的参数。还是针对上述代码,从字节码的角度来看,打开method方法中的局部变量表,发现只有this,而没有super。

在这里插入图片描述

4、成员方法中直接访问本类成员时,编译之后会将this还原,即本类非静态成员都是通过this来访问的;在子类中如果通过super访问父类成员,编译之后在字节码层面super实际是不存在的。

在这里插入图片描述

5、在构造方法中:this(…)用于调用本类构造方法,super(…)用于调用父类构造方法,两种调用不能同时在构造方法中出现。
6、 构造方法中一定会存在super(…)的调用,用户没有写编译器也会增加,但是this(…)用户不写则没有。

7、代码块执行顺序

第一种:在没有继承关系时的执行顺序


public class Person {
    int age;
    String name;

    public Person(int age,String name){
        this.age=age;
        this.name=name;
        System.out.println("执行构造方法");
    }
    {
        System.out.println("执行实例代码块");
    }

    static {
        System.out.println("执行静态代码块");
    }

    public static void main(String[] args) {
        Person a=new Person(20,"luka");
        System.out.println("-----------------------");
        Person b=new Person(21,"stepth");
    }
}

说明:
1、静态代码块先执行,并且只执行一次,在类加载阶段执行
2、 当有对象创建时,才会执行实例代码块,实例代码块执行完成后,最后构造方法执行
第二种:在存在继承关系时的执行顺序


public class Person {
    int age;
    String name;

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
        System.out.println("Person:执行构造方法");
    }

    {
        System.out.println("Person:执行实例代码块");
    }

    static {
        System.out.println("Person:执行静态代码块");
    }
}
public class Student extends Person{
    public Student(int age,String name){
        super(age,name);
        System.out.println("Student:执行构造方法");
    }
    {
        System.out.println("Student:执行实例代码块");
    }
    static{
        System.out.println("Student:执行静态代码块");
    }

    public static void main(String[] args) {
        Student a=new Student(20,"luka");
        System.out.println("------------------------");
        Student b=new Student(21,"stepth");
    }
}

说明:
1、父类静态代码块优先于子类静态代码块执行,静态代码块相较于其他是最早执行。
2、父类实例代码块和父类构造方法紧接着执行。
3、子类的实例代码块和子类构造方法紧接着再执行。
4、第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行(静态代码块只执行一次)。

8、父类成员在子类中的可见性

在这里插入图片描述

父类中不同访问权限的成员,在子类中的可见性又是什么样子的?


// extend01包中
public class B {
private int a;
protected int b;
public int c;
int d;
}
// extend01包中
// 同一个包中的子类
public class D extends B{
public void method(){
// super.a = 10; // 编译报错,父类private成员在相同包子类中不可见
super.b = 20; // 父类中protected成员在相同包子类中可以直接访问
super.c = 30; // 父类中public成员在相同包子类中可以直接访问
super.d = 40; // 父类中默认访问权限修饰的成员在相同包子类中可以直接访问
}
}
// extend02包中
// 不同包中的子类
public class C extends B {
public void method(){
// super.a = 10; // 编译报错,父类中private成员在不同包子类中不可见
super.b = 20; // 父类中protected修饰的成员在不同包子类中可以直接访问
super.c = 30; // 父类中public修饰的成员在不同包子类中可以直接访问
//super.d = 40; // 父类中默认访问权限修饰的成员在不同包子类中不能直接访问
}
}
// extend02包中
// 不同包中的类
public class TestC {
public static void main(String[] args) {
C c = new C();
c.method();
// System.out.println(c.a); // 编译报错,父类中private成员在不同包其他类中不可见
// System.out.println(c.b); // 父类中protected成员在不同包其他类中不能直接访问
System.out.println(c.c); // 父类中public成员在不同包其他类中可以直接访问
// System.out.println(c.d); // 父类中默认访问权限修饰的成员在不同包其他类中不能直接访问
}
}

**注意:**父类中private成员变量随时在子类中不能直接访问,但是也继承到子类中了。

9、继承方式

Java中支持以下几种继承方式:

单继承:

在这里插入图片描述

多层继承:

在这里插入图片描述

不同类继承同一个类

在这里插入图片描述

不支持多继承

在这里插入图片描述

10、final关键字

final关键可以用来修饰变量、成员方法以及类。

1、修饰变量或字段,表示常量(即不能修改)。


final int a = 10;
a = 20; // 编译出错

2、修饰类:表示此类不能被继承。


final public class Animal {
...
}
public class Bird extends Animal {
...
}
// 编译出错

平时使用的String字符串类,打开其源码可以看到它是被final修饰的,不可以被继承。

在这里插入图片描述

3.、修饰方法:表示该方法不能被重写。

11、组合

组合也是一种表达类之间关系的方式, 也是能够达到代码重用的效果。组合并没有涉及到特殊的语法(诸如 extends 这样的关键字), 仅仅是将一个类的实例作为另外一个类的字段。
这是继承和组合的区别。

在这里插入图片描述


//车闸类
class Brake{

}
//车把手类
class Handle{

}
//轮胎类
class Tire{

}

public class Bicycle {
    private Brake brake;    //可以复用车闸中的属性和方法
    private Handle handle;  //可以复用车把手中的属性和方法
    private Tire tire;      //可以复用轮胎中的属性和方法
}

作者:luka.lh
over!!!

到此这篇关于Java中的重要核心知识点之继承详解的文章就介绍到这了,更多相关Java 继承内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java中的重要核心知识点之继承详解

本文链接: https://lsjlt.com/news/154931.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java中的重要核心知识点之继承详解
    目录一、继承1、概念2、语法3、父类成员的访问(1)子类中访问父类成员变量(2)子类中访问父类成员方法4、super关键字5、子类构造方法6、super和this7、代码块执行顺序8...
    99+
    2024-04-02
  • Java继承的知识点有哪些
    今天小编给大家分享一下Java继承的知识点有哪些的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。继承继承的介绍继承是java面...
    99+
    2023-06-29
  • Java中的ClassLoader核心知识点有哪些
    这篇文章主要介绍“Java中的ClassLoader核心知识点有哪些”,在日常操作中,相信很多人在Java中的ClassLoader核心知识点有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中的C...
    99+
    2023-06-16
  • JavaScript中class继承的知识点整理
    本篇内容主要讲解“JavaScript中class继承的知识点整理”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript中class继承的知识点整理...
    99+
    2024-04-02
  • Java面试重点中的重点之Elasticsearch核心原理
    目录Elasticsearch简介Elasticsearch是什么?它能干什么?从核心概念开始Lucence核心数据结构DocumentIndex倒排索引FST集群相关概念节点分片总...
    99+
    2024-04-02
  • 一文深入了解Python中的继承知识点
    目录1 类继承1.1 继承的简单例子2 继承的类型2.1 单继承2.2 多继承2.3 多级继承2.4 分层继承2.5 Python中的混合继承3 总结1 类继承 Python 是面向...
    99+
    2024-04-02
  • java多线程的核心知识点是什么
    这篇文章主要介绍“java多线程的核心知识点是什么”,在日常操作中,相信很多人在java多线程的核心知识点是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java多线程的核心知识点是什么”的疑惑有所帮助!...
    99+
    2023-06-20
  • java的重要知识点有哪些
    本篇内容介绍了“java的重要知识点有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Spring Cloud Config配置管理工具包...
    99+
    2023-06-04
  • JS高级程序设计之class继承重点详解
    目录引言写法constructor特性继承题外话引言 前文已提过:在 class 出现之前,JavaScript 实现继承是件麻烦事,构造函数继承有加上原型上的函数不能复用的问题;原...
    99+
    2024-04-02
  • 深入了解Springboot核心知识点之数据访问配置
    目录自定义数据源配置多数据源配置使用SpringDataRepositories将@Entity定义与Spring配置分开配置JPA属性配置Hibernate命名策略配置Hibern...
    99+
    2024-04-02
  • Java超详细分析继承与重写的特点
    概念:继承是面向对象语法三大特征之一,继承可以降低代码的沉余度,提高编程的效率。通过继承子类可以随意调用父类中的某些属性与方法,一个子类只能继承一个父类,一个父类可以被多个子类继承。...
    99+
    2024-04-02
  • Axios中值得学习的核心知识点有哪些
    本篇内容介绍了“Axios中值得学习的核心知识点有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、A...
    99+
    2024-04-02
  • Java 面向对象之继承篇详解原理与特点
    目录一、前言二、继承什么是继承呢?继承的好处与弊端继承的使用场景?继承的格式:继承的特点:重写的概念:super关键字super和this的比较一、前言 前面我也们讲述了相关封装的,...
    99+
    2024-04-02
  • Java 知识难点之异常的认知与使用详解
    目录前言一、 异常的背景初识异常数组下标越界访问 null 对象异常分为2种:异常体系:防御式编程:异常的好处LBYL 风格的代码(不使用异常)EAFP 风格的代码(使用异常)二、异...
    99+
    2024-04-02
  • 掌握HTML全局属性的核心要点:5个需要记住的关键知识点
    掌握HTML全局属性的核心要点:5个需要记住的关键知识点 HTML是构建网页的基础语言,全局属性是HTML中可以应用于任何元素的属性。理解和掌握这些全局属性对于编写高效、灵活的网页至关...
    99+
    2024-02-23
    全局属性 核心要点 关键知识点 html元素
  • Java面向对象之继承的概念详解
    目录1. 继承1.1 继承的实现1.2 继承的好处和弊端1.3. Java中继承的特点2. 继承中的成员访问特点2.1 继承中变量的访问特点2.2 super2.3 方法重写2.4 ...
    99+
    2023-05-18
    Java 继承 Java 面向对象
  • 详解Java面向对象中的继承
    继承的概念 继承是面向对象编程中的一个概念,它允许一个类(称为子类或派生类)继承另一个类(称为父类或基类)的属性和方法。子类在继承父类的同时也可以添加自己的属性和方法,从而实现代码的...
    99+
    2023-05-19
    Java 面向对象 Java 继承
  • Java SpringBoot的相关知识点详解
    目录1. IOC和DI2. Spring容器加载Bean/创建对象的时机3. @Autowired注解4. @Configuration配置类5. @Conditional条件注解6...
    99+
    2024-04-02
  • Java集合HashMap的知识点详解
    这篇文章主要讲解了“Java集合HashMap的知识点详解”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java集合HashMap的知识点详解”吧!一、什么是哈希表在讨论哈希表之前,我们先大...
    99+
    2023-06-02
  • Java ynchronized重量级锁的核心原理详解
    目录1.monitor原理2.snychronized同步代码块原理3.synchronized同步方法原理4.重量级锁的开销总结在JVM中,每个对象都关联一个监视器,这里的对象包含...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作