第一章 Java简介


一、概述

1.1 Java简介

Java语言是美国Sun(Stanford University Netword)1995推出的计算机语言。

Java之父:詹姆斯·高斯林(James Gosling)。

image-20220524231710965

2009年Oracle收购Sun公司,Java隶属于甲骨文公司。

二、Java语言跨平台原理

此处的平台指的是操作系统,Java程序能够在任意操作系统上执行。

Java通过**JVM(Java Virtual Machine)**实现跨平台间的操作。JVM是一种抽象化的计算机,通过在实际的计算机上仿真模拟各类计算机功能来实现。

image-20220524232447360

三、JRE与JDK

JRE(Java Runtime Environment)是Java运行时环境,包含JVM和运行时所需要的核心类库。

JDK(Java Development Kit)是Java程序开发工具包,包含JRE和开发人员使用的工具。包括编译工具(javac.exe)和运行工具(java.exe)。

image-20220524232926702

四、Java开发流程

开发一个Java程序,需要以下三个步骤:

  • 编写程序
  • 编译程序
  • 运行程序

我们新建一个HelloWorld.java文件:

1
2
3
4
5
public class HelloWorld{
public static void main(String[] args){
System.out.println("HelloWorld");
}
}

在运行前,我们需要先编译下,在CMD中输入:

1
javac HelloWorld.java

此时我们发现,出现了编译文件HelloWorld.class

再执行运行任务:

1
2
3
4
5
6
java HelloWorld

'''
out:
HelloWorld
'''

此时可能出现以下错误:

1
Hellow.java:1: 错误: 类 HelloWorld 是公共的, 应在名为 HelloWorld.java 的文件中声明

这是由于系统声明的class名称与文件名称不相同所导致的。

Java程序中最基本的组成单位是类,代码的执行是从main方法开始的。


第二章 基础语法


一、注释

1
2
3
4
5
// 单行注释

/* 多行注释 */

/** 文档注释 **/

二、关键字

具有特定含义的单词。关键字全部小写。目前Java中一共有53个关键字(2个保留字)。

2.1 保留关键字:

  • const:常量
  • goto:转到

2.2 访问修饰符

  • public:公用,可跨包
  • protected:受保护的,当前包内可用
  • private:私有的,当前类可用

2.3 OOP关键字

  • class:类,类名需要与文件名相同
  • interface:接口,接口一般提供方法但不实现
  • abstract:抽象,介于类与接口中,可以有也可以没有实现的方法体
  • implemenst:实现,用于类或接口,实现接口
  • extends:继承,用于类继承类
  • new:新建一个类

2.4 包的关键字

  • import:引入包
  • package:定义包

2.5 数据类型

  • byte:字节型,8bit
  • char:字节型,16bit
  • boolean:布尔型
  • short:短整型,16bit
  • int:整型,32bit
  • float:浮点型,32bit
  • long:长整型,64bit
  • double:双精度,64bit
  • void:无返回值
  • null:空值
  • true:真
  • false:假

2.6 条件循环(流程控制)

  • if
  • else
  • while
  • for
  • switch
  • case
  • do
  • break
  • continue
  • return
  • instanceof:实例检测,判断左边对象是否是右边的实例

2.7 修饰方法

  • static:静态
  • super:调用父类的方法
  • this:当前类父类的对象
  • native:本地
  • strictfp:严格
  • synchronized:线程,同步
  • transient:短暂
  • volatile:易失

2.8 错误处理

  • catch
  • try
  • finally
  • throw

2.9 其他

  • enum:枚举
  • assert:断言

三、常量

在程序中保持不变的量,称为常量。

在Java中,常量可分为六类:

  • 字符串常量
  • 整数常量
  • 小数常量
  • 字符常量
  • 布尔常量
  • 空常量

四、变量

与常量相对,能够在程序中发生改变的量,称为变量。

Java提供的显示的访问权限修饰符有3种,分别是:私有(private)、保护(protected)和公 共(public)。除此之外,还有一种默认的访问权限:friendly,它并不是Java的关键字,只有当变量前面没有写明任何访问权限修饰符时,就 默认以friendly作为访问权限。

4.1 变量定义

格式:数据类型 变量名=变量值;

面对long变量数据越界,可以在数据后添加一个L

而Java默认小数类型为double,使用float关键字时,为防止不兼容,需要添加F

1
2
long l=100000000L;
float f=13.14F;

五、数据类型

5.1 计算机存储单元

计算机存储设备的最小信息单元叫"位(bit)“,我们又称之为“比特位”,通常用小写的字母“b”表示,而计算机中最小的存储单元叫“字节(byte)”,通常用大写字母"B"表示,字节是由连续的8个位组成。

5.2 数据类型

Java是强类型语言,每一种数据都必须有明确的数据类型,不同的数据类型也分配了不同的内存空间。所以其表示的数据大小是不一致的。

image-20220525123222411

六、标识符

所谓标识符,就是给类、方法、变量等起名字的符号。

规则

  • 由数字、字母、下划线_和美元符$组成
  • 不能以数字开头
  • 不能是关键字
  • 区分大小写

约定

小驼峰:方法、变量

  • 标识符是一个单词时,首字母小写
  • 标识符由多个单词组成,第一个单词字母小写,其他首字母大写

大驼峰:类

  • 标识符是一个单词时,首字母大写
  • 标识符由多个单词组成,首字母全部大写

七、类型转换

7.1 类型转换分类

  • 自动类型转换
  • 强制类型转换

7.2 自动类型转换

把一个表示数据范围小的数值或变量赋值给一个表示数据范围大的变量时,可以实现自动范围转换:

1
double d=10

image-20220525130806831

7.3 强制类型转换

将数据范围大的转换为范围小的

  • 格式:目标数据类型 变量名=(目标数据类型)值或变量
  • 范例:int k=(int)88.88

第三章 运算符


一、算数运算符

1.1 运算符与表达式

  • 运算符:对常量或变量进行操作的符号
  • 表达式:用运算符把常量或变量连接起来符合java语法规范的句子

1.2 算数运算符

  • +
  • -
  • *
  • /
  • %

除法得到的是商,取余得到的是余数。整数相除只能得到整数,要得到小数必须有浮点数的参与。

当字符型与数字类型做加法时,会将字符转为ASCII码进行运算。

  • byte类型、short类型和char类型都将被提升到int类型

字符串型做加操作时,做的是字符拼接。(只要是字符串在前,那就是字符拼接)。例如:

1
2
3
4
5
"a"+1+2
-->"a12"

1+2+"a":
-->"3a"

二、赋值运算符

1
2
3
4
5
6
7
8
9
int i=10;

i+=20;

// 注意,+=操作带有一个强制类型转换
short a=10;
a=a+20// 此时右边是int类型,会报错
a=(short)(a+20); // 不会报错
a+=20; // 不会报错
  • +=
  • -=
  • *=
  • /=
  • %=

三、自增自减运算符

  • ++
  • --
1
2
3
4
5
6
7
8
9
10
11
12
// 单独使用时二者相等
++i;
i++;

// 参与操作时,先参与操作后自加:
int i=10;
int j=i++;
---> j: 10 ; i: 11

// ++放前时,先进行自增:
int j=++i;
---> j: 11 ; i: 11

四、关系运算符

  • ==
  • !=
  • >
  • >=
  • <
  • <=

五、逻辑运算符

逻辑运算符是用来连接关系表达式的运算符。

  • &逻辑与 有false则false
  • |逻辑或 有true则true
  • ^逻辑异或 相同false不同true
  • !逻辑非

短路逻辑运算符

  • &&短路与
  • ||短路或

逻辑与&,无论左边真假,右边都要执行

短路与&&,若左边为假,则右边不执行

逻辑或|,无论真假,都要执行

短路或||,左边为真,则右边不执行


六、三元运算符

格式关系表达式?表达式1:表达式2;

范例a>b?a:b;

先计算关系表达式的值,若为true,表达式1的值就是运算结果;

若为false,表达式2的值就是运算结果。

数据输入(Scanner包):

1
2
3
import java.util.Scanner;
Scanner sc=new Scanner(System.in);
int i=sc.nextInt();

第四章 控制语句


流程控制语句可分为三大类:

  • 顺序结构
  • 分支结构
  • 循环结构

一、顺序结构

作为基本的流程控制结构,顺序结构从上往下依次执行语序。


二、分支结构

2.1 if 结构

格式

1
2
3
if (关系表达式){
语句体;
}

2.2 if…else 结构

格式

1
2
3
4
5
if(关系表达式){
语句体1;
}else{
语句体2;
}

2.3 if…else…if 结构

格式

1
2
3
4
5
6
7
if(关系表达式1){
语句体1;
}else if(关系表达式2){
语句体2;
}else{
语句体n;
}

2.4 Switch结构

格式

1
2
3
4
5
6
7
8
9
10
11
12
switch(表达式){
case1:
语句体1;
break;
case2:
语句体2;
break;
...
default:
语句体n;
break;
}

值得注意的是,当case语句块中没有break时,将继续执行下一次的case

1
2
3
4
5
6
7
switch(a){
case 1:
case 2:
case 3:
System.out.println("HELLO");
break;
}

三、循环结构

循环结构由四个部分构成:

  • 初始化语句
  • 条件判断语句
  • 循环体语句
  • 条件控制语句

3.1 for循环

格式

1
2
3
for (初始化语句;条件判断语句;条件控制语句){
循环体语句;
}

3.2 while循环

格式

1
2
3
4
while(条件判断语句){
循环体语句;
条件控制语句;
}

3.3 do … while 循环

格式

1
2
3
4
5
6
do{
循环体语句;
条件控制语句;
}0
while(条件判断语句)


四、跳转语句

  • continue
  • break

随机数Random

1
2
3
4
5
import java.util.Random;
Random r=new Random();
int num=r.nextInt(10);

// 0-9

IDEA

快速生成语句

  • 快速生成main方法:psvm
  • 快速生成输出语句:sout

内容辅助键

  • Ctrl+Alt+space(内容提示,代码补全)

快捷键

  • 注释

    • 单行:ctrl+/ 再来一次是取消
    • 多行:ctrl+shift+/ 再来一次是取消
  • 格式化

    • ctrl+alt+L

第五章 数组


一、数组定义格式

格式一

  • 数据类型[] 变量名
  • 范例: int[] arr
  • 定义了一个int类型的数组,数组名是arr

格式二:

  • 数据类型 变量名[]
  • 范例:int arr[]
  • 定义了一个int类型的变量,变量名是arr数组

二、数组初始化

Java中的数组必须先初始化,然后才能使用。

所谓初始化,就是为数组中的数组元素分配内存空间,并为每个数组元素赋值。

2.1 动态初始化

在初始化时,指定数组长度,由系统为数组动态分配初始值

例如:

1
int[] arr=new int[3];

2.2 静态初始化

指定数组的初始值,由系统决定长度。

例如:

1
2
3
int[] arr = new int[] {1,2,3,4};
// 或者
int[] arr = {1,2,3,4};

三、数组元素访问

3.1 数组元素访问

格式:数组名[索引]

索引用于访问数组中的数据使用,数组名[索引]等同于变量名,是一种特殊的变量名。

  • 索引从0开始
  • 索引是连续的
  • 索引每次递增1

四、内存分配

4.1 Java中内存分配

Java为了提高效率,给每种类型的数据都分配了空间。数组在初始化时,会为存储空间添加默认值:

  • 整数:0
  • 浮点:0.0
  • 布尔:false
  • 字符:空字符
  • 引用:null

Java中的内存可分为两种,栈内存和堆内存。

栈内存:存储局部变量,定义在方法中的变量,使用完毕,立即消失。

堆内存:存储new出来的内容(实体、对象),数组在初始化时会为期添加默认值。当使用完毕时,会在垃圾回收期空闲时被回收。

image-20220527233055693

4.2 数组内存图

image-20220527233316829

当两个数组指向相同的栈内存时,牵一而动全身。

1
int[] arr1=arr;

五、常见问题

  • 索引越界
  • 空指针异常

六、数组常见操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 遍历数组
int[] arr ={11,12,13};
for(int i=0;i<3;i++){
System.out.println(arr[i]);
}

// 获取数组元素数量
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}

// 获取最值
int max=arr[0];
for(int i=0;i<arr.length;i++){
if(max<arr[i]){
max=arr[i];
}
}

// 翻转
int[] arr={11,22,33,44,55,66};

for(int start=0,end=arr.length-1;start<=end;start++,end--){
int temp=arr[start];
arr[start]=arr[end];
arr[end]=temp;
}

第六章 方法


一、方法概述

方法是将具有独立功能的代码块组织成一个整体,使之能够完成特定任务的代码集。

  • 方法必须先创建才可使用,该过程称为方法定义
  • 方法创建后不是直接运行的,需要手动使用后才执行,该过程称为方法调用

定义方法

1
2
3
4
// 格式
public static void 方法名(){
// 方法体
}

调用方法

1
2
// 格式
方法名();

二、带参数的方法

定义方法与调用

1
2
3
4
5
6
7
8
9
// 格式
public static void 方法名(参数){...}

// 范例
public static void isNumber(int number){...}
public static void getMax(int number1,int number2){...}

isNumber(5);
getMax(6,7);

形参与实参

形参

  • 方法定义中的参数
  • 等同于变量定义格式

实参

  • 方法调用中的参数
  • 等同于使用变量或常量

三、带返回值的方法

定义方法与调用

1
2
3
4
5
6
7
8
9
10
11
// 格式
public static 数据类型 方法名(参数){
return 数据;
}

// 范例
public static int getMax(int n1,int n2){
return n1>n2?n1:n2;
}

a=getMax(5,6);

注意事项

  • 方法不能嵌套定义
  • void表示无返回值,可以省略return,也可以不省略,但后面不能加数据。

四、方法重载

方法重载指同一个类中定义的多个方法之间的关系,满足下列条件的多个方法互相构成重载。

  • 多个方法在同一个类中
  • 多个方法具有相同的方法名
  • 多个方法的参数不同,类型不同或数量不同

重载仅针对参数进行识别,与返回值无关。

示例

设计一个兼容整数类型的比较方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static boolean compare(int a,int b){
return a==b;
}

public static boolean compare(short a,short b){
return a==b;
}

public static boolean compare(byte a,byte b){
return a==b;
}

public static boolean compare(long a,long b){
return a==b;
}

compare(1,2);
compare(short(1),short(2));

五、方法参数传递

基本类型的参数,各个方法是隔开进行的(作用域),所以形参并不会影响实参的值。

image-20220528132130223

对于引用参数,由于传进去了堆内存,所以修改时会在堆内存里修改,形参传递的是堆地址。

image-20220528132800842


Debug:是供程序员使用的程序调试工具,它可用于查看程序的执行流程,也可以用于追踪程序执行过程来调试程序。

Debug调试又称断点调试,断点本质上是一个标记,告诉我们从哪里开始查看。


第七章 类和对象


一、类和对象

对象:客观存在的实体。

:类是对显示生活中一类具有共同属性和行为的事物的抽象。

特点

  • 类是对象的数据类型
  • 类是具有相同属性和行为的一组对象的集合

在Java程序中,类是基本组成单位,它将确定对象会拥有的属性和行为。

类的组成:属性和行为

  • 属性:通过成员变量来体现
  • 行为:通过行为方法来体现

类的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class 类名{
// 成员变量
变量1的数据类型 变量1;
变量2的数据类型 变量2;
...

// 成员方法
方法1;
方法2;
...
}

// 案例
public class Phone{
// 成员变量
String brand;
int price;

// 成员方法
public void call(){
System.out.println("Calling");
}
}

创建并使用对象

1
2
3
4
5
6
7
8
9
10
11
12
// 创建对象
Phone p=new Phone();

// 调用成员变量
p.brand; // 会得到默认值哦

// 调用成员方法
p.call();

// 赋值
p.brand="OPPO";
p.price=3000;

二、对象内存图

image-20220529005813465

在申请对象时,会在栈内存中创建一个地址,作为引用类型,对象地址会指向堆内存中存储的方法和成员变量。

image-20220529010535860 image-20220529010803689

三、成员变量和局部变量

成员变量:在类中方法外的变量

局部变量:在类中方法中的变量

区别 成员变量 局部变量
类中位置不同 类中方法外 方法内或方法声明上
内存中位置不同 堆内存 栈内存
生命周期不同 随对象存在而存在,随对象的消失而消失 随方法的调用而存在
初始化值不同 有默认初始值 无默认初始值,必须先定义

四、封装

4.1 private关键字

  • 是一个权限修饰符
  • 可以修饰成员(成员变量和成员方法)
  • 作用是保护成员不被别的类使用,被private修饰的成员只在本类中才能访问。

针对被private修饰的成员变量,如果需要被别的类使用,则需要提供相应的操作

  • get 变量名()方法,用于获取成员变量的名称,方法用public修饰
  • set 变量名(参数)方法,用于设置成员变量的值,方法用public修饰

例如:

1
2
3
4
5
6
7
8
9
10
11
12
public class Student{
String name;
private age;

public getAge(){
return age;
}

public setAge(int a){
age=a;
}
}

4.2 this关键字

this修饰的变量用于指代成员变量。

  • 方法的形参如果与成员变量同名,不带this修饰的变量指的是形参,而不是成员变量
  • 方法的形参没有与成员变量同名,不带this修饰的变量指的是成员变量

this就是栈内存地址本身哦。

4.3 封装

概述

  • 封装是面向对象三大特征之一
  • 是面向对象编程语言对客观世界的模拟,客观世界成员变量都是隐藏在对象内部的,外界是无法直接操作的

原则

  • 将类的某些信息隐藏在类内部,不允许外部程序直接访问。而是提供对应的接口。

好处

  • 控制了成员变量的操作,提高了代码的安全性
  • 提供了代码的复用性

五、构造方法

构造方法是一种特殊的方法,用于创建对象。

例如:

1
2
3
4
5
6
7
8
9
10
11
public class Student(){

public Student(){
System.out.println("hi");
}

public Student(int a){
System.out.println(a);
}

}

当一个类没有构造方法时,系统会自动给一个无参的构造方法。

标准类

  • 成员变量
    • 使用private修饰
  • 构造方法
    • 提供一个无参构造方法
    • 提供一个或多个带参构造方法
  • 成员方法
    • 提供每个成员变量的set、get方法
    • 提供显示对象信息的show方法
  • 创建对象并为其成员变量赋值的两种方法

第八章 字符串


一、API

API(Application Programming Interface)应用程序编程接口

Java API:在JDK中提供各种功能的Java类,这些类将底层的实现封装起来了,我们不需要关心这些类是如何实现的,只需要学习这些类是如何使用即可。


二、String

String类在java.lang包下,使用时不需要额外导入。

String类代表字符串,Java程序中所有字符串文字都被实现为此类的实例。

特点

  • 字符串不可变
  • 字符串可被共享
  • 字符串底层是字节数组

通过new创建的字符串对象,每次new都会申请一个内存空间,虽然内容相同,但结果不同。

通过""方式创建的字符串对象,只要字典序相同,无论程序中代码出现几次,JVM都只会建立一个String对象,并在字符串池中维护。

字符串的比较

使用==做比较:

  • 基本类型:比较数据值是否相同
  • 引用类型:比较地址值是否相同

字符串是对象,如果用==则是比较地址。为了比较内容,需要一个新的方法来实现:equals()

public boolean equals(Object anObject):将此字符串与指定对象比较

s1.equals(s2)

案例一 登录系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static void main(String[] args) {
String username="UCAS";
String password="Hello";
Scanner sc=new Scanner(System.in);
for(int i=0;i<3;i++) {
System.out.println("请输入用户名");
String name = sc.nextLine();

System.out.println("请输入密码");
String pass = sc.nextLine();

if (name.equals(username) && pass.equals(password)) {
System.out.println("登录成功");
break;
} else {
if(2-i==0){
System.out.println("您的账号已被锁定");
}
System.out.println("登录失败");
}
}
}

案例二 遍历字符串

1
2
3
4
5
6
7
Scanner sc=new Scanner(System.in);
System.out.println("请输入一个字符串");
String line=sc.nextLine();
for(int i=0;i<line.length();i++){
// 通过charAt(idx)获取索引位置的字符
System.out.println(line.charAt(i));
}

三、StringBuilderimage-20220529095929563

若对字符串进行拼接,每次拼接都会构建一个新的String对象,即耗时又浪费内存。

StringBuilder是一个可变的字符串类,可以有效处理上述问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 创建空白可变
StringBuilder sb=new StringBuilder();

// 创建内容可变
StringBuilder sb1=new StringBuilder("hello");

// 添加数据 返回数据本身
sb.append("hello");

// 转换
sb.toString();


// 反转
sb.reverse();

案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int[] arr={1,2,3};
public static String arrayToString(int[] arr){
StringBuilder sb= new StringBuilder();
sb.append("[");
for(int i=0;i<arr.length;i++){
if(i== arr.length-1){
sb.append(arr[i]);
}else{
sb.append(arr[i]).append(",");
}
}
sb.append("]");
String s=sb.toString();
return s;
}

第九章 集合


一、集合基础

集合是一种提供可变存储空间的存储模型类,存储的数据容量可以发生改变。

ArrayList<E>

方法名 说明
public ArrayList() 创建一个新的集合对象
public boolean add(E e) 追加到末尾
public void add(int index,E element) 在指定位置插入元素
public boolean remove(Object o) 删除指定元素
public E remove(int index) 删除指定位置元素,返回被删除元素
public E set(int index,E element) 修改指定元素,返回被修改元素
public E get(int index) 返回指定索引处元素
public int size() 返回集合中的元素个数

案例一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 存储字符串并遍历
public static void main(String[] args){

// 创建集合对象
ArrayList<String> array = new ArrayList<String>();

// 添加字符串对象
array.add("Y");
array.add("ou");
array.add("Bui");

// 遍历集合
for(int i=0;i<array.size();i++){
String s = array.get(i);
System.out.println(s);
}
}

案例二

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// Student类
public class Student {
private String name;
private int age;

public Student(){}

public Student(String name,int age){
this.name=name;
this.age=age;
}

public void setName(String name){
this.name=name;
}
public void setAge(int age){
this.age=age;
}

public String getName(){
return this.name;
}
public int getAge(){
return age;
}
}

// 集合操作
public class Test {
public static void main(String[] arg){
// 创建集合对象
ArrayList<Student> array= new ArrayList<Student>();

// 添加到集合
addStudent(array);
addStudent(array);
addStudent(array);

for(int i=0;i<array.size();i++){
Student s= array.get(i);
System.out.println(s.getName()+","+s.getAge());
}

}

public static void addStudent(ArrayList<Student> array){
Scanner sc=new Scanner(System.in);
System.out.println("Student's name");

String name=sc.nextLine();
System.out.println("Student's age");
int age=sc.nextInt();

// 创建学生对象
Student s = new Student();
s.setName(name);
s.setAge(age);
array.add(s);
}
}

第十章 面向对象


一、继承

1.1 继承概述

1
2
3
4
5
// 格式
public class 子类名 extends 父类名{}

// 范例
public class children extends parents{}

父类也称基类、超类,子类也称派生类。

子类可以有父类的内容和自己独特的内容。

1.2 继承的好处和弊端

好处

  • 提高了代码的复用性
  • 提高了代码的可维护性

弊端

  • 增加了类的耦合性,削弱了子类的独立性

1.3 继承中变量的访问特点

在子类方法中访问一个变量

  • 子类局部范围找
  • 子类成员范围找
  • 父类成员范围找
  • 报错

1.4 Super

this关键字差不多,super关键字用于在子类中调用父类的成员和方法。

关键字 访问成员变量 访问构造方法 访问成员方法
this this.成员 this(…) this.方法
super super.成员 super(…) super.方法

1.5 构造方法

子类中所有的构造方法都会默认访问父类中无参的构造方法。因而,在子类进行初始化之前,一定要先完成父类数据的初始化。

在每个子类构造方法的第一条语句默认都是super()

面对带参的父类,要么用super()显示调用,要么在父类中构建个无参方法。当调用构造方法时,父类将会被置入堆内存。

1.6 方法重写

方法重写概述

  • 子类中出现了和父类中一模一样的方法声明
  • 注意区分重载和重写

例如

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Phone{
public void call(String name){
System.out.println(name);
}
}

public class XiaoMi extends Phone{

@Override
public void call(String name){
System.out,println("H");
}
}

@Override

  • 是一个注解
  • 可以帮我们检查重写方法声明的正确性

注意事项

  • 方法重写不能重写私有方法
  • 重写方法访问权限不能低于父类
  • Java中不能多类继承,但可以多层继承

二、包与修饰符

2.1 包

在Java中,包就是文件夹,用于对类进行分级管理。

格式

package 包名1.包名2package\ 包名1.包名2

在程序中使用package文件夹,会将class放到对应的文件夹下。

导入

1
import1;

2.2 修饰符

权限修饰符

修饰符 同一类 同一包子类无关类 不同包子类 不同包无关类
private 1
默认 1 1
protected 1 1 1
public 1 1 1 1

状态修饰符

final关键字可用于修饰成员方法、成员变量、类。

特点

  • 修饰方法:表示该方法为最终方法,不能被重写
  • 修饰变量:表示该变量时常量,不能被再次赋值
1
2
3
public final void find(){}

public final int pig;

当修饰变量时基本类型,则数据值不能发生改变。

当修饰变量为引用类型,则数据地址值不能改变,但内容可变。

static关键字可以修饰成员方法和变量。

特点

  • 被类所有对象共享
    • 也是判断是否能能够使用静态关键字的条件
  • 可通过类名调用,也可以通过对象名调用

非静态成员方法:

  • 能够访问静态和非静态的变量和方法

静态成员方法:

  • 只能访问静态成员方法和变量

三、 多态

3.1 概述

同一个对象,在不同时刻表现出来的不同形态。

1
2
3
4
// cat类可以生成cat对象或是animal对象
cat c = new cat();
// 父类引用指向子类对象
animal c = new cat();

多态的前提和体现:

  • 有继承/实现关系
  • 有方法重写
  • 有父类引用指向子类对象

3.2 成员访问特点

成员变量:编译和执行看左边,即最终接收到多态对象的类型。

成员方法:编译看左边,执行看右边,即生成对象的类型。

究其原因是成员方法有重写,而成员变量没有。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Animal{
int age=40;
public void eat(){
System.out.println("吃饭");
}
}

public class cat extend Animal{
int age=20;
@Override
public void eat(){
System.out.println("猫");
}
}

Animal a= new cat();
System.out.println(a.age); // 40
a.eat(); // 猫

3.3 多态的好处和弊端

好处:在声明方法时,在父类型里声明,但是在子类型里定义具体实现,参与操作。提高了程序的扩展性

弊端:不能使用子类特有的方法

3.4 多态中的转型

目的:访问子类中的特有方法

操作:强转(向下转型)


四、 抽象类

4.1 概述

一个没有方法体的方法应定义为抽象方法,而含有抽象方法的类必须定义为抽象类。

1
2
3
public abstract class Animal(){
public abstract void eat();
}

抽象类并不能创建一个实例对象。

4.2 抽象类的特点

  • 抽象类和抽象方法必须使用abstract关键词修饰
  • 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
  • 抽象类不能实例化
  • 抽象类的子类要么重写抽象类中的所有抽象方法,要么是抽象类

4.3 抽象类的成员特点

  • 成员变量
    • 可以是变量
    • 也可以是常量
  • 构造方法
    • 有构造方法,但不能实例化,用于子类访问父类数据的初始化
  • 成员方法
    • 可以有抽象方法:限制成员必须完成某些动作
    • 也可以有非抽象方法:提高代码复用性

5、 接口

5.1 概述

接口是一种公共的规范标准,只要符合规范,那么大家都可以通用。Java中的接口更多的体现在对行为的抽象。

5.2 接口的特点

  • 接口用关键字interface修饰

    • public interface 接口名{}
      
      1
      2
      3
      4
      5

      + 类实现接口用`implements`表示

      + ```java
      public class 类名 implements 接口名{}
  • 接口不能实例化

  • 接口的实现类

    • 要么重写接口中的所有抽象方法
    • 要么是抽象类

5.3 接口的成员特点

  • 成员变量
    • 只能是常量
    • 默认修饰符:public static final
  • 构造方法
    • 接口没有构造方法,因为接口主要是对行为进行抽象的,是有具体存在
    • 一个类如果没有父类,默认继承自Object
  • 成员方法
    • 只能是抽象方法

5.4 类和接口的关系

  • 类和类

    • 继承关系,只能单继承但可以多层继承
  • 类和接口

    • 实现关系,可以单实现或是多实现,或是继承实现
  • 接口和接口

    • 继承关系,可以单继承也可以多继承

5.5 抽象类和接口的区别

  • 成员区别
抽象类 接口
变量,常量 常量
有构造方法 无构造方法
有抽象或非抽象方法 只有抽象方法
  • 关系区别
    • 见3.4

案例

  • 定义一个门对象,有openclose两个动作
1
2
3
4
5
6
7
8
9
10
11
// 抽象类
public abstract class Door{
public abstract void open();
public abstract void close();
}

// 接口
public interface Door{
void open();
void close();
}