文章目录
day01 【前言、入门程序、常量、变量】
1. Java程序开发三步骤:
编写、编译、运行。
2. 6种类型的常量
常量
在程序运行期间,固定不变的量。
常量的分类
- 字符串常量:凡是用双引号引起来的部分,叫做字符串常量。例如:“abc”、“Hello”、“123”
- 整数常量:直接写上的数字,没有小数点。例如:100、200、0、-250
- 浮点数常量:直接写上的数字,有小数点。例如:2.5、-3.14、0.0
- 字符常量:凡是用单引号引起来的单个字符,就做字符常量。例如:‘A’、‘b’、‘9’、‘中’
- 布尔常量:只有两种取值。true、false。
- 空常量:null。代表没有任何数据。
3. 8种基本数据类型的变量
变量
程序运行期间,内容可以发生改变的量。
格式
创建一个变量并且使用的格式:
数据类型 变量名称; // 创建了一个变量 变量名称 = 数据值; // 赋值,将右边的数据值,赋值交给左边的变量 数据类型 变量名称 = 数据值; // 在创建一个变量的同时,立刻放入指定的数据值
注意事项
- 如果创建多个变量,那么变量之间的名称不可以重复。
- 对于float和long类型来说,字母后缀F和L不要丢掉。
- 如果使用byte或者short类型的变量,那么右侧的数据值不能超过左侧类型的范围。
- 没有进行赋值的变量,不能直接使用;一定要赋值之后,才能使用。
- 变量使用不能超过作用域的范围。【作用域】:从定义变量的一行开始,一直到直接所属的大括号结束为止。
- 可以通过一个语句来创建多个变量,但是一般情况不推荐这么写。
4. 标识符
1. 定义
指在程序中,自己定义的内容。如类的名字、方法的名字和变量的名字等,都是标识符。
2. 命名规则
- 可以包含英文字母26个(区分大小写)、0-9数字、
$和_ - 标识符不能以数字开头
- 不能是关键字
eg. new、1234、car.taxi是非法变量;$Usdollars合规
3. 命名规范(建议)
- 类名:首字母大写,大驼峰
- 方法名:首字母小写,小驼峰
- 变量名:首字母小写,小驼峰
day02 【数据类型转换、运算符、方法入门】
1. 强制转换
转换格式:
数据类型 变量名 = (数据类型)被转数据值;
注意事项
- 强制类型转换一般不推荐使用,因为有可能发生精度损失、数据溢出。
- byte/short/char这三种类型都可以发生数学运算,例如加法“+”.
- byte/short/char这三种类型在运算的时候,都会被首先提升成为int类型,然后再计算。
- boolean类型不能发生数据类型转换
2. ASCII编码表
'0'--->48; 'A'--->65; 'a'--->97;
3. 运算符++
++在前,先加后用;++在后,先用后加
4. 三元运算符
格式:
数据类型 变量名 = 布尔类型表达式?结果1:结果2
位运算为增加部分,在后边看源码时很多都会用到,如hashmap
5. 位运算
与运算&:
相同位的两个数字都为1,结果为1;否则结果为0
按位或|:
相同位的两个数字只要有1,结果为1;否则结果为0
按位异或^:
相同位的两个数字相同结果为0;不同结果为1
按位左移<< 如 <<1为左移一位
按位右移>> 同理
6.除法相关
/整型 时,结果为整型,舍去小数;运算量中有一个为实型,结果为双精度实型
eg. 1/2=0 5/2.5=2.0%取余rem、取模mod 参与变量需要均为整型。取模运算的结果等于两个数相除后的余数
eg. 1%2=1 5%2.0报错
day03【 流程控制语句】
1. 判断语句–if…else if…else
格式:
if (判断条件1) {
执行语句1; } else if (判断条件2) {
执行语句2; } ... }else if (判断条件n) {
执行语句n; } else {
执行语句n+1; }
2. 选择语句switch
格式:
switch(表达式) { case 常量值1: 语句体1; break; case 常量值2: 语句体2; break; ... default: 语句体n+1; break; }
case的穿透性(月份对应的季节)
注意事项
- 多个case后面的数值不可以重复。
- switch后面小括号当中只能是下列数据类型:
基本数据类型:byte/short/char/int
引用数据类型:String字符串、enum枚举 - switch语句格式可以很灵活:前后顺序可以颠倒,而且break语句还可以省略。
“匹配哪一个case就从哪一个位置向下执行,直到遇到了break或者整体结束为止。”
jdk1.7后switch能用哪些类型
3. for循环
格式:
for(初始化表达式①; 布尔表达式②; 步进表达式④){
循环体③ }
4. while 循环
格式:
初始化表达式① while(布尔表达式②){ 循环体③ 步进表达式④ }
5. do…while循环
格式:
初始化表达式① do{ 循环体③ 步进表达式④ }while(布尔表达式②);
6. break 和continue
break 跳出循环;continue跳过本次循环,继续下一个循环
7. 嵌套循环
经典题型: 直角三角形、倒三角型、等腰三角形的*号
day04【 Idea、方法】
1. idea的相关知识
idea的相关知识汇总在idea小工具
2. 定义方法
方法其实就是若干语句的功能集合。
格式(三要素):
修饰符 返回值类型 方法名(参数列表){
//代码省略... return 结果; }
注意事项
3. 方法调用流程图

4. 方法的重载
- 方法重载:指在同一个类中,允许存在一个以上的同名方法,只要它们的参数列表不同即可,与修饰符和返回值类型无关。
- 参数列表:个数不同,数据类型不同,顺序不同。
- 重载方法调用:JVM通过方法的参数列表,调用不同的方法。
day05【数组】
1. 容器
将多个数据存储到一起,每个数据称为该容器的元素。
2. 数组概念
数组就是存储数据长度固定的容器,保证多个数据的数据类型要一致。
3. 数组的定义
数组的特点
- 数组是一种引用数据类型
- 数组当中的多个数据,类型必须统一
- 数组的长度在程序运行期间不可改变
数组的初始化
在内存当中创建一个数组,并且向其中赋予一些默认值。
- 动态初始化:
数组存储的数据类型[] 数组名字 = new 数组存储的数据类型[长度];
- 静态初始化:
数据类型[] 数组名 = new 数据类型[]{
元素1,元素2,元素3...};
静态简写:
数据类型[] 数组名 = {
元素1,元素2,元素3...};
默认值
5. 索引
- 索引: 每一个存储到数组的元素,都会自动的拥有一个编号,从0开始,这个自动编号称为数组索引(index),可以通过数组的索引访问到数组中的元素。
6. java虚拟机的内存划分
| 区域名称 | 作用 |
|---|---|
| 寄存器 | 给CPU使用,和我们开发无关。 |
| 本地方法栈 | JVM在使用操作系统功能的时候使用,和我们开发无关。 |
| 方法区 | 存储可以运行的class文件。 |
| 堆内存 | 存储对象或者数组,new来创建的,都存储在堆内存。 |
| 方法栈 | 方法运行时使用的内存,比如main方法运行,进入方法栈中执行。 |
7. 数组在内存中的存储

8. 遍历数组
public static void main(String[] args) {
int[] arr = {
1, 2, 3, 4, 5 }; for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]); } }
9. 最大值
public static void main(String[] args) {
int[] arr = {
5, 15, 2000, 10000, 100, 4000 }; //定义变量,保存数组中0索引的元素 int max = arr[0]; //遍历数组,取出每个元素 for (int i = 0; i < arr.length; i++) {
//遍历到的元素和变量max比较 //如果数组元素大于max if (arr[i] > max) {
//max记录住大值 max = arr[i]; } } System.out.println("数组最大值是: " + max); }
10. 数组反转
public static void main(String[] args) {
int[] arr = {
1, 2, 3, 4, 5 }; /* 循环中定义变量min=0最小索引 max=arr.length-1最大索引 min++,max-- */ for (int min = 0, max = arr.length - 1; min <= max; min++, max--) {
//利用第三方变量完成数组中的元素交换 int temp = arr[min]; arr[min] = arr[max]; arr[max] = temp; } // 反转后,遍历数组 for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]); } }
11. 数组作为方法参数
public static void main(String[] args) {
int[] arr = {
1, 3, 5, 7, 9 }; //调用方法,传递数组 printArray(arr); } /* 创建方法,方法接收数组类型的参数 进行数组的遍历 */ public static void printArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]); } }
12. 数组作为方法返回值
public class Demo12ArrayReturn {
public static void main(String[] args) {
int[] result = calculate(10,20,30); System.out.println("main方法接收到的返回值数组是:"); System.out.println(result); System.out.println("总和:"+result[0]); System.out.println("平均:"+result[1]); } public static int[] calculate(int a, int b, int c){
int sum = a+b+c; int avg = sum/3; // 两个结果都希望进行返回 /* int[] array = new int[2]; array[0] = sum;// 总和 array[1] = avg;//平均数 */ int[] array = {
sum,avg}; System.out.println(array); return array; } }
day06【类与对象、封装、构造方法】
1. 面向对象的思想
概念
一种程序设计思想,这里的对象泛指现实中一切事物,每种事物都具备自己的属性和行为。面向对象思想就是在计算机程序设计过程中,参照现实中事物,将事物的属性特征、行为特征抽象出来,描述成计算机事件的设计思想。强调的是通过调用对象的行为来实现功能。
特点
更符合我们的思考习惯,将复杂的事情简单化,并将我们从执行者变成指挥者。面向对象的语言中,包含了三大基本特征,即封装、继承和多态。
2. 类和对象
2.1类
- 类:是一组相关属性和行为的集合。可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该类事物。
- 属性:就是该事物的状态信息。
- 行为:就是该事物能够做什么。
2.2 对象
对象:是一类事物的具体体现。对象是类的一个实例,必然具备该类事物的属性和行为。
2.3 类和对象的关系
- 类是对一类事物的描述,是抽象的。
- 对象是一类事物的实例,是具体的。
- 类是对象的模板,对象是类的实体。
3. 类的定义
public class ClassName {
//成员变量 //成员方法 }
- 定义类:就是定义类的成员,包括成员变量和成员方法。
- 成员变量:和以前定义变量几乎是一样的。只不过位置发生了改变。在类中,方法外。
- 成员方法:和以前定义方法几乎是一样的。只不过把static去掉,static的作用在面向对象后面课程中再详细讲解。
4. 类的使用
步骤
通常情况下,一个类并不能直接使用,需要根据类创建一个对象,才能使用。
- 导包:也就是指出需要使用的类,在什么位置。
import包名称.类名称;
import cn.itcast.day06.demo01.Student;
对于和当前类属于同一个包的情况,可以省略导包语句不写。 - 创建,格式:
类名称 对象名 =new类名称();
Student stu = new Student(); - 使用,分为两种情况:
使用成员变量:对象名.成员变量名
使用成员方法:对象名.成员方法名(参数)
(也就是,想用谁,就用对象名点儿谁。)
注意
如果成员变量没有进行赋值,那么将会有一个默认值,规则和数组一样。
5. 对象的定义
创建对象:
类名 对象名 = new 类名();
使用对象访问类中的成员:
对象名.成员变量; 对象名.成员方法();
6. 对象内存图
一个对象
[外链图片转存失败(img-yrB8jONO-03)(img\2.jpg)]
两个对象,调用同一个方法内存图
[外链图片转存失败(img-UTsYHDSy-05)(img\3.jpg)]
7. 成员变量和局部变量区别
- 定义的位置不一样【重点】
局部变量:在方法的内部
成员变量:在方法的外部,直接写在类当中 - 作用范围不一样【重点】
局部变量:只有方法当中才可以使用,出了方法就不能再用
成员变量:整个类全都可以通用。 - 默认值不一样【重点】
局部变量:没有默认值,如果要想使用,必须手动进行赋值
成员变量:如果没有赋值,会有默认值,规则和数组一样 - 内存的位置不一样(了解)
局部变量:位于栈内存
成员变量:位于堆内存 - 生命周期不一样(了解)
局部变量:随着方法进栈而诞生,随着方法出栈而消失
成员变量:随着对象创建而诞生,随着对象被垃圾回收而消失
8.封装
封装性在Java当中的体现:
- 方法就是一种封装
- 关键字private也是一种封装
封装就是将一些细节信息隐藏起来,对于外界不可见。
9.private
超出了本类范围之外就不能再直接访问了。间接访问private成员变量,就是定义一对儿Getter/Setter方法
10.Getter/Setter命名规则
对于基本类型当中的boolean值,Getter方法一定要写成isXxx的形式,而setXxx规则不变。
11. this
通过谁调用的方法,谁就是this。
12. 构造方法
构造方法是专门用来创建对象的方法,当我们通过关键字new来创建对象时,其实就是在调用构造方法。
格式
public 类名称(参数类型 参数名称) {
方法体 }
注意事项
- 构造方法的名称必须和所在的类名称完全一样,就连大小写也要一样
- 构造方法不要写返回值类型,连void都不写
- 构造方法不能return一个具体的返回值
- 如果没有编写任何构造方法,那么编译器将会默认赠送一个构造方法,没有参数、方法体什么事情都不做。
public Student() {} - 一旦编写了至少一个构造方法,那么编译器将不再赠送。
- 构造方法也是可以进行重载的。
重载:方法名称相同,参数列表不同。
13.java bean
一个标准的类通常要拥有下面四个组成部分:
- 所有的成员变量都要使用private关键字修饰
- 为每一个成员变量编写一对儿Getter/Setter方法
- 编写一个无参数的构造方法
- 编写一个全参数的构造方法
day07【Scanner类、Random类、ArrayList类】
1. API
概念
API(Application Programming Interface),应用程序编程接口。Java API是一本程序员的字典 ,是JDK中提供给我们使用的类的说明文档。
使用步骤
- 打开帮助文档。
- 点击显示,找到索引,看到输入框。
- 你要找谁?在输入框里输入,然后回车。
- 看包。
java.lang下的类不需要导包,其他需要。 - 看类的解释和说明。
- 学习构造方法。
- 使用成员方法。
2. Scanner类
2.1什么是Scanner类
一个可以解析基本类型和字符串的简单文本扫描器。
Scanner sc = new Scanner(System.in); int i = sc.nextInt();
备注:System.in 系统输入指的是通过键盘录入数据。
2.2 使用步骤
1. 导包 import 包名.类名; import java.util.Scanner; 2. 创建对象 数据类型 变量名 = new 数据类型(参数列表); Scanner sc = new Scanner(System.in); 3. 使用 变量名.方法名(); int i = sc.nextInt(); // 接收一个键盘录入的整数
3. 匿名对象
概念
创建对象时,只有创建对象的语句,却没有把对象地址值赋值给某个变量。
匿名对象 :没有变量名的对象
应用场景
作为方法的参数和返回值
- 作为参数
class Test { public static void main(String[] args) { // 普通方式 Student stu = new Student("小强",18); input(stu); //匿名对象作为方法接收的参数 input( new Student("小强",18) ); } public static void input(Student stu){ stu.method(); } }- 作为返回值
class Test2 { public static void main(String[] args) { // 普通方式 Student stu = newInstance(); } public static Student newInstance(){ //普通方式 //Student stu = new Student("小强",18); //return stu; //匿名对象作为方法返回值 return new Student("小强",18); } }
4. Random类
4.1 作用
它的实例用于生成伪随机数
4.2 使用步骤
//1. 导包 import java.util.Random; public class Demo01_Random {
public static void main(String[] args) {
//2. 创建键盘录入数据的对象 Random r = new Random(); for(int i = 0; i < 3; i++){
//3. 随机生成一个数据 int number = r.nextInt(10); //4. 输出数据 System.out.println("number:"+ number); } } }
4. ArrayList类
4.1 定义
java.util.ArrayList 是大小可变的数组的实现,存储在内的数据称为元素。此类提供一些方法来操作内部存储的元素。 ArrayList 中可不断添加元素,其大小也自动增长。
4.2 使用步骤
查看类
java.util.ArrayList:该类需要 import导入使后使用。
,表示一种指定的数据类型,叫做泛型。我们使用一种引用数据类型将其替换即可,表示我们将存储哪种引用类型的元素。代码:
ArrayList
,ArrayList
查看构造方法
public ArrayList():构造一个内容为空的集合。
day08【String类、static关键字、Arrays类、Math类】
1. String类
概述
java中所有的字符串文字都可以被看做是实现此类的实例
特点
- 字符串不变: 字符串的值在创建后不能被更改
- String对象是不可变的,所以可以被共享
- "abc"等效于char[] data = {‘a’,‘b’,‘c’}
例如: String str = "abc"; 相当于: char data[] = {
'a', 'b', 'c'}; String str = new String(data); // String底层是靠字符数组实现的
使用步骤
- 查看类
java.lang.String:此类不需要导入
- 查看构造方法
public String(): 初始化新创建的String对象,以使其表示空字符序列public String(char[] value): 通过当前参数中的字符数组来构造新的Stringpublic String(byte[] bytes): 通过使用平台默认字符集解码当前参数中的字节数组来构造新的String
//无参构造 String str = new String(); // 通过字符数组构造 char chars[] = {
'a', 'b', 'c'}; String str2 = new String(chars); // 通过字节数组构造 byte bytes[] = {
97,98,99}; String str3 = new String(bytes);
2. String 常用方法
判断功能的方法
public boolean equals (Object anObject): 将次字符串与指定对象比较public boolean equalsIgnoreCase(String anotherString)忽略大小写
获取功能的方法
public int length ():返回此字符串的长度public String concat(String str): 将指定的字符串拼接到字符串的末尾public char charAt(int index): 返回指定索引处的char值public int indexOf(String str): 返回指定字符串第一次出现在该字符串内的索引public String substring(int beginIndex): 返回子字符串,从beginindex开始截取字符串到字符串末尾public String substring (int beginIndex,int endIndex):从beginindex到endIndex截取字符串,左闭右开
public class String_Demo02 {
public static void main(String[] args) {
//创建字符串对象 String s = "helloworld"; // int length():获取字符串的长度,其实也就是字符个数 System.out.println(s.length()); System.out.println("--------"); // String concat (String str):将将指定的字符串连接到该字符串的末尾. String s = "helloworld"; String s2 = s.concat("hello itheima"); System.out.println(s2);// helloworldhello itheima // char charAt(int index):获取指定索引处的字符 System.out.println(s.charAt(0)); System.out.println(s.charAt(1)); System.out.println("--------"); // int indexOf(String str):获取str在字符串对象中第一次出现的索引,没有返回-1 System.out.println(s.indexOf("l")); System.out.println(s.indexOf("owo")); System.out.println(s.indexOf("ak")); System.out.println("--------"); // String substring(int start):从start开始截取字符串到字符串结尾 System.out.println(s.substring(0)); System.out.println(s.substring(5)); System.out.println("--------"); // String substring(int start,int end):从start到end截取字符串。含start,不含end。 System.out.println(s.substring(0, s.length())); System.out.println(s.substring(3,8)); } }
转换功能的方法
public char[] toCharArray (): 将此字符串转化为新的字符数组public byte[] getBytes ():使用默认字符集将String编码转换为新的字节数组public String replace(CharSequence target, CharSequence replacement): 将与target匹配的字符串用replacement字符串替换
public class String_Demo03 {
public static void main(String[] args) {
// 创建字符串对象 String s = "abcde"; // char[] tpCharArray() 把字符串转换为字符数组 char[] chs = s.toCharArray(); for(int x = 0; x<chs.length;x++) {
System.out.println(chs[x]); } System.out.println("==========="); // byte[] getBytes ():把字符串转换为字节数组 byte[] bytes = s.getBytes(); for(int x = 0; x < bytes.length; x++) {
System.out.println(bytes[x]); } System.out.println("-----------"); // 替换字母it为大写IT String str = "itcast itheima"; String replace = str.replace("it", "IT"); System.out.println(replace); // ITcast ITheima System.out.println("-----------"); } }
CharSequence是一个接口,也是一种引用类型,作为参数类型,可以把String对象传递到方法中。
分割功能的方法
public String[] split(String regex): 将此字符串按照给定的regex拆分为字符串数组
3. Static关键字
概述
用来修饰成员变量和成员方法,被修饰的成员属于 类
定义和使用格式
- 类变量:使用static关键字修饰的成员变量
格式:
static 数据类型 变量名;
应用: 学号编号
- 类方法: 使用static关键字修饰的成员方法,称为静态方法
格式:
修饰符 static 返回值类型 方法名(参数列表){
// 执行语句 }
- 静态方法调用的注意事项:
- 静态方法可以直接访问类变量和静态方法
- 静态方法不能直接访问普通成员变量和成员方法
- 静态方法,不能使用this关键字
小贴士:静态方法只能访问静态成员
调用格式
被static修饰的成员可以并且建议通过类名直接访问
静态原理图解
static 修饰的内容:
- 是随着类的加载而加载的,且只加载一次。
- 存储于一块固定的内存区域(静态区),所以,可以直接被类名调用。
- 它优先于对象存在,所以,可以被所有对象共享。

静态代码块
定义在成员位置,使用static修饰的代码块{},随着类的加载而执行,且执行一次,优先于main方法和构造方法的执行。
作用:给类变量进行初始化赋值
3. Arrays类
概述
java.util.Arrays此类包含用来操作数组的各种方法,所有方法均为静态方法。
操作数组的方法
public static String toString(int[] a): 返回指定数组内容的字符串表示形式public static void sort(int[] a): 对指定的int 型数组按数字升序排序 案例:倒序打印
4. Math类
概述
基本数学运算,也是静态方法,不用创建对象
基本运算方法
public static double abs(double a): 返回double的绝对值public static double ceil(double a): 返回大于等于参数的最小的整数public static double floor(double a): 返回小于等于参数最大的整数public static long round(double a): 返回最接近参数的long(相当于四舍五入)
day09【继承、super、this、抽象类】
1. 继承
定义
多个类存在相同的属性和行为时,共性抽取。
子类继承父类的属性和行为,可以直接访问父类的非私有属性和行为。
好处
- 提高代码的复用性
- 类与类之间产生了关系,是多态的前提。
格式
class 父类 {
... } class 子类 extends 父类 {
... }
继承后的特点-成员变量
- 成员变量不重名 没有影响
- 成员变量重名 有同名的成员变量,访问父类中非私有成员变量时,使用
super关键字,修饰父类成员变量
一般遵循封装的原则,private修饰成员变量,如何访问父类的私有成员变量?用父类提供的公共的getXxx和setXxx方法
继承后的特点-成员方法
- 成员方法不重名 没有影响
- 成员方法重名 重写(override)
重写
子类出现重名的成员方法(返回值类型,方法名和参数列表都相同),访问是特殊情况,叫方法重写,又叫覆写,声明不变,重新实现。
应用: 新旧手机(super.父类成员方法表示调用父类的成员方法)
注意事项
- 子类方法覆盖父类方法,必须要保证权限大于等于父类权限。
- 子类方法覆盖父类方法,返回值类型、函数名和参数列表都要一模一样。
继承后的特点-构造方法
- 构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的。
- 构造方法的作用是初始化成员变量的。所以子类的初始化过程中,必须先执行父类的初始化动作。子类的构造方法中默认有一个
super(),表示调用父类的构造方法,父类成员变量初始化后,才可以给子类使用。
继承的特点
- Java只支持单继承,不支持多继承。
- Java支持多层继承(继承体系)。
- 子类和父类是一种相对的概念。
2. super和this
父类空间优先于子类对象产生
在每次创建子类对象时,先初始化父类空间,再创建其子类对象本身。目的在于子类对象中包含了其对应的父类空间,便可以包含其父类的成员,如果父类成员非private修饰,则子类可以随意使用父类成员。代码体现在子类的构造方法调用时,一定先调用父类的构造方法。
super和this的含义:
- super: 代表父类的存储空间标识(可以理解为父类的引用)
- this: 代表当前对象的引用(谁调用就代表谁)
super和this的用法
- 访问成员
this.成员变量 -- 本类的 super.成员变量 -- 父类的 this.成员方法名() -- 本类的 super.成员方法名() -- 父类的
- 访问构造方法
this(...) -- 本类的构造方法 super(...) -- 父类的构造方法
子类的每个构造方法中均有默认的super(),调用父类的空参构造。手动调用父类构造会覆盖默认的super()。
super() 和 this() 都必须是在构造方法的第一行,所以不能同时出现。
3. 抽象类
概述
我们把没有方法主体的方法称为抽象方法。Java语法规定,包含抽象方法的类就是抽象类。
abstract使用格式
- 抽象方法
修饰符 abstract 返回值类型 方法名 (参数列表);
- 抽象类
abstract class 类名字 {
}
抽象的使用
继承抽象类的子类必须重写父类所有的抽象方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该父类的抽象方法,否则,从最初的父类到最终的子类都不能创建对象,失去意义。
此时的方法重写,是子类对父类抽象方法的完成实现,我们将这种方法重写的操作,也叫做实现方法。
抽象的注意事项
- 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。
理解:假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义。
- 抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的。
理解:子类的构造方法中,有默认的super(),需要访问父类构造方法。
- 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
理解:未包含抽象方法的抽象类,目的就是不想让调用者创建该类对象,通常用于某些特殊的类结构设计。
- 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象类。
理解:假设不重写所有抽象方法,则类中可能包含抽象方法。那么创建对象后,调用抽象的方法,没有意义。
day10【接口、多态】
1. 接口
概述
接口,是java语言中一种引用类型,是方法的集合,接口的内部主要就是封装了方法,包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法(JDK 9)。
接口的定义,与定义类相似,但是使用interface关键字。不能创建对象,但是可以被实现(implements,类似于被继承)。一个实现接口的类,需要实现接口中的所有的抽象方法,创建该类对象,就可以调用方法了,否则它必须是一个抽象类。
默认方法:以Iterator接口为例,用户通常不会使用remove方法,1.8以后将remove方法设为默认方法,默认实现。
default void remove() { throw new UnsupportedOperationException("remove"); }
定义格式
- 含有抽象方法
public interface InterFaceName {
public abstract void method(); }
- 含有默认方法和静态方法
public interface InterFaceName {
public default void method() {
// 执行语句 } public static void method2() {
// 执行语句 } }
基本的实现
类与接口的关系为实现关系,类实现接口,该类称为接口的实现类,也可以称为接口的子类。
非抽象子类实现接口:
- 必须重写接口所有的抽象方法
- 继承了接口的默认方法,既可以直接调用,也可重写。
实现格式
class 类名 implements 接口名 {
// 重写接口中抽象方法【必须】 // 重写接口中默认方法【可选】 }
静态方法的使用
静态只能用接口名调用,不可以通过实现类的类名或者实现类的对象调用。
接口的多实现
对于接口而言,一个类可以实现多个接口,这叫接口的多实现。一个类能继承一个父类,同时实现多个接口。
格式:
class 类名 [extends 父类名] implements 接口名1,接口名2,接口名3... {
// 重写接口中抽象方法【必须】 // 重写接口中默认方法【不重名时可选】 }
如果抽象方法有重名的,只需要重写一次。
如果默认方法有重名的,必须重写一次。
静态方法不会冲突,因为只能通过各自接口名访问。
优先级
当一个类,既继承一个父类,又实现若干接口,父类的成员方法与接口的默认方法重名,子类执行父类的成员方法。
其他
- 接口中,无法定义成员变量,但是可以定义常量,其值不可以改变,默认使用public static final修饰
- 接口中,没有构造方法,不能创建对象。
- 接口中,没有静态代码块。
- 父类可以作为类型接收子类的对象
接口可以作为类型接收实现类的对象
2. 多态
概念
是指同一行为,具有多个不同的表现形式。
前提
- 继承或者实现【二选一】
- 方法的重写【意义体现:不重写,无意义】
- 父类引用指向子类对象【格式体现】
格式
父类类型 变量名 = new 子类对象; 变量名.方法名();
父类类型:指子类对象继承的父类类型,或者实现的父接口类型。
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,执行的是子类重写后方法。
成员变量:编译看左边,运行还看左边。 成员方法:编译看左边,运行看右边。
多态的好处
实际开发的过程中,父类类型作为方法形式参数,传递子类对象给方法,进行方法的调用,更能体现出多态的扩展性与便利。可以使程序编写的更简单,并有良好的扩展。
引用类型转换
- 向上转型: 多态本身是子类类型向父类类型向上转换的过程,这个过程是默认的。
- 向下转型:父类类型向子类类型向下转换的过程,这个过程是强制的。
为什么要转型?
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误,不能调用子类拥有,而父类没有的方法。想要调用子类特有的方法,必须做向下转型。
转型的异常:运行报错
ClassCastException
如何避免转型异常?
变量名 instanceof 数据类型 如果变量属于该数据类型,返回true。 如果变量不属于该数据类型,返回false。
多态经典题
A B C D的题,见 day10_test.demo03
day11 【内部类、final、权限】
1. 内部类
1. 概念
将一个类A定义在另一个类B里面,里面的类A就成为内部类,B则为外部类
2. 成员内部类
- 成员内部类: 定义在类中方法外的类
- 格式:
class 外部类 {
class 内部类 {
} }
- 应用场景:描述事物时,若一个事物内部还包含其他事物,就可以使用内部类,如汽车类中包含发动机类。
- 访问特点:
- 内部类可以直接访问外部类的成员,包括私有成员
- 外部类要访问内部类的成员,必须建立内部类的对象
- 内部类对象创建格式
外部类名.内部类名 对象名 = new 外部类型().new 内部类型();
内部类仍然是独立的类,编译后内部类编译为独立的.class如Person$Heart.class
2. 匿名内部类
概念
内部类的简化写法,本质为一个带具体实现的父类或者父接口的匿名的子类对象。
格式
new 父类名或者接口名(){
//方法重写 @Override public void method(){
//执行语句 } };
使用方式
定义接口
public abstract class FlyAble{
public abstract void fly(); }
创建匿名内部类,并调用:
通常在方法的形参是接口或者抽象类时,可以将匿名内部类作为参数传递
public class InnerDemo1 {
public static void main(String[] args){
/* 1. 等号右边: 定义并创建该接口的子类对象 2. 等号左边:是多态,接口类型引用指向子类对象 */ FlyAble f = new FlyAble(){
public void fly() {
System.out.println("我飞了~~~"); } }; // 将f传递给showFly方法中 showFly(f); } public static void showFly(FlyAble f){
f.fly(); } }
简化写法
public class InnerDemo2 {
public static void main(String[] args){
/* 创建匿名内部类,直接传递给showFly(FlyAble f) */ showFly( new FlyAble(){
public void fly() {
System.out.println("我飞了~~~"); } }); } public static void showFly(FlyAble f) {
f.fly(); } }
3. final
概述
为了避免这种随意改写继承API中提供的类的内容的情况,Java提供了final 关键字,用于修饰不可改变内容。
- final: 不可改变。可以用于修饰类、方法和变量。
- 类:被修饰的类,不能被继承。
- 方法:被修饰的方法,不能被重写。
- 变量:被修饰的变量,不能被重新赋值。
使用方式
- 修饰类
格式如下:
final class 类名 {
}
查询API发现像 public final class String 、public final class Math 、public final class Scanner 等,很多我们学习过的类,都是被final修饰的,目的就是供我们使用,而不让我们所以改变其内容。
- 修饰方法
格式如下:
修饰符 final 返回值类型 方法名(参数列表){
//方法体 }
重写被 final修饰的方法,编译时就会报错
- 修饰变量
- 局部变量——基本类型 被final修饰后,只能赋值一次,不能再更改
- 局部变量——引用类型 只能指向一个对象,地址不能再更改。但是不影响对象内部的成员变量值的修改
- 成员变量 涉及到初始化的问题
a. 显示初始化
public class User {
final String USERNAME = "张三"; private int age; }
b. 构造方法初始化
public class User {
final String USERNAME ; private int age; public User(String username, int age) {
this.USERNAME = username; this.age = age; } }
被final修饰的常量名称,一般都有书写规范,所有字母都大写
4. 权限修饰符
不同权限的访问能力
| public | protected | default(空的) | private | |
|---|---|---|---|---|
| 同一类中 | √ | √ | √ | √ |
| 同一包中(子类与无关类) | √ | √ | √ | |
| 不同包的子类 | √ | √ | ||
| 不同包中的无关类 | √ |
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/225543.html原文链接:https://javaforall.net
