JAVA学习笔记(第三周)
文章目录
- 继承
- 概述
- 使用场景
- 继承的特点
- 子类继承的内容
- 成员变量访问特点
- 成员方法访问特点
- 方法的重写
- 构造方法
- this super
- 多态
- 多态的表现形式
- 多态的前提
- 成员变量和方法调用
- instanceof
- 优势
- 弊端
- 包
- 包名的规则
- 全类名
- final
- 常量
- 权限修饰符
- 代码块
继承
概述
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
-
Java中提供一个关键字extends,用这个关键字,我们可以让一个类与另一个类建立起继承关系
public class Student extends Person{}
-
Student称为子类(派生类),Person称为父类(基类或超类)
使用场景
当类与类之间存在相同(共性)的内容,并满足子类时父类的一种,就可以考虑使用继承来优化代码。
继承的特点
- Java只支持单继承
- Java不支持多继承,但支持多层继承
- Java中所有的类都直接或者间接继承与Object类
- 子类只能访问父类中非私有的成员

子类继承的内容
非私有 | private | |
---|---|---|
构造方法 | 不能 | 不能 |
成员变量 | 能 | 能(不能直接用) |
成员方法 | 能 | 不能 |
- 子类不能直接访问父类中的私有成员变量,因为私有成员变量只能在所属类的内部访问。子类只能通过父类提供的公有方法来间接访问父类的私有成员变量。
虚方法表:
能被继承的成员方法:
- 非private
- 非static
- 非final
当一个子类继承自父类时,子类会继承父类的虚方法表,并且可以重写(覆盖)父类的虚方法。
每个类都有一个对应的虚方法表,用于存储该类中所有的虚方法。当创建一个对象时,会为该对象分配一块空间来存储虚方法表,并且每个对象都包含一个指向该虚方法表的指针。
成员变量访问特点
就近原则:谁离我近就用谁
在查找成员变量时遵循就近原则,先在当前作用域(局部位置)中查找,然后在本类的成员位置(成员变量)中查找,最后在父类的成员位置中查找。
super
关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
this
关键字:指向自己的引用。
//test01.java
public class test01 {public static void main(String[] args) {Zi zi1 = new Zi();zi1.Print();}
}//Fu.java
public class Fu {String name = "Fu";
}//Zi.java
class Zi extends Fu {String name = "Zi";public void Print() {String name = "Print";System.out.println(name); // Print 从局部位置向上找System.out.println(this.name); // Zi 从本类成员位置向上找System.out.println(super.name); // Fu 从父类成员位置向上找}
}
成员方法访问特点
方法的重写
当父类的方法不能满足子类现在的需求时,需要进行方法的重写
书写格式:
class Parent {// 父类方法public void display() {System.out.println("Parent");}
}class Child extends Parent {// 子类重写父类方法@Overridepublic void display() {System.out.println("Child");}
}
@Override重写注解:
- @Override是放在重写的方法上,检验子类重写语法是否正确
- 没有重写,语法错误会显示红色波浪线
发生重写本质是覆盖虚方法表的方法
注意:
- 重写方法的名称,形参列表必须与父类一致
- 子类重写父类方法时,访问权限子类必须大于等于父类(空着不写<protected<public)
- 子类重写父类方法是,返回值类型必须小于等于父类
- 私有方法不能被重写
- 子类不能重写父类的静态方法
- 只有被添加到虚方法表中的方法才能重写
- 使用
super.
可以在不完全覆盖父类方法的基础上,扩展子类方法的功能
构造方法
-
父类的构造方法不会被子类继承,但可以通过
super
进行调用 -
子类中所有的构造方法都是默认先访问父类的无参构造,再执行自己
原因:
-
子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据
-
子类初始化之前,一定要调用父类构造方法先完成父类数据空间的初始化,
怎么调用父类构造方法
- 子类构造方法的第一行语句默认都是:
super()
不写也存在,且必须在第一行。 - 如果想访问父类有参构造,必须手写
super(###)
进行调用,
this super
this:理解为一个变量,表示当前方法调用者的地址值;
super:代表父类存储空间。
关键字 | 访问成员变量 | 访问成员方法 | 访问构造方法 |
---|---|---|---|
this | this.成员变量 (访问本类成员变量) | this.成员方法(…) (访问本类成员方法) | this(…) 访问本类构造方法 |
super | super.成员变量 (访问父类成员变量) | super.成员方法(…) (访问父类成员方法) | super(…) 访问父类构造方法 |
this(...)
访问本类构造方法:成员变量不全部初始化,但是想给其他没初始化的成员变量一个默认值
public class Example {private int number;private String name;public Example(int number) {this(number, "Default Name"); // 调用另一个构造方法}public Example(int number, String name) {this.number = number;this.name = name;}
}
多态
同类型的对象,表现出的不同形态。
多态的表现形式
父类类型 对象名称 = 子类对象;
多态的前提
- 有继承关系
- 有父类引用指向子类对象
- 有方法重写
Fu f = new Zi();
成员变量和方法调用
-
调用成员变量:
编译看左边,运行也看左边
编译看左边:javac编译代码的时候,会看左边的父类中有没有这个变量,如果有,编译成功,如果没有编译失败。
运行也看左边:java运行代码的时候,实际获取的就是左边父类中成员变量的值 -
调用成员方法:
编译看左边,运行看右边
编译看左边:javac编译代码的时候,会看左边的父类中有没有这个方法,如果有,编译成功,如果没有编译失败
运行看右边:java运行代码的时候,实际上运行的是子类中的方法
public class Animal {String name = "动物";public void eat(){System.out.println("进食");}
}public class Dog extends Animal {String name = "狗";@Overridepublic void eat() {System.out.println("吃狗粮");}public void LookHome(){System.out.println("看家");}
}public class Test {public static void main(String[] args) {Animal a = new Animal();Animal b = new Dog();System.out.println(a.name);//动物System.out.println(b.name);//动物a.eat();//进食b.eat();//吃狗粮//b.LookHome(); //编译错误//变回子类型Dog c = (Dog)b;c.LookHome();//看家}
}
对于 a
,它是 Animal
类的实例,所以输出的是 Animal
类中定义的 name
变量的值,即 “动物”;而对于 b
,它虽然是 Dog
类的实例,但由于引用类型是 Animal
,所以输出的也是 Animal
类中定义的 name
变量的值,同样是 “动物”。
由于多态的原因,虽然 b
的真实类型是 Dog
,但是在编译时只考虑了 Animal
类型,所以调用的是 Dog
类中重写覆盖的 eat()
方法,输出 “吃狗粮”。
Animal
类型的引用不能直接调用 Dog
类中特有的方法
instanceof
运算符,用于检查对象是否是某个类的实例或者实现了某个接口。
object instanceof Class
确保在 b 是 Dog 类型的对象时才调用 LookHome() 方法。
if (b instanceof Dog) {Dog c = (Dog)b;c.LookHome();
} else {System.out.println("b 不是 Dog 类型的对象");
}//jdk14
if (b instanceof Dog c) {c.LookHome();
} else if (b instanceof Cat d) {d.CatchMouse();
} else {System.out.println("没有b对应的类型");
}
优势
在方法中,使用父类型作为参数,可以接受所有的子类对象
通过父类类型引用来访问子类对象,这使得代码更加灵活,能够处理更多类型的对象。
当需要添加新的子类时,只需编写新的子类并确保它符合父类的接口,而无需修改现有的代码。
弊端
不能使用子类的特有功能
类型转换:自动类型转换,强制类型转换
// 自动类型转换
Person p = new Student();
// 强制类型转换
Student s = (Student)p;
强制类型转换:
- 可以转换为真正的子类类型,从而调用子类独有功能
- 转换类型与真正对象类型不一致会报错
- 转换的时候用
instanceof
关键字判断
包
包就是文件夹,用来管理不同功能的java类
包名的规则
- 使用小写字母:包名应该全部使用小写字母,不建议使用大写字母。尽管Java编译器对大小写不敏感,但是惯例上包名使用小写字母是推荐的做法。
- 使用点号分隔:包名中的各个部分之间使用点号(
.
)进行分隔。点号用于表示包之间的层次关系,类似于文件系统中的目录结构。例如:com.example
。- 使用有意义的名称:包名应该具有描述性,能够清晰地表达其所包含的类和功能。通常使用公司域名的倒序作为根包名,然后根据项目或模块再进行细分。例如:
com.example.project
。- 避免使用Java保留字:包名不能使用Java语言中的保留字(例如
class
、int
等)。- 不要使用特殊字符:包名中不应该包含空格、连字符、下划线等特殊字符,只能使用字母、数字和点号。
- 不能以数字开头:包名不能以数字开头。
全类名
全类名(fully qualified class name)是指包括包名在内的类的完整名称。在Java中,每个类都有一个唯一的全类名,用于标识该类的位置和名称。
全类名的格式通常为:
包名.类名
全类名的主要作用是在Java程序中准确地定位和引用类。
有一个位于com.example
包中的MyClass
类,其全类名就是com.example.MyClass
。
在使用类时,如果没有使用import语句导入类,可以通过全类名来引用类,以避免命名冲突。例如:
// 通过全类名`com.example.MyClass`来创建`MyClass`类的实例。
com.example.MyClass myObj = new com.example.MyClass();
使用其他类的规则:
- 使用同一个包中的类时,不需要导包
- 使用java.lang包中的类时,不需要导包
- 其他情况都需要导包
- 如果同时使用两个包中的同名类,需要用全类名
final
- final 修饰变量:
- 对于基本类型的变量,
final
表示该变量的值不能被修改,即为常量。 - 对于引用类型的变量,
final
表示该变量的引用不可变,即不能再指向其他对象,但对象本身的内容是可以修改的。 final
变量通常在声明时初始化,可以在构造函数中初始化,或者在实例初始化块中初始化。如果没有在声明时初始化,那么必须确保在对象的构造完成之前对final
变量进行初始化。
- 对于基本类型的变量,
- final 修饰方法:
final
修饰的方法不能被子类重写(覆盖),确保方法的行为不会被子类改变。- 如果一个类被声明为
final
,其中的所有方法都隐式地成为final
方法,即不能被子类重写。
- final 修饰类:
final
修饰的类不能被继承,即该类是最终类,不能有子类。
常量
-
基本数据类型常量:
-
对于基本数据类型(如整型、浮点型、字符型等),使用
final
关键字声明的变量,其值在声明后无法再次修改,这就构成了常量。 -
例如:
final int MAX_VALUE = 100; final double PI = 3.14159; final char GRADE = 'A';
-
-
引用类型常量:
-
对于引用类型,通过
final
关键字声明的变量,其引用不可变,即不能再指向其他对象,但是对象本身的内容是可以修改的。 -
例如:
public class Example {public static void main(String[] args) {final StringBuilder sb = new StringBuilder("Hello");System.out.println(sb); // Hello// 可以修改StringBuilder对象的内容sb.append(", world!");System.out.println(sb); // Hello, world!// 不能将sb指向其他对象,会编译报错// sb = new StringBuilder("Goodbye");} }
-
权限修饰符
- public(公共的):
public
是最宽松的访问权限修饰符,在任何地方都可以访问到被public
修饰的类、变量、方法和构造函数。- 用于表示对所有类都是可见的,比如一个公共接口或者公共类成员。
- protected(受保护的):
protected
修饰的成员对同一包内的类以及子类是可见的,即只有同一包内的类和该类的子类可以访问被protected
修饰的成员。- 用于表示对子类和同一包内的类可见。
- default(只能本包使用):
- 如果没有使用任何权限修饰符,默认情况下成员具有默认的访问权限,即同一包内的类可以访问,但对于不同包内的类则不可访问。
- 在Java中,没有关键字修饰的成员就是默认访问权限。
- private(只能自己用):
private
是最严格的访问权限修饰符,只有声明它的类内部才可以访问被private
修饰的成员,其他类无法访问。- 用于表示对当前类可见,其他类无法访问。
修饰符 | 同一个类中 | 同一个包中其他类 | 不同包下的子类 | 不同包下的无关类 |
---|---|---|---|---|
private | √ | |||
default (默认) | √ | √ | ||
protected | √ | √ | v | |
public | √ | √ | √ | v |
权限修饰符的使用规则:
实际开发中,一般只用private
和public
- 成员变量私有
- 方法公开
特例:如果方法中的代码是抽取其他方法中共性代码,这个方法一般也私有。
代码块
-
局部代码块:
-
局部代码块是指被
{}
包围的一组语句,通常用于限定变量的作用范围,以及在一段代码中创建局部作用域。 -
局部代码块可以出现在方法内部、循环内部、条件语句内部等任意位置。
-
示例:
public class Example {public static void main(String[] args) {int x = 10;{int y = 20;System.out.println(x + y); // 输出:30}// System.out.println(y); // 编译错误,y超出了其作用范围} }
-
-
构造代码块:
- 写在成员位置的代码块
- 构造代码块在创建对象时会优先于构造函数执行。
- 作用:初始化实例变量,提取重复代码
用于在创建对象时执行初始化操作,与构造函数类似,但没有方法名,并且不带任何修饰符。
主要作用是对对象进行初始化,通常用于对实例变量进行初始化,或者执行一些需要在对象创建时就完成的操作。
public class Example {int x; // 实例变量// 构造代码块{System.out.println("Constructor block: Initializing instance variable");x = 10; // 对实例变量进行初始化}// 构造函数public Example() {System.out.println("Constructor: Object created");}public static void main(String[] args) {Example obj = new Example(); // 创建对象System.out.println("x = " + obj.x); // 输出实例变量的值} }
构造代码块在对象创建时首先被执行,用于初始化实例变量
x
。然后,构造函数被执行,输出对象创建的消息。最后,在main
方法中创建对象并输出实例变量x
的值。 -
静态代码块:
使用场景:用于在类加载时执行一些初始化操作。
格式:
static { }
特点和作用:
- 在类加载时执行:静态代码块在类加载时执行,且只执行一次。这意味着它在类的生命周期中只会执行一次,无论类被实例化多少次,静态代码块只会执行一次。
- 用于对静态成员进行初始化:静态代码块通常用于对静态成员进行初始化操作,例如初始化静态变量,加载静态资源等。因为它在类加载时执行,可以保证静态成员在使用前已经完成了初始化。
public class Example {static {System.out.println("Static block: Class is being loaded");// 执行一些静态成员的初始化操作// 例如初始化静态变量}public static void main(String[] args) {System.out.println("Main method: Class is loaded and ready");} }
静态代码块在类加载时优先于
main
方法执行,用于对静态成员进行初始化。
如有错误烦请指正。
感谢您的阅读
相关文章:

JAVA学习笔记(第三周)
文章目录 继承概述使用场景继承的特点子类继承的内容成员变量访问特点成员方法访问特点方法的重写构造方法this super 多态多态的表现形式多态的前提成员变量和方法调用instanceof优势弊端 包包名的规则全类名final常量 权限修饰符代码块 继承 概述 继承就是子类继承父类的特征…...

linux 内核驱动 -- reboot -f 导致内核死机 而 reboot则不会引起问题
问题描述,定于与解决:...

【vue-echarts】 报错问题解决 “Error: Component series.pie not exists. Load it first.“
目录 问题描述解决【解决1】【解决2】 问题描述 使用 vue-echarts 时导入的文件 import VChart from vue-echarts/components/ECharts import echarts/lib/chart/line import echarts/lib/chart/bar import echarts/lib/chart/pie import echarts/lib/component/legend impor…...

MySQL慢查询SQL优化
一、慢查询日志 描述:通过慢查询日志等定位那些执行效率较低的SQL语句 查看 # 慢查询是否开启 show variables like slow_query_log%; # 慢查询超时时间 show variables like long_query_time%;执行SQL 开启慢查询日志 set global slow_query_log ON;设置慢查…...

【嵌入式DIY实例】-DDS信号生成器
DDS信号生成器 文章目录 DDS信号生成器1、AD9805介绍2、硬件准备与接线3、代码实现在本文中,将详细介绍如何使用AD9850来搭建一个简易的DDS(Direct Digital signal )信号生成器。 1、AD9805介绍 AD9850是一款高度集成的器件,采用先进的DDS技术,内置一个高速、高性能数模转…...

java设计模式四 桥接模式
桥接模式关注于将抽象部分与实现部分分离,使它们可以独立变化。它通过在抽象和实现之间建立一个桥梁来实现这一目的。这种设计模式属于结构型模式。 假设我们要设计一个图形编辑器,其中图形(如圆形、正方形)可以有不同的颜色填充…...

《Python编程从入门到实践》day24
# 昨日知识点学习 创建外星人从一个到一行 # 主程序snipdef _create_fleet(self):"""创建外星人群"""# 创建一个外星人并计算一行可容纳多少个外星人# 外星人的间距为外星人的宽度alien Alien(self)alien_width alien.rect.widthavailable_sp…...

【hackmyvm】 Animetronic靶机
靶机测试 arp-scanporturl枚举exiftool套中套passwordsudo 提权 arp-scan arp-scan 检测局域网中活动的主机 192.168.9.203 靶机IP地址port 通过nmap扫描,获取目标主机的端口信息 ┌──(root㉿kali)-[/usr/share/seclists] └─# nmap -sT -sV -O 192.16…...

[附源码]石器时代_恐龙宝贝内购版_三网H5手游_带GM工具
石器时代之恐龙宝贝内购版_三网H5经典怀旧Q萌全网通手游_Linux服务端源码_视频架设教程_GM多功能授权后台_CDK授权后台 本教程仅限学习使用,禁止商用,一切后果与本人无关,此声明具有法律效应!!!࿰…...

RS2255XN功能和参数介绍及PDF资料
RS2255XN是一款由Runic(润石)公司生产的模拟开关。以下是关于RS2255XN的一些技术参数和特点: 封装:MSOP-10 电源电压范围:2.5V至5.5V 工作温度范围:-40C至125C 类型:模拟开关 品牌:R…...

设计模式——外观模式(Facade)
外观模式(Facade Pattern) 是一种结构型设计模式,它为一个子系统中的一组接口提供一个统一的高层接口,使得子系统更加容易使用。这种类型的设计模式属于结构型模式,它向客户端提供了一个接口,隐藏了子系统的…...

【linux软件基础知识】Linux 中的普通进程的调度机制
活动集Active processes和过期集Expired processes 为了实现静态优先级较低的进程没有完全锁定并有机会运行,Linux 调度程序维护两个不相交的可运行进程集:活动集和过期集。 此机制是完全公平调度程序 (CFS) 算法的一部分。 以下是这两组的工作原理: 活动集Active proces…...

keil5软件安装教程(MDKv5.39)
keil5软件安装分为三部分: 目录 1.安装mdk 2.激活mdk 3.安装STM32芯片包 1.安装mdk 安装包链接:链接:https://pan.baidu.com/s/1PZoGhzI5Y19ROv7xe9QJKA?pwdgt3s 提取码:gt3s 1、下载keil5的压缩包并解压,鼠…...

改变视觉创造力:图像合成中基于样式的生成架构的影响和创新
原文地址:revolutionizing-visual-creativity-the-impact-and-innovations-of-style-based-generative 2024 年 4 月 30 日 介绍 基于风格的生成架构已经开辟了一个利基市场,它将机器学习的技术严谨性与类人创造力的微妙表现力融为一体。这一发展的核…...

【LAMMPS学习】八、基础知识(5.8)LAMMPS 中热化 Drude 振荡器教程
8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语,以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…...

基于SpringBoot的全国风景区WebGIS按省展示实践
目录 前言 一、全国风景区信息介绍 1、全国范围内数据分布 2、全国风景区分布 3、PostGIS空间关联查询 二、后台查询的设计与实现 1、Model和Mapper层 2、业务层和控制层设计 三、WebGIS可视化 1、省份范围可视化 2、省级风景区可视化展示 3、成果展示 总结 前…...

深入理解网络原理3----TCP核心特性介绍(上)【面试高频考点】
文章目录 前言TCP协议段格式一、确认应答【保证可靠性传输的机制】二、超时重传【保证可靠性传输的机制】三、连接管理机制【保证可靠性传输的机制】3.1建立连接(TCP三次握手)---经典面试题3.2断开连接(四次挥手)3.3TCP状态转换 四…...

Java并发编程之锁的艺术:面试与实战指南(三)
Java并发编程之锁的艺术:面试与实战指南(三) 文章目录 Java并发编程之锁的艺术:面试与实战指南(三)前言十七、Java中线程和进程的区别是什么?十八、什么是Java内存模型(JMMÿ…...

Final Draft 12 for Mac:高效专业剧本创作软件
对于剧本创作者来说,一款高效、专业的写作工具是不可或缺的。Final Draft 12 for Mac就是这样一款完美的选择。这款专为Mac用户设计的剧本创作软件,凭借其卓越的性能和丰富的功能,让您的剧本创作更加得心应手。 Final Draft 12支持多种剧本格…...

php字符串变量和常见的字符串函数
在 PHP 中,字符串变量用于存储文本数据。你可以使用单引号()、双引号(")或定界符(heredoc 或 nowdoc)来定义字符串。下面是一些关于 PHP 字符串变量的重要点和示例: 1. 单引号…...

PPT基础
5种ppt仅可读形式 Ⅰ 开始选项卡 1.【幻灯片】组中:新建幻灯片,从大纲中导入幻灯片;修改幻灯片的版式;节(新增节,重命名节)。 2.【字体】组中:设置字体,字体大小&…...

初识JDBC
1、JDBC是什么? Java DataBase Connectivity(Java语言连接数据库) 2、JDBC的本质是什么? JDBC是SUN公司制定的一套接口(interface) java.sql.*;(这个包下有很多接口) 接口都有调用者和实现者。 面向接口调用、面向接口写实现类,这都属于…...

React 学习-5
React 条件渲染: 与js中的写法一致 注意:在 JavaScript 中,true && expression 总是返回 expression,而 false && expression 总是返回 false。 因此,如果条件是 true,&& 右侧的元素就会被渲…...

深入浅出TCP 与 UDP
🔥 个人主页:空白诗 文章目录 🔥 引言🌐 基础认知概览💻 TCP - 稳健的信使 🛡️🎭 UDP - 敏捷的使者 🏃♂️ 🧑💻 实战演练:代码示例TCP 服务…...

Leetcode—387. 字符串中的第一个唯一字符【简单】
2024每日刷题(127) Leetcode—387. 字符串中的第一个唯一字符 实现代码 class Solution { public:int firstUniqChar(string s) {int count[26] {0};for(char c: s) {count[c - a];}for(int i 0; i < s.length(); i) {if(count[s[i] - a] 1) {re…...

Blazor入门-调用js+例子
参考: Blazor入门笔记(3)-C#与JS交互 - 半野 - 博客园 https://www.cnblogs.com/zxyao/p/12638233.html 本地环境:win10, visual studio 2022 community 其他例子写了再更新! 调用js函数并传递参数 首先要加上injec…...

暴力数据结构之栈与队列(队列详解)
1.队列的定义 队列是一种特殊的线性表,它遵循先进先出(FIFO)的原则。在队列中,只允许在表的一端进行插入操作(队尾),而在另一端进行删除操作(队头)。这种数据结构确保了最…...

仿照JDK源码写一个ArrayList实现
仿照JDK编写一个简化的ArrayList实现是一个很好的学习Java集合框架内部工作原理的方式。以下是一个简化版的ArrayList实现,它包含了基本的添加、获取、删除和大小检查功能。 public class MyArrayList<E> {private static final int DEFAULT_CAPACITY = 10;private Obj…...

[链表专题]力扣21, 234
1. 力扣21 题 : 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1:输入:l1 [1,2,4], l2 [1,3,4] 输出:[1,1,2,3,4,4] 示例 2:输入:l1 [], l2 [] 输出&…...

智慧便民小程序源码系统 求职招聘+房产出租+相亲交友 带完整的安装代码包以及系统搭建教程
在数字化、智能化的今天,我们的生活节奏越来越快,对于各种服务的需求也越发多元化和个性化。为了满足广大市民对于便捷、高效、全面的服务需求,罗峰给大家分享一款智慧便民小程序源码系统,集求职招聘、房产出租、相亲交友三大功能…...