Java面向对象三大特征之继承(一)

在之前的文章我们从建立一个类开始,讲述了创建对象的有关知识,(点此进入了解《Java——从建立一个类开始》)
以及关于Java面向对象第一个特征封装(点此了解 《封装》 )
在这篇文章中,我们讲述关于继承的相关知识子类与父类的种种联系以及子类的微观实现
(关于子类构造方法以及super关键字的相关知识将会在下一文讲述)


继承

继承的概述

继承的概念

子类继承父类的特征和行为,使得子类具有父类相同的属性。
代码格式如下,

class 父类 {
}class 子类 extends 父类 {
}

为什么要继承

在不同类中会有共同的属性或者方法,我们可以将这些共同的属性和方法放在同一个父类,然后再派生出其他子类来共享

优点

避免重复,易于维护,易于理解。

缺点:

耦合性,即父类发生改变,子类也会随即发生改变。

  • 继承类型:单继承、多重继承 和 多继承一 ,不支持 一继承多。

继承的微观

子类继承父类,除了构造方法的部分,剩下的都会继承。

但是私有的属性,无法在子类中直接访问,但是可以通过间接的手段来访问(可继承,但无法访问)

继承类型

继承类型

java不支持多继承。
我们写的类是现实事物的抽象,而我们真正在公司中所遇到的项目往往业务比较复杂,也会涉及到一系列复杂的概念,都需要我们用代码表示,所以在实际项目中写的类比较多,类之间的关系也十分复杂 。
但是即使如此,我们并不希望类之间的继承层次太复杂,一般我们不希望超出三层的继承关系,如果继承层数过多,就考虑对代码进行重构了。
如果想从语法上限制继承,就可以使用final关键字

Object类

若java中的某个类没有显式的继承任何类,则默认它继承Objec类
Object类是Java语言提供的根类(老祖宗类),也就是说所有对象都会有Object类型中所有的特征。


访问子类对象

遵循就近原则,有则访问自己的,没有则访问父类的。

访问子类对象的成员变量

  1. 如果访问的成员变量,子类中没有,则访问从父类继承下来的,
    倘若父类也没有,则报错。
  2. 同名:如果访问的成员变量与继承父类中的成员变量同名,则优先访问自己的。
    即遵循就近原则。
    示例代码如下,
class A {static int E = 10;static int I = 8;
}
class B extends A{static int E = 20;
}
public class Main {public static void main(String[] args) {B b = new B();System.out.println(b.E);System.out.println(b.I);}
}//输出20 和 8
这段代码定义了一个A类,其中有两个被static修饰的变量E和I值为10和8,
以及继承A类的B类,B类中也有类变量E值为20,
后通过公共Main类中的main函数来,来创建一个B类对象,并访问其中的E和I的值。
结果表明E是B类中的变量,符合第二种情况,I是A类中的变量,符合第一情况。

(这里用类名.类变量名访问变量值在《Java——从建立一个类开始》有提及)

访问子类对象的成员方法

  1. 方法名不同时,在子类方法中或者通过子类对象访问方法时,则优先访问自己的,自己没有时再到父类中找,如果父类中也没有则报错
  2. 方法名相同时,父类和子类方法中的参数列表不同,根据调用方法时传递的参数选择合适的方法进行访问,如果没有则报错。
  3. 通过子类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表、返回值都相同,则遵循就近原则访问子类中的方法,不会访问父类中的方法。
class A {void beA() {System.out.println("This is A");}void difference(int number) {System.out.println("A is not number");}void be() {System.out.println("This is A");}
}
class B extends A{void beB() {System.out.println("This is B");}void difference(char letter) {if(letter != 'B') System.out.println("B is not " + letter);}void be() {System.out.println("This is B");}
}
public class Main {public static void main(String[] args) {B b = new B();b.beA();b.beB();b.difference(5);b.difference('C');b.be();}
}
/*输出:This is AThis is BA is not numberB is not CThis is B*/
这段代码定义了一个A类和一个继承A类的B类,
其中子类和父类分别有同名同参数的be()函数,不同名同参数的beA()函数和beB()函数,以及同名不同参数的difference()函数,
分别对应着上文第一二三种情况。
后通过公共Main类中的main函数来,来创建一个B类对象,并依次调用B类对象中的上述函数
输出依次表明上文的结果。

类的初始化

我们将一个类分为静态代码块实例代码块两个部分。

静态代码块和实例代码块都是在Java中用来初始化类或对象的特殊代码块。

静态代码块

静态代码块是使用关键字static定义的代码块,它在类加载的时候执行只会执行一次。
静态代码块通常用于初始化静态变量或执行一些静态操作。

实例代码块

实例代码块是在类中定义的非静态代码块,它在创建对象的时候执行每次创建对象都会执行一次。
实例代码块通常用于初始化实例变量或执行一些实例操作。

class A {static int E;static int I;void beA() {System.out.println("This is A");}void difference(int number) {System.out.println("A is not number");}void be() {System.out.println("This is A");}
}

比如上文的示例代码,其中A类中static修饰的就是静态代码块其余部分就是实例代码块。

没有继承关系下的执行顺序

  1. 静态代码块先执行,且只执行一次,在类的加载阶段执行。
  2. 当有对象创建时,才会执行实例代码块,实例代码块执行完成后,执行构造方法。

有继承关系下父类子类中的执行顺序

  1. 父类静态代码块优先于子类静态代码块执行,而且是最早执行
  2. 父类实例代码块和父类构造方法紧接着执行
  3. 子类实例代码块和子类构造方法紧接着执行
  4. 第二次实例化子类对象时,父类盒子类的静态代码块都将不会执行
    我们可以编写以下的代码来实验一下。
class A {public A() {System.out.println("执行:A的构造函数");}{System.out.println("执行:A的实例代码块");}static {System.out.println("执行:A的静态代码块");}
}
class B extends A {public B() {System.out.println("执行:B的构造函数");}{System.out.println("执行:B的实例代码块");}static {System.out.println("执行:B的静态代码块");}
}
public class Main {public static void main(String[] args) {B b1 = new B();System.out.println("----------------");B b2 = new B();}
}
输出:  执行:A的静态代码块执行:B的静态代码块执行:A的实例代码块执行:A的构造函数执行:B的实例代码块执行:B的构造函数----------------执行:A的实例代码块执行:A的构造函数执行:B的实例代码块执行:B的构造函数

证明结论是对的。


下面是《Java面向对象三大特征》这几篇文章的参考链接:
(1) (2) (3) (4) (5)
(6) (7) (8) (9) (10)
(11) (12) (13) (14)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/433616.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

博途S7-1200PLC轴控指令轴暂停和急停处理(SCL代码)

S7-1200PLC位置控制相关功能块,请查看下面链接文章: https://rxxw-control.blog.csdn.net/article/details/135768878https://rxxw-control.blog.csdn.net/article/details/135768878S7-1200PLC位置控制功能块 https://rxxw-control.blog.csdn.net/article/details/1352993…

Docker 容器内运行 mysqldump 命令来导出 MySQL 数据库,自动化备份

备份容器数据库命令: docker exec 容器名称或ID mysqldump -u用户名 -p密码 数据库名称 > 导出文件.sql请替换以下占位符: 容器名称或ID:您的 MySQL 容器的名称或ID。用户名:您的 MySQL 用户名。密码:您的 MySQL …

懂醒酒才能让葡萄酒得到升华

懂醒酒才能让葡萄酒得到升华 一、什么是醒酒器? 醒酒器,亦作醒酒瓶、醒酒壶,是一种饮用新发酵葡萄酒时所用的器皿,作用是让酒与空气接触,让酒的香气充分挥发,并让酒里的沉淀物隔开。 醒酒器的形状标志一般…

用C语言实现贪吃蛇游戏!!!(破万字)

前言 大家好呀,我是Humble,不知不觉在CSND分享自己学过的C语言知识已经有三个多月了,从开始的C语言常见语法概念说到C语言的数据结构今天用C语言实现贪吃蛇已经有30余篇博客的内容,也希望这些内容可以帮助到各位正在阅读的小伙伴…

[docker] 关于docker的面试题

docker命名空间? docker与虚拟机的区别? 容器虚拟机所有容器共享宿主机的内核每个虚拟机都有独立的操作系统和内核通过namespace实现资源隔离,通过cgroup实现限制资源的最大使用量完全隔离。每个虚拟机都有独立的硬件资源秒级启动速度分钟级…

RabbitMQ 笔记二

1.Spring 整合RabbitMQ 生产者消费者 创建生产者工程添加依赖配置整合编写代码发送消息 创建消费者工程添加依赖配置整合编写消息监听器 2.创建工程RabbitMQ Producers spring-rabbitmq-producers <?xml version"1.0" encoding"UTF-8"?> <pr…

国考省考行测:判断推理,形式逻辑,充分条件,必要条件,用箭头,找真假,找不定

国考省考行测&#xff1a;判断推理 2022找工作是学历、能力和运气的超强结合体! 公务员特招重点就是专业技能&#xff0c;附带行测和申论&#xff0c;而常规国考省考最重要的还是申论和行测&#xff0c;所以大家认真准备吧&#xff0c;我讲一起屡屡申论和行测的重要知识点 遇到…

已经安装了CUDA,但是cmd执行nvcc -V报错:nvcc不是内部或外部命令,也不是可运行的程序或批处理文件

请注意&#xff0c;查看版本的指令是nvcc --version或nvcc -V&#xff0c;注意区分大小写 如果还是不能输出版本信息&#xff0c;那这个原因可能是由于没有在系统环境变量里添加CUDA。 先来看看CUDA是否安装成功&#xff1a; 在CUDA的安装路径下找到bandwidthTest.exe 和 devi…

vue3+echarts绘制某省区县地图

vue3echarts绘制某省区县地图 工作中经常需要画各种各样的图&#xff0c;echarts是使用最多的工具&#xff0c;接近春节&#xff0c;想把之前画的echarts图做一个整合&#xff0c;方便同事和自己随时使用&#xff0c;因此用vue3专门写了个web项目&#xff0c;考虑之后不断完善…

LeetCode 40.组合总和 II

组合总和 II 给定一个候选人编号的集合 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用 一次 。 注意&#xff1a;解集不能包含重复的组合。 方法一、回溯 由于题目要求解集…

C++初阶--queue和stack

stack stack是一种容器适配器&#xff0c;按照后进先出的原则存储数据。通过 #include< stack > 头文件进行提供&#xff1b; stack是作为容器适配器被实现的&#xff0c;容器适配器即是对特定类封装作为其底层的容器&#xff0c;并提供一组特定的成员函数来访问其元素&…

03 SB实战 -微头条之首页门户模块(跳转某页面自动展示所有信息+根据hid查询文章全文并用乐观锁修改阅读量)

1.1 自动展示所有信息 需求描述: 进入新闻首页portal/findAllType, 自动返回所有栏目名称和id 接口描述 url地址&#xff1a;portal/findAllTypes 请求方式&#xff1a;get 请求参数&#xff1a;无 响应数据&#xff1a; 成功 {"code":"200","mes…