五分钟手撕“三大特性”<继承>(下)

ops/2024/10/18 16:41:58/

目录

一、protected 关键字

二、继承方式

三、final 关键字

四、子类的构造方法

五、this和super 

(一)相同点:

(二)不同点:

六、代码块的执行先后 


一、protected 关键字

在类与对象中提到过,为了实现封装特性,Java中引入了访问限定符,主要限定:类或者类中成员能否在类外或者其他包中被访问。

protected它是一种比较温和的权限,它既不会像private一样私密,也不会像public一样开放,它是介于中间的。在同一个包中可以使用,在不同包也能用(不过是子类)。 

java">// 为了掩饰基类中不同访问权限在子类中的可见性,为了简单类B中就不设置成员方法了
// 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成员变量虽然在子类中不能直接访问,但是也继承到子类中了。

二、继承方式

 但是在现实生活中,我们的继承确是多种多样的:

但是Java只接受以下几种方式:

注意:Java中不支持多继承。 

三、final 关键字

我们并不希望类之间的继承层次太复杂. 一般我们不希望出现超过三层的继承关系。

如果继承层 次太多, 就需要考虑对代码进行重构了. 如果想从语法上进行限制继承, 就可以使用 final 关键字。

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

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

final int a = 10;

a = 20; // 编译出错

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

final public class Animal {

        ...

}

public class Bird extends Animal {

        ...

} // 编译出错

我们平时是用的 String 字符串类, 就是用 final 修饰的, 不能被继承。

3. 修饰方法:表示该方法不能被重写(后序的博客会介绍) 

四、子类的构造方法

父子父子,先有父再有子,即:子类对象构造时,需要先调用父类构造方法,然后执行子类的构造方法。 

java">public class Base {
public Base(){System.out.println("Base()");
}
}
public class Derived extends Base{
public Derived(){
// super(); // 注意子类构造方法中默认会调用基类的无参构造方法:super(),
// 用户没有写时,编译器会自动添加,而且super()必须是子类构造方法中第一条语句,
// 并且只能出现一次System.out.println("Derived()");
}
}
public class Test {
public static void main(String[] args) {Derived d = new Derived();
}
}
结果打印:
Base()
Derived()

注意:

1. 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构造方法。

2. 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的 父类构造方法调用,否则编译失败。

3. 在子类构造方法中,super(...)调用父类构造时,必须是子类构造函数中第一条语句。

4. super(...)只能在子类构造方法中出现一次,并且不能和this同时出现。

五、this和super 

(一)相同点:

1.都是Java的关键字;

2. 只能在类的非静态方法中使用;

3.必须是构造方法中的第一条语句,并且不能同时存在

(二)不同点:

1.this既可以指子类也可以指父类,但是调用时优先子类,super只调用父类;

2.构造方法中一定会存在super(...)的调用,用户没有写编译器也会增加,但是this(...)用户不写则没有

六、代码块的执行先后 

代码块的三大总类:静态代码块实例代码块构造代码块

1.静态代码块:初始化静态变量;

2.实例化代码块:可用于在创建对象之前进行一些初始化操作;

3.构造方法:用于初始化对象的成员变量和执行其他操作。

注意:(构造方法和实例代码块区别就是构造方法需要public和类名,实例化代码块上面都不写)

那它们执行的顺序怎么样呢,代码如下:

java">class Person {public String name;public int age;public Person(String name, int age) {this.name = name;this.age = age;System.out.println("构造方法执行");
}{System.out.println("实例代码块执行");
}static {System.out.println("静态代码块执行");
}
}public class TestDemo {
public static void main(String[] args) {Person person1 = new Person("红红",10);System.out.println("============================");Person person2 = new Person("绿绿",20);
}
}

执行结果如下: 

java">静态代码块执行
实例代码块执行
构造方法执行
============================
实例代码块执行
构造方法执行

1. 静态代码块先执行,并且只执行一次,在类加载阶段执行

2. 当有对象创建时,才会执行实例代码块,实例代码块执行完成后,最后构造方法执行

 那在继承中,它们的顺序呢?代码如下:

java">class Person {public String name;public int age;public Person(String name, int age) {this.name = name;this.age = age;System.out.println("Person:构造方法执行");
}{System.out.println("Person:实例代码块执行");
}static {System.out.println("Person:静态代码块执行");
}
}class Student extends Person{
public Student(String name,int age) {super(name,age);System.out.println("Student:构造方法执行");
}{System.out.println("Student:实例代码块执行");
}static {System.out.println("Student:静态代码块执行");
}
}public class TestDemo4 {
public static void main(String[] args) {Student student1 = new Student("张三",19);System.out.println("===========================");Student student2 = new Student("gaobo",20);
}
public static void main1(String[] args) {Person person1 = new Person("红红",10);System.out.println("============================");Person person2 = new Person("绿绿",20);
}
}

执行结果:

java">Person:静态代码块执行
Student:静态代码块执行
Person:实例代码块执行
Person:构造方法执行
Student:实例代码块执行
Student:构造方法执行
===========================
Person:实例代码块执行
Person:构造方法执行
Student:实例代码块执行
Student:构造方法执行

 通过分析执行结果,得出以下结论:

1、父类静态代码块优先于子类静态代码块执行,且是最早执行

2、父类实例代码块和父类构造方法紧接着执行

3、子类的实例代码块和子类构造方法紧接着再执行

4、第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行

 


http://www.ppmy.cn/ops/6428.html

相关文章

基于双向长短期神经网络bilstm的径流量预测,基于gru神经网络的径流量预测

目录 背影 摘要 LSTM的基本定义 LSTM实现的步骤 BILSTM神经网络 基于双向长短期神经网络bilstm的径流量预测,基于gru神经网络的径流量预测 完整代码:基于双向长短期神经网络bilstm的径流量预测,基于gru神经网络的径流量预测(代码完整,数据齐全)资源-CSDN文库 https://dow…

SpringMVC 常用注解介绍

Spring MVC 常用注解介绍 文章目录 Spring MVC 常用注解介绍准备1. RequestMapping1.1 介绍2.2 注解使用 2. 请求参数2.1 传递单个参数2.2 传递多个参数2.3 传递对象2.4 传递数组 3. RequestParam3.1 注解使用3.2 传入集合 4. RequestBody5. PathVariable6. RequestPart7. Rest…

学习在Debian系统上安装Shadowsocks教程

学习在Debian系统上安装Shadowsocks教程 安装shadowsocks-libev及其所需的依赖启动Shadowsocks服务:如果你想要通过代理本地流量,你可以使用ss-local:启动并设置ss-local:查看状态本地连接 安装shadowsocks-libev及其所需的依赖 …

(vue)el-select选择框加全选/清空/反选

(vue)el-select选择框加全选/清空/反选 <el-form-item label"批次"><el-selectv-model"formInline.processBatch"multiplecollapse-tagsfilterableplaceholder"请选择"style"width: 250px"no-data-text"请先选择企业、日…

特殊统计SQL实例分析:活动答题记录表的多维度统计

特殊统计SQL实例分析&#xff1a;活动答题记录表的多维度统计 引言数据表结构应用场景与SQL查询实例问题一&#xff1a;活动7天&#xff0c;每人每天有3次机会&#xff0c;每次机会答5道题&#xff0c;每5道题一个批次&#xff0c;答对有状态status为Y。现在需要获取活动期间每…

通过v-if渲染的element-ui表单,校验规则不生效的问题

因为form-item绑定验证事件是在mounted中进行的&#xff0c;规则变化后没有进行重新绑定验证事件&#xff0c;v-if渲染组件节点diff后被复用了&#xff0c;所以验证也就自然失效了 例如&#xff1a;通过动态选择类型来控制驾驶人是否显示&#xff0c;并且是必填项 给每一个el…

物联网社区信息化管理系统设计的毕业论文

物联网社区信息化管理系统设计的毕业论文 **摘要&#xff1a;**随着物联网技术的不断发展&#xff0c;社区信息化管理已成为智慧城市建设的重要组成部分。本文旨在设计一个基于物联网的社区信息化管理系统&#xff0c;以提升社区管理效率和服务水平。本文通过深入分析物联网技…

设计模式:访问者模式

文章目录 定义应用场景示例代码反例原则间的权衡与冲突设计模式的局限性总结与建议 定义 访问者模式&#xff08;Visitor Pattern&#xff09;是一种将算法与对象结构分离的设计模式。这种模式中&#xff0c;可以在不修改已有程序结构的前提下&#xff0c;通过添加额外的“访问…