文章目录

  • 第一章 常用API
    • 1. API概述和使用
    • 2. Scanner概述及其API文档
      • 2.1 什么是Scanner类
      • 2.2 引用类型使用步骤
      • 2.3 练习:键盘输入两数字求和
      • 2.4 练习 键盘输入三个数字求最大值
    • 3. 匿名对象
      • 3.1 匿名对象的说明
      • 3.2 匿名对象作为方法的参数
    • 4. Random类
      • 4.1 Random概述和基本使用
      • 4.2 Random生成指定范围的随机数
      • 4.3 随机生成1~n之间的数
      • 4.4 猜数字小游戏
    • 5. ArrayList集合
      • 5.1 引入对象数组
      • 5.2 什么是ArrayList类
      • 5.3 ArrayList使用步骤
      • 5.4 使用方法和遍历
      • 5.5 如何存储基本数据类型
      • 5.6 ArrayList练习
        • 题目:生成6个1~33之间的随机整数,添加到集合,并遍历集合。
        • 题目:自定义4个学生对象,添加到集合,并遍历。
        • 题目:定义以指定格式打印集合的方法(ArrayList类型作为参数),使用{}扩起集合,使用@分隔每个元素。
        • 题目:用一个大集合存入20个随机数字,然后筛选其中的偶数元素,放到小集合当中。
    • 6. String类
      • 6.1 字符串的构造方法和直接创建
      • 6.2 字符串的常量池
      • 6.3 字符串的比较相关方法
      • 6.4 字符串的获取相关方法
      • 6.5 字符串的截取相关方法
      • 6.6 字符串的转换相关方法
      • 6.7 字符串的分割方法
        • 练习 定义一个方法,把数组{1,2,3}按照指定格式拼接成一个字符串。格式参照如下:[word1#word2#word3]。
        • 练习 键盘输入一个字符串,并且统计其中各种字符出现的次数。
    • 7. static静态
      • 7.1 静态static关键字修饰成员
      • 7.2 静态static关键字修饰成员
      • 7.3 静态static的内存图
      • 7.5 静态代码块
    • 8. Arrays工具类
      • 8.1 数组工具类Arrays
      • 8.2 题目:请使用Arrays相关的API,将一个随机字符串中的所有字符升序排列,并倒序打印。
    • 9. Math类
      • 9.1 数学工具类Math
      • 9.1 题目 计算在-10.8到5.9之间,绝对值大于6或者小于2.1的整数有多少个?
  • 第二章 继承与多态
    • 1. 继承
      • 1.1 继承的格式
      • 1.2 继承中成员变量的访问特点
      • 1.3 区分子类方法中重名的三种
      • 1.4 继承中成员方法的访问特点
      • 1.5 继承中方法的覆盖重写(注解)
      • 1.6 继承中方法的覆盖重写(应用)
      • 1.7 继承中构造方法的访问特点
      • 1.8 super关键字的三种用法
      • 1.9 this关键字的三种用法
      • 1.10 super与this关键字图解
      • 1.11 Java继承的三个特点
    • 2. 抽象类
      • 2.1 抽象的概念
      • 2.2 抽象方法和抽象类的格式
      • 2.3 抽象方法和抽象类的使用
      • 2.4 抽象方法和抽象类的注意事项
      • 2.5 发红包案例
    • 3. 接口
      • 3.1 接口的定义基本格式
      • 3.2 接口的抽象方法使用
      • 3.3 接口的默认方法定义和使用
      • 3.4 接口的静态方法定义和使用
      • 3.5 接口的私有方法定义和使用
      • 3.6 接口的常量定义和使用
      • 3.7 接口的内容小结
      • 3.8 继承父类并实现多个接口
      • 3.9 接口之间的多继承
    • 4. 多态
      • 4.1 多态的格式和使用
      • 4.2 多态中成员变量方法的使用特点
      • 4.3 使用多态的好处
      • 4.4 对象的向上转型
      • 4.5 对象的向下转型
      • 4.6 用instanceof关键字进行
      • 4.7 笔记本USB案例
    • 5. final关键字
      • 5.1 final关键字用于修饰类
      • 5.2 final关键字用于修饰成员方法
      • 5.3 final关键字用于修饰局部变量
      • 5.4 final关键字用于修饰成员
    • 6. 权限修饰符
    • 7. 内部类
      • 7.1 成员内部类的定义
      • 7.2 成员内部类的使用
      • 7.3 内部类的同名变量访问
      • 7.4 局部内部类定义
      • 7.5 局部内部类final问题
      • 7.6 匿名内部类及注意事项
      • 7.7 类作为成员变量类型
      • 7.8 接口作为成员变量类型
      • 7.9 接口作为方法的参数
      • 7.10 发红包案例

第一章 常用API

1. API概述和使用


2. Scanner概述及其API文档

2.1 什么是Scanner类

一个可以解析基本类型和字符串的简单文本扫描器。
例如,以下代码使用户能够从 System.in中读取一个数:

Scanner sc = new Scanner(System.in);
int i = sc.nextInt();

备注:System.in 系统输入指的是通过键盘录入数据。

2.2 引用类型使用步骤

导包
使用import关键字导包,在类的所有代码之前导包,引入要使用的类型,java.lang包下的所有类无需导入。

import java.util.Scanner; // 1. 导包/*
Scanner类的功能:可以实现键盘输入数据,到程序当中。引用类型的一般使用步骤:1. 导包
import 包路径.类名称;
如果需要使用的目标类,和当前类位于同一个包下,则可以省略导包语句不写。
只有java.lang包下的内容不需要导包,其他的包都需要import语句。2. 创建
类名称 对象名 = new 类名称();3. 使用
对象名.成员方法名()获取键盘输入的一个int数字:int num = sc.nextInt();
获取键盘输入的一个字符串:String str = sc.next();*/
public class Demo01Scanner {public static void main(String[] args) {// 2. 创建// 备注:System.in代表从键盘进行输入Scanner sc = new Scanner(System.in);// 3. 获取键盘输入的int数字int num = sc.nextInt();System.out.println("输入的int数字是:" + num);// 4. 获取键盘输入的字符串String str = sc.next();System.out.println("输入的字符串是:" + str);}}

2.3 练习:键盘输入两数字求和

import java.util.Scanner;/*
题目:
键盘输入两个int数字,并且求出和值。思路:
1. 既然需要键盘输入,那么就用Scanner
2. Scanner的三个步骤:导包、创建、使用
3. 需要的是两个数字,所以要调用两次nextInt方法
4. 得到了两个数字,就需要加在一起。
5. 将结果打印输出。*/
public class Demo02ScannerSum {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入第一个数字:");int a = sc.nextInt();System.out.println("请输入第二个数字:");int b = sc.nextInt();int result = a + b;System.out.println("结果是:" + result);}}

2.4 练习 键盘输入三个数字求最大值

import java.util.Scanner;/*
题目:
键盘输入三个int数字,然后求出其中的最大值。思路:
1. 既然是键盘输入,肯定需要用到Scanner
2. Scanner三个步骤:导包、创建、使用nextInt()方法
3. 既然是三个数字,那么调用三次nextInt()方法,得到三个int变量
4. 无法同时判断三个数字谁最大,应该转换成为两个步骤:4.1 首先判断前两个当中谁最大,拿到前两个的最大值4.2 拿着前两个中的最大值,再和第三个数字比较,得到三个数字当中的最大值
5. 打印最终结果*/
public class Demo03ScannerMax {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入第一个数字:");int a = sc.nextInt();System.out.println("请输入第二个数字:");int b = sc.nextInt();System.out.println("请输入第三个数字:");int c = sc.nextInt();// 首先得到前两个数字当中的最大值int temp = a > b ? a : b;int max = temp > c ? temp : c;System.out.println("最大值是:" + max);}
}

3. 匿名对象

Anonymous匿名的

3.1 匿名对象的说明

定义一个Person类

public class Person {String name;public void showName() {System.out.println("我叫:" + name);}}

创建对象

/*
创建对象的标准格式:
类名称 对象名 = new 类名称();匿名对象就是只有右边的对象,没有左边的名字和赋值运算符。
new 类名称();注意事项:匿名对象只能使用唯一的一次,下次再用不得不再创建一个新对象。
使用建议:如果确定有一个对象只需要使用唯一的一次,就可以用匿名对象。*/
public class Demo01Anonymous {public static void main(String[] args) {// 左边的one就是对象的名字Person one = new Person();one.name = "高圆圆";one.showName(); // 我叫高圆圆System.out.println("===============");// 匿名对象new Person().name = "赵又廷";new Person().showName(); // 我叫:null}}

3.2 匿名对象作为方法的参数

import java.util.Scanner;public class test {public static void main(String[] args) {// 普通使用方式
//        Scanner sc = new Scanner(System.in);
//        int num = sc.nextInt();// 匿名对象的方式
//        int num = new Scanner(System.in).nextInt();
//        System.out.println("输入的是:" + num);// 使用一般写法传入参数
//        Scanner sc = new Scanner(System.in);
//        methodParam(sc);// 使用匿名对象来进行传参
//        methodParam(new Scanner(System.in));Scanner sc = methodReturn();int num = sc.nextInt();System.out.println("输入的是:" + num);}public static void methodParam(Scanner sc) {int num = sc.nextInt();System.out.println("输入的是:" + num);}public static Scanner methodReturn() {//        Scanner sc = new Scanner(System.in);
//        return sc;return new Scanner(System.in);}}

4. Random类

4.1 Random概述和基本使用

import java.util.Random;/*
Random类用来生成随机数字。使用起来也是三个步骤:1. 导包
import java.util.Random;2. 创建
Random r = new Random(); // 小括号当中留空即可3. 使用
获取一个随机的int数字(范围是int所有范围,有正负两种):int num = r.nextInt()
获取一个随机的int数字(参数代表了范围,左闭右开区间):int num = r.nextInt(3)
实际上代表的含义是:[0,3),也就是0~2*/
public class Demo01Random {public static void main(String[] args) {Random r = new Random();int num = r.nextInt();System.out.println("随机数是:" + num);}}

4.2 Random生成指定范围的随机数

import java.util.Random;public class Demo02Random {public static void main(String[] args) {Random r = new Random();for (int i = 0; i < 100; i++) {int num = r.nextInt(10); // 范围实际上是0~9System.out.println(num);}}}

4.3 随机生成1~n之间的数

import java.util.Random;/*
题目要求:
根据int变量n的值,来获取随机数字,范围是[1,n],可以取到1也可以取到n。思路:
1. 定义一个int变量n,随意赋值
2. 要使用Random:三个步骤,导包、创建、使用
3. 如果写10,那么就是0~9,然而想要的是1~10,可以发现:整体+1即可。
4. 打印随机数字*/
public class Demo03Random {public static void main(String[] args) {int n = 5;Random r = new Random();for (int i = 0; i < 100; i++) {// 本来范围是[0,n),整体+1之后变成了[1,n+1),也就是[1,n]int result = r.nextInt(n) + 1;System.out.println(result);}}}

4.4 猜数字小游戏

import java.util.Random;
import java.util.Scanner;/*
题目:
用代码模拟猜数字的小游戏。思路:
1. 首先需要产生一个随机数字,并且一旦产生不再变化。用Random的nextInt方法
2. 需要键盘输入,所以用到了Scanner
3. 获取键盘输入的数字,用Scanner当中的nextInt方法
4. 已经得到了两个数字,判断(if)一下:如果太大了,提示太大,并且重试;如果太小了,提示太小,并且重试;如果猜中了,游戏结束。
5. 重试就是再来一次,循环次数不确定,用while(true)。*/
public class Demo04RandomGame {public static void main(String[] args) {Random r = new Random();int randomNum = r.nextInt(100) + 1; // [1,100]Scanner sc = new Scanner(System.in);while (true) {System.out.println("请输入你猜测的数字:");int guessNum = sc.nextInt(); // 键盘输入猜测的数字if (guessNum > randomNum) {System.out.println("太大了,请重试。");} else if (guessNum < randomNum) {System.out.println("太小了,请重试。");} else {System.out.println("恭喜你,猜中啦!");break; // 如果猜中,不再重试}}
·System.out.println("游戏结束。");}}

5. ArrayList集合

定义一个Person类

public class Person {private String name;private int age;public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

5.1 引入对象数组

/*
题目:
定义一个数组,用来存储3个Person对象。数组有一个缺点:一旦创建,程序运行期间长度不可以发生改变。*/
public class Demo01Array {public static void main(String[] args) {// 首先创建一个长度为3的数组,里面用来存放Person类型的对象Person[] array = new Person[3];Person one = new Person("迪丽热巴", 18);Person two = new Person("古力娜扎", 28);Person three = new Person("玛尔扎哈", 38);// 将one当中的地址值赋值到数组的0号元素位置array[0] = one;array[1] = two;array[2] = three;System.out.println(array[0]); // 地址值System.out.println(array[1]); // 地址值System.out.println(array[2]); // 地址值System.out.println(array[1].getName()); // 古力娜扎}
}

5.2 什么是ArrayList类

5.3 ArrayList使用步骤

import java.util.ArrayList;/*
数组的长度不可以发生改变。
但是ArrayList集合的长度是可以随意变化的。对于ArrayList来说,有一个尖括号<E>代表泛型。
泛型:也就是装在集合当中的所有元素,全都是统一的什么类型。
注意:泛型只能是引用类型,不能是基本类型。注意事项:
对于ArrayList集合来说,直接打印得到的不是地址值,而是内容。
如果内容是空,得到的是空的中括号:[]*/
public class Demo02ArrayList {public static void main(String[] args) {// 创建了一个ArrayList集合,集合的名称是list,里面装的全都是String字符串类型的数据// 备注:从JDK 1.7+开始,右侧的尖括号内部可以不写内容,但是<>本身还是要写的。ArrayList<String> list = new ArrayList<>();System.out.println(list); // []// 向集合当中添加一些数据,需要用到add方法。list.add("赵丽颖");System.out.println(list); // [赵丽颖]list.add("迪丽热巴");list.add("古力娜扎");list.add("玛尔扎哈");System.out.println(list); // [赵丽颖, 迪丽热巴, 古力娜扎, 玛尔扎哈]//        list.add(100); // 错误写法!因为创建的时候尖括号泛型已经说了是字符串,添加进去的元素就必须都是字符串才行}}

5.4 使用方法和遍历

使用方法

import java.util.ArrayList;/*
ArrayList当中的常用方法有:public boolean add(E e):向集合当中添加元素,参数的类型和泛型一致。返回值代表添加是否成功。
备注:对于ArrayList集合来说,add添加动作一定是成功的,所以返回值可用可不用。
但是对于其他集合(今后学习)来说,add添加动作不一定成功。public E get(int index):从集合当中获取元素,参数是索引编号,返回值就是对应位置的元素。public E remove(int index):从集合当中删除元素,参数是索引编号,返回值就是被删除掉的元素。public int size():获取集合的尺寸长度,返回值是集合中包含的元素个数。*/
public class Demo03ArrayListMethod {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();System.out.println(list); // []// 向集合中添加元素:addboolean success = list.add("柳岩");System.out.println(list); // [柳岩]System.out.println("添加的动作是否成功:" + success); // truelist.add("高圆圆");list.add("赵又廷");list.add("李小璐");list.add("贾乃亮");System.out.println(list); // [柳岩, 高圆圆, 赵又廷, 李小璐, 贾乃亮]// 从集合中获取元素:get。索引值从0开始String name = list.get(2);System.out.println("第2号索引位置:" + name); // 赵又廷// 从集合中删除元素:remove。索引值从0开始。String whoRemoved = list.remove(3);System.out.println("被删除的人是:" + whoRemoved); // 李小璐System.out.println(list); // [柳岩, 高圆圆, 赵又廷, 贾乃亮]// 获取集合的长度尺寸,也就是其中元素的个数int size = list.size();System.out.println("集合的长度是:" + size);}}

遍历

import java.util.ArrayList;public class Demo04ArrayListEach {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("迪丽热巴");list.add("古力娜扎");list.add("玛尔扎哈");// 遍历集合for (int i = 0; i < list.size(); i++) {System.out.println(list.get(i));}}
}

5.5 如何存储基本数据类型

import java.util.ArrayList;/*
如果希望向集合ArrayList当中存储基本类型数据,必须使用基本类型对应的“包装类”。基本类型    包装类(引用类型,包装类都位于java.lang包下)
byte        Byte
short       Short
int         Integer     【特殊】
long        Long
float       Float
double      Double
char        Character   【特殊】
boolean     Boolean从JDK 1.5+开始,支持自动装箱、自动拆箱。自动装箱:基本类型 --> 包装类型
自动拆箱:包装类型 --> 基本类型*/
public class Demo05ArrayListBasic {public static void main(String[] args) {ArrayList<String> listA = new ArrayList<>();// 错误写法!泛型只能是引用类型,不能是基本类型
//        ArrayList<int> listB = new ArrayList<>();ArrayList<Integer> listC = new ArrayList<>();listC.add(100);listC.add(200);System.out.println(listC); // [100, 200]int num = listC.get(1);System.out.println("第1号元素是:" + num);}}

5.6 ArrayList练习

题目:生成6个1~33之间的随机整数,添加到集合,并遍历集合。

import java.util.ArrayList;
import java.util.Random;/*
题目:
生成6个1~33之间的随机整数,添加到集合,并遍历集合。思路:
1. 需要存储6个数字,创建一个集合,<Integer>
2. 产生随机数,需要用到Random
3. 用循环6次,来产生6个随机数字:for循环
4. 循环内调用r.nextInt(int n),参数是33,0~32,整体+1才是1~33
5. 把数字添加到集合中:add
6. 遍历集合:for、size、get*/
public class Demo01ArrayListRandom {public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>();Random r = new Random();for (int i = 0; i < 6; i++) {int num = r.nextInt(33) + 1;list.add(num);}// 遍历集合for (int i = 0; i < list.size(); i++) {System.out.println(list.get(i));}}}

题目:自定义4个学生对象,添加到集合,并遍历。

public class Student {private String name;private int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
import java.util.ArrayList;/*
题目:
自定义4个学生对象,添加到集合,并遍历。思路:
1. 自定义Student学生类,四个部分。
2. 创建一个集合,用来存储学生对象。泛型:<Student>
3. 根据类,创建4个学生对象。
4. 将4个学生对象添加到集合中:add
5. 遍历集合:for、size、get*/
public class Demo02ArrayListStudent {public static void main(String[] args) {ArrayList<Student> list = new ArrayList<>();Student one = new Student("洪七公", 20);Student two = new Student("欧阳锋", 21);Student three = new Student("黄药师", 22);Student four = new Student("段智兴", 23);list.add(one);list.add(two);list.add(three);list.add(four);// 遍历集合for (int i = 0; i < list.size(); i++) {Student stu = list.get(i);System.out.println("姓名:" + stu.getName() + ",年龄" + stu.getAge());}}}

题目:定义以指定格式打印集合的方法(ArrayList类型作为参数),使用{}扩起集合,使用@分隔每个元素。

import java.util.ArrayList;/*
题目:
定义以指定格式打印集合的方法(ArrayList类型作为参数),使用{}扩起集合,使用@分隔每个元素。
格式参照 {元素@元素@元素}。System.out.println(list);       [10, 20, 30]
printArrayList(list);           {10@20@30}*/
public class Demo03ArrayListPrint {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("张三丰");list.add("宋远桥");list.add("张无忌");list.add("张翠山");System.out.println(list); // [张三丰, 宋远桥, 张无忌, 张翠山]printArrayList(list);}/*定义方法的三要素返回值类型:只是进行打印而已,没有运算,没有结果;所以用void方法名称:printArrayList参数列表:ArrayList*/public static void printArrayList(ArrayList<String> list) {// {10@20@30}System.out.print("{");for (int i = 0; i < list.size(); i++) {String name = list.get(i);if (i == list.size() - 1) {System.out.println(name + "}");} else {System.out.print(name + "@");}}}}

题目:用一个大集合存入20个随机数字,然后筛选其中的偶数元素,放到小集合当中。

import java.util.ArrayList;
import java.util.Random;/*
题目:
用一个大集合存入20个随机数字,然后筛选其中的偶数元素,放到小集合当中。
要求使用自定义的方法来实现筛选。分析:
1. 需要创建一个大集合,用来存储int数字:<Integer>
2. 随机数字就用Random nextInt
3. 循环20次,把随机数字放入大集合:for循环、add方法
4. 定义一个方法,用来进行筛选。
筛选:根据大集合,筛选符合要求的元素,得到小集合。
三要素
返回值类型:ArrayList小集合(里面元素个数不确定)
方法名称:getSmallList
参数列表:ArrayList大集合(装着20个随机数字)
5. 判断(if)是偶数:num % 2 == 0
6. 如果是偶数,就放到小集合当中,否则不放。*/
public class Demo04ArrayListReturn {public static void main(String[] args) {ArrayList<Integer> bigList = new ArrayList<>();Random r = new Random();for (int i = 0; i < 20; i++) {int num = r.nextInt(100) + 1; // 1~100bigList.add(num);}ArrayList<Integer> smallList = getSmallList(bigList);System.out.println("偶数总共有多少个:" + smallList.size());for (int i = 0; i < smallList.size(); i++) {System.out.println(smallList.get(i));}}// 这个方法,接收大集合参数,返回小集合结果public static ArrayList<Integer> getSmallList(ArrayList<Integer> bigList) {// 创建一个小集合,用来装偶数结果ArrayList<Integer> smallList = new ArrayList<>();for (int i = 0; i < bigList.size(); i++) {int num = bigList.get(i);if (num % 2 == 0) {smallList.add(num);}}return smallList;}}

6. String类

6.1 字符串的构造方法和直接创建

/*
java.lang.String类代表字符串。
API当中说:Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。
其实就是说:程序当中所有的双引号字符串,都是String类的对象。(就算没有new,也照样是。)字符串的特点:
1. 字符串的内容永不可变。【重点】
2. 正是因为字符串不可改变,所以字符串是可以共享使用的。
3. 字符串效果上相当于是char[]字符数组,但是底层原理是byte[]字节数组。创建字符串的常见3+1种方式。
三种构造方法:
public String():创建一个空白字符串,不含有任何内容。
public String(char[] array):根据字符数组的内容,来创建对应的字符串。
public String(byte[] array):根据字节数组的内容,来创建对应的字符串。
一种直接创建:
String str = "Hello"; // 右边直接用双引号注意:直接写上双引号,就是字符串对象。*/
public class Demo01String {public static void main(String[] args) {// 使用空参构造String str1 = new String(); // 小括号留空,说明字符串什么内容都没有。System.out.println("第1个字符串:" + str1);// 根据字符数组创建字符串char[] charArray = { 'A', 'B', 'C' };String str2 = new String(charArray);System.out.println("第2个字符串:" + str2);// 根据字节数组创建字符串byte[] byteArray = { 97, 98, 99 };String str3 = new String(byteArray);System.out.println("第3个字符串:" + str3);// 直接创建String str4 = "Hello";System.out.println("第4个字符串:" + str4);}}

6.2 字符串的常量池

/*
字符串常量池:程序当中直接写上的双引号字符串,就在字符串常量池中。对于基本类型来说,==是进行数值的比较。
对于引用类型来说,==是进行【地址值】的比较。*/
public class Demo02StringPool {public static void main(String[] args) {String str1 = "abc";String str2 = "abc";char[] charArray = {'a', 'b', 'c'};String str3 = new String(charArray);System.out.println(str1 == str2); // trueSystem.out.println(str1 == str3); // falseSystem.out.println(str2 == str3); // false}}

6.3 字符串的比较相关方法

/*
==是进行对象的地址值比较,如果确实需要字符串的内容比较,可以使用两个方法:public boolean equals(Object obj):参数可以是任何对象,只有参数是一个字符串并且内容相同的才会给true;否则返回false。
注意事项:
1. 任何对象都能用Object进行接收。
2. equals方法具有对称性,也就是a.equals(b)和b.equals(a)效果一样。
3. 如果比较双方一个常量一个变量,推荐把常量字符串写在前面。
推荐:"abc".equals(str)    不推荐:str.equals("abc")public boolean equalsIgnoreCase(String str):忽略大小写,进行内容比较。*/
public class Demo01StringEquals {public static void main(String[] args) {String str1 = "Hello";String str2 = "Hello";char[] charArray = {'H', 'e', 'l', 'l', 'o'};String str3 = new String(charArray);System.out.println(str1.equals(str2)); // trueSystem.out.println(str2.equals(str3)); // trueSystem.out.println(str3.equals("Hello")); // trueSystem.out.println("Hello".equals(str1)); // trueString str4 = "hello";System.out.println(str1.equals(str4)); // falseSystem.out.println("=================");String str5 = null;System.out.println("abc".equals(str5)); // 推荐:false
//        System.out.println(str5.equals("abc")); // 不推荐:报错,空指针异常NullPointerExceptionSystem.out.println("=================");String strA = "Java";String strB = "java";System.out.println(strA.equals(strB)); // false,严格区分大小写System.out.println(strA.equalsIgnoreCase(strB)); // true,忽略大小写// 注意,只有英文字母区分大小写,其他都不区分大小写System.out.println("abc一123".equalsIgnoreCase("abc壹123")); // false}}

6.4 字符串的获取相关方法

/*
String当中与获取相关的常用方法有:public int length():获取字符串当中含有的字符个数,拿到字符串长度。
public String concat(String str):将当前字符串和参数字符串拼接成为返回值新的字符串。
public char charAt(int index):获取指定索引位置的单个字符。(索引从0开始。)
public int indexOf(String str):查找参数字符串在本字符串当中首次出现的索引位置,如果没有返回-1值。*/
public class Demo02StringGet {public static void main(String[] args) {// 获取字符串的长度int length = "asdasfeutrvauevbueyvb".length();System.out.println("字符串的长度是:" + length);// 拼接字符串String str1 = "Hello";String str2 = "World";String str3 = str1.concat(str2);System.out.println(str1); // Hello,原封不动System.out.println(str2); // World,原封不动System.out.println(str3); // HelloWorld,新的字符串System.out.println("==============");// 获取指定索引位置的单个字符char ch = "Hello".charAt(1);System.out.println("在1号索引位置的字符是:" + ch);System.out.println("==============");// 查找参数字符串在本来字符串当中出现的第一次索引位置// 如果根本没有,返回-1值String original = "HelloWorldHelloWorld";int index = original.indexOf("llo");System.out.println("第一次索引值是:" + index); // 2System.out.println("HelloWorld".indexOf("abc")); // -1}}

6.5 字符串的截取相关方法

/*
字符串的截取方法:public String substring(int index):截取从参数位置一直到字符串末尾,返回新字符串。
public String substring(int begin, int end):截取从begin开始,一直到end结束,中间的字符串。
备注:[begin,end),包含左边,不包含右边。*/
public class Demo03Substring {public static void main(String[] args) {String str1 = "HelloWorld";String str2 = str1.substring(5);System.out.println(str1); // HelloWorld,原封不动System.out.println(str2); // World,新字符串System.out.println("================");String str3 = str1.substring(4, 7);System.out.println(str3); // oWoSystem.out.println("================");// 下面这种写法,字符串的内容仍然是没有改变的// 下面有两个字符串:"Hello","Java"// strA当中保存的是地址值。// 本来地址值是Hello的0x666,// 后来地址值变成了Java的0x999String strA = "Hello";System.out.println(strA); // HellostrA = "Java";System.out.println(strA); // Java}}

6.6 字符串的转换相关方法

/*
String当中与转换相关的常用方法有:public char[] toCharArray():将当前字符串拆分成为字符数组作为返回值。
public byte[] getBytes():获得当前字符串底层的字节数组。
public String replace(CharSequence oldString, CharSequence newString):
将所有出现的老字符串替换成为新的字符串,返回替换之后的结果新字符串。
备注:CharSequence意思就是说可以接受字符串类型。*/
public class Demo04StringConvert {public static void main(String[] args) {// 转换成为字符数组char[] chars = "Hello".toCharArray();System.out.println(chars[0]); // HSystem.out.println(chars.length); // 5System.out.println("==============");// 转换成为字节数组byte[] bytes = "abc".getBytes();for (int i = 0; i < bytes.length; i++) {System.out.println(bytes[i]);}System.out.println("==============");// 字符串的内容替换String str1 = "How do you do?";String str2 = str1.replace("o", "*");System.out.println(str1); // How do you do?System.out.println(str2); // H*w d* y*u d*?System.out.println("==============");String lang1 = "会不会玩儿呀!的!的!的!!!";String lang2 = lang1.replace("的", "****");System.out.println(lang2); // 会不会玩儿呀!****!****!****!!!}}

6.7 字符串的分割方法

/*
分割字符串的方法:
public String[] split(String regex):按照参数的规则,将字符串切分成为若干部分。注意事项:
split方法的参数其实是一个“正则表达式”,今后学习。
今天要注意:如果按照英文句点“.”进行切分,必须写"\\."(两个反斜杠)*/
public class Demo05StringSplit {public static void main(String[] args) {String str1 = "aaa,bbb,ccc";String[] array1 = str1.split(",");for (int i = 0; i < array1.length; i++) {System.out.println(array1[i]);}System.out.println("===============");String str2 = "aaa bbb ccc";String[] array2 = str2.split(" ");for (int i = 0; i < array2.length; i++) {System.out.println(array2[i]);}System.out.println("===============");String str3 = "XXX.YYY.ZZZ";String[] array3 = str3.split("\\.");System.out.println(array3.length); // 0for (int i = 0; i < array3.length; i++) {System.out.println(array3[i]);}}}

练习 定义一个方法,把数组{1,2,3}按照指定格式拼接成一个字符串。格式参照如下:[word1#word2#word3]。

/*
题目:
定义一个方法,把数组{1,2,3}按照指定格式拼接成一个字符串。格式参照如下:[word1#word2#word3]。分析:
1. 首先准备一个int[]数组,内容是:1、2、3
2. 定义一个方法,用来将数组变成字符串
三要素
返回值类型:String
方法名称:fromArrayToString
参数列表:int[]
3. 格式:[word1#word2#word3]
用到:for循环、字符串拼接、每个数组元素之前都有一个word字样、分隔使用的是#、区分一下是不是最后一个
4. 调用方法,得到返回值,并打印结果字符串*/
public class Demo06StringPractise {public static void main(String[] args) {int[] array = {1, 2, 3, 4};String result = fromArrayToString(array);System.out.println(result);}public static String fromArrayToString(int[] array) {String str = "[";for (int i = 0; i < array.length; i++) {if (i == array.length - 1) {str += "word" + array[i] + "]";} else {str += "word" + array[i] + "#";}}return str;}}

练习 键盘输入一个字符串,并且统计其中各种字符出现的次数。

/*
题目:
键盘输入一个字符串,并且统计其中各种字符出现的次数。
种类有:大写字母、小写字母、数字、其他思路:
1. 既然用到键盘输入,肯定是Scanner
2. 键盘输入的是字符串,那么:String str = sc.next();
3. 定义四个变量,分别代表四种字符各自的出现次数。
4. 需要对字符串一个字、一个字检查,String-->char[],方法就是toCharArray()
5. 遍历char[]字符数组,对当前字符的种类进行判断,并且用四个变量进行++动作。
6. 打印输出四个变量,分别代表四种字符出现次数。*/
public class Demo07StringCount {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入一个字符串:");String input = sc.next(); // 获取键盘输入的一个字符串int countUpper = 0; // 大写字母int countLower = 0; // 小写字母int countNumber = 0; // 数字int countOther = 0; // 其他字符char[] charArray = input.toCharArray();for (int i = 0; i < charArray.length; i++) {char ch = charArray[i]; // 当前单个字符if ('A' <= ch && ch <= 'Z') {countUpper++;} else if ('a' <= ch && ch <= 'z') {countLower++;} else if ('0' <= ch && ch <= '9') {countNumber++;} else {countOther++;}}System.out.println("大写字母有:" + countUpper);System.out.println("小写字母有:" + countLower);System.out.println("数字有:" + countNumber);System.out.println("其他字符有:" + countOther);}}

7. static静态

7.1 静态static关键字修饰成员

定义学生类

public class Student {private int id; // 学号private String name; // 姓名private int age; // 年龄static String room; // 所在教室private static int idCounter = 0; // 学号计数器,每当new了一个新对象的时候,计数器++public Student() {this.id = ++idCounter;}public Student(String name, int age) {this.name = name;this.age = age;this.id = ++idCounter;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
/*
如果一个成员变量使用了static关键字,那么这个变量不再属于对象自己,而是属于所在的类。多个对象共享同一份数据。*/
public class Demo01StaticField {public static void main(String[] args) {Student two = new Student("黄蓉", 16);two.room = "101教室";System.out.println("姓名:" + two.getName()+ ",年龄:" + two.getAge() + ",教室:" + two.room+ ",学号:" + two.getId());Student one = new Student("郭靖", 19);System.out.println("姓名:" + one.getName()+ ",年龄:" + one.getAge() + ",教室:" + one.room+ ",学号:" + one.getId());}}

7.2 静态static关键字修饰成员

/*
一旦使用static修饰成员方法,那么这就成为了静态方法。静态方法不属于对象,而是属于类的。如果没有static关键字,那么必须首先创建对象,然后通过对象才能使用它。
如果有了static关键字,那么不需要创建对象,直接就能通过类名称来使用它。无论是成员变量,还是成员方法。如果有了static,都推荐使用类名称进行调用。
静态变量:类名称.静态变量
静态方法:类名称.静态方法()注意事项:
1. 静态不能直接访问非静态。
原因:因为在内存当中是【先】有的静态内容,【后】有的非静态内容。
“先人不知道后人,但是后人知道先人。”
2. 静态方法当中不能用this。
原因:this代表当前对象,通过谁调用的方法,谁就是当前对象。*/
public class Demo02StaticMethod {public static void main(String[] args) {MyClass obj = new MyClass(); // 首先创建对象// 然后才能使用没有static关键字的内容obj.method();// 对于静态方法来说,可以通过对象名进行调用,也可以直接通过类名称来调用。obj.methodStatic(); // 正确,不推荐,这种写法在编译之后也会被javac翻译成为“类名称.静态方法名”MyClass.methodStatic(); // 正确,推荐// 对于本类当中的静态方法,可以省略类名称myMethod();Demo02StaticMethod.myMethod(); // 完全等效}public static void myMethod() {System.out.println("自己的方法!");}}
public class MyClass {int num; // 成员变量static int numStatic; // 静态变量// 成员方法public void method() {System.out.println("这是一个成员方法。");// 成员方法可以访问成员变量System.out.println(num);// 成员方法可以访问静态变量System.out.println(numStatic);}// 静态方法public static void methodStatic() {System.out.println("这是一个静态方法。");// 静态方法可以访问静态变量System.out.println(numStatic);// 静态不能直接访问非静态【重点】
//        System.out.println(num); // 错误写法!// 静态方法中不能使用this关键字。
//        System.out.println(this); // 错误写法!}}

7.3 静态static的内存图

public class Demo03StaticStudent {public static void main(String[] args) {// 首先设置一下教室,这是静态的东西,应该通过类名称进行调用Student.room = "101教室";Student one = new Student("郭靖", 20);System.out.println("one的姓名:" + one.getName());System.out.println("one的年龄:" + one.getAge());System.out.println("one的教室:" + Student.room);System.out.println("============");Student two = new Student("黄蓉", 18);System.out.println("two的姓名:" + two.getName());System.out.println("two的年龄:" + two.getAge());System.out.println("two的教室:" + Student.room);}}

7.5 静态代码块

public class Person {static {System.out.println("静态代码块执行!");}public Person() {System.out.println("构造方法执行!");}}
/*
静态代码块的格式是:public class 类名称 {static {// 静态代码块的内容}
}特点:当第一次用到本类时,静态代码块执行唯一的一次。
静态内容总是优先于非静态,所以静态代码块比构造方法先执行。静态代码块的典型用途:
用来一次性地对静态成员变量进行赋值。*/
public class Demo04Static {public static void main(String[] args) {Person one = new Person();Person two = new Person();}}

8. Arrays工具类

8.1 数组工具类Arrays

import java.util.Arrays;/*
java.util.Arrays是一个与数组相关的工具类,里面提供了大量静态方法,用来实现数组常见的操作。public static String toString(数组):将参数数组变成字符串(按照默认格式:[元素1, 元素2, 元素3...])
public static void sort(数组):按照默认升序(从小到大)对数组的元素进行排序。备注:
1. 如果是数值,sort默认按照升序从小到大
2. 如果是字符串,sort默认按照字母升序
3. 如果是自定义的类型,那么这个自定义的类需要有Comparable或者Comparator接口的支持。(今后学习)*/
public class Demo01Arrays {public static void main(String[] args) {int[] intArray = {10, 20, 30};// 将int[]数组按照默认格式变成字符串String intStr = Arrays.toString(intArray);System.out.println(intStr); // [10, 20, 30]int[] array1 = {2, 1, 3, 10, 6};Arrays.sort(array1);System.out.println(Arrays.toString(array1)); // [1, 2, 3, 6, 10]String[] array2 = {"bbb", "aaa", "ccc"};Arrays.sort(array2);System.out.println(Arrays.toString(array2)); // [aaa, bbb, ccc]}}

8.2 题目:请使用Arrays相关的API,将一个随机字符串中的所有字符升序排列,并倒序打印。

import java.util.Arrays;/*
题目:
请使用Arrays相关的API,将一个随机字符串中的所有字符升序排列,并倒序打印。*/
public class Demo02ArraysPractise {public static void main(String[] args) {String str = "asv76agfqwdfvasdfvjh";// 如何进行升序排列:sort// 必须是一个数组,才能用Arrays.sort方法// String --> 数组,用toCharArraychar[] chars = str.toCharArray();Arrays.sort(chars); // 对字符数组进行升序排列// 需要倒序遍历for (int i = chars.length - 1; i >= 0; i--) {System.out.println(chars[i]);}}}

9. Math类

9.1 数学工具类Math

/*
java.util.Math类是数学相关的工具类,里面提供了大量的静态方法,完成与数学运算相关的操作。public static double abs(double num):获取绝对值。有多种重载。
public static double ceil(double num):向上取整。
public static double floor(double num):向下取整。
public static long round(double num):四舍五入。Math.PI代表近似的圆周率常量(double)。*/
public class Demo03Math {public static void main(String[] args) {// 获取绝对值System.out.println(Math.abs(3.14)); // 3.14System.out.println(Math.abs(0)); // 0System.out.println(Math.abs(-2.5)); // 2.5System.out.println("================");// 向上取整System.out.println(Math.ceil(3.9)); // 4.0System.out.println(Math.ceil(3.1)); // 4.0System.out.println(Math.ceil(3.0)); // 3.0System.out.println("================");// 向下取整,抹零System.out.println(Math.floor(30.1)); // 30.0System.out.println(Math.floor(30.9)); // 30.0System.out.println(Math.floor(31.0)); // 31.0System.out.println("================");System.out.println(Math.round(20.4)); // 20System.out.println(Math.round(10.5)); // 11}}

9.1 题目 计算在-10.8到5.9之间,绝对值大于6或者小于2.1的整数有多少个?

/*
题目:
计算在-10.8到5.9之间,绝对值大于6或者小于2.1的整数有多少个?分析:
1. 既然已经确定了范围,for循环
2. 起点位置-10.8应该转换成为-10,两种办法:2.1 可以使用Math.ceil方法,向上(向正方向)取整2.2 强转成为int,自动舍弃所有小数位
3. 每一个数字都是整数,所以步进表达式应该是num++,这样每次都是+1的。
4. 如何拿到绝对值:Math.abs方法。
5. 一旦发现了一个数字,需要让计数器++进行统计。备注:如果使用Math.ceil方法,-10.8可以变成-10.0。注意double也是可以进行++的。*/
public class Demo04MathPractise {public static void main(String[] args) {int count = 0; // 符合要求的数量double min = -10.8;double max = 5.9;// 这样处理,变量i就是区间之内所有的整数for (int i = (int) min; i < max; i++) {int abs = Math.abs(i); // 绝对值if (abs > 6 || abs < 2.1) {System.out.println(i);count++;}}System.out.println("总共有:" + count); // 9}}

第二章 继承与多态

1. 继承

1.1 继承的格式

/*
在继承的关系中,“子类就是一个父类”。也就是说,子类可以被当做父类看待。
例如父类是员工,子类是讲师,那么“讲师就是一个员工”。关系:is-a。定义父类的格式:(一个普通的类定义)
public class 父类名称 {// ...
}定义子类的格式:
public class 子类名称 extends 父类名称 {// ...
}*/
public class Demo01Extends {public static void main(String[] args) {// 创建了一个子类对象Teacher teacher = new Teacher();// Teacher类当中虽然什么都没写,但是会继承来自父类的method方法。teacher.method();// 创建另一个子类助教的对象Assistant assistant = new Assistant();assistant.method();}}

// 定义一个父类:员工

// 定义一个父类:员工
public class Employee {public void method() {System.out.println("方法执行!");}}

// 定义了员工的另一个子类:助教

// 定义了员工的另一个子类:助教
public class Assistant extends Employee {}

// 定义了一个员工的子类:讲师

// 定义了一个员工的子类:讲师
public class Teacher extends Employee {}

1.2 继承中成员变量的访问特点

public class Fu {int numFu = 10;int num = 100;public void methodFu() {// 使用的是本类当中的,不会向下找子类的System.out.println(num);}}
public class Zi extends Fu {int numZi = 20;int num = 200;public void methodZi() {// 因为本类当中有num,所以这里用的是本类的numSystem.out.println(num);}}
/*
在父子类的继承关系当中,如果成员变量重名,则创建子类对象时,访问有两种方式:直接通过子类对象访问成员变量:等号左边是谁,就优先用谁,没有则向上找。
间接通过成员方法访问成员变量:该方法属于谁,就优先用谁,没有则向上找。*/
public class Demo01ExtendsField {public static void main(String[] args) {Fu fu = new Fu(); // 创建父类对象System.out.println(fu.numFu); // 只能使用父类的东西,没有任何子类内容System.out.println("===========");Zi zi = new Zi();System.out.println(zi.numFu); // 10System.out.println(zi.numZi); // 20System.out.println("===========");// 等号左边是谁,就优先用谁System.out.println(zi.num); // 优先子类,200
//        System.out.println(zi.abc); // 到处都没有,编译报错!System.out.println("===========");// 这个方法是子类的,优先用子类的,没有再向上找zi.methodZi(); // 200// 这个方法是在父类当中定义的,zi.methodFu(); // 100}}

1.3 区分子类方法中重名的三种

public class Fu {int num = 10;}
public class Zi extends Fu {int num = 20;public void method() {int num = 30;System.out.println(num); // 30,局部变量System.out.println(this.num); // 20,本类的成员变量System.out.println(super.num); // 10,父类的成员变量}}
/*
局部变量:         直接写成员变量名
本类的成员变量:    this.成员变量名
父类的成员变量:    super.成员变量名*/
public class Demo01ExtendsField {public static void main(String[] args) {Zi zi = new Zi();zi.method();}}

1.4 继承中成员方法的访问特点

public class Fu {public void methodFu() {System.out.println("父类方法执行!");}public void method() {System.out.println("父类重名方法执行!");}}
public class Zi extends Fu {public void methodZi() {System.out.println("子类方法执行!");}public void method() {System.out.println("子类重名方法执行!");}}
/*
在父子类的继承关系当中,创建子类对象,访问成员方法的规则:创建的对象是谁,就优先用谁,如果没有则向上找。注意事项:
无论是成员方法还是成员变量,如果没有都是向上找父类,绝对不会向下找子类的。重写(Override)
概念:在继承关系当中,方法的名称一样,参数列表也一样。重写(Override):方法的名称一样,参数列表【也一样】。覆盖、覆写。
重载(Overload):方法的名称一样,参数列表【不一样】。方法的覆盖重写特点:创建的是子类对象,则优先用子类方法。*/
public class Demo01ExtendsMethod {public static void main(String[] args) {Zi zi = new Zi();zi.methodFu();zi.methodZi();// 创建的是new了子类对象,所以优先用子类方法zi.method();}}

1.5 继承中方法的覆盖重写(注解)

/*
方法覆盖重写的注意事项:1. 必须保证父子类之间方法的名称相同,参数列表也相同。
@Override:写在方法前面,用来检测是不是有效的正确覆盖重写。
这个注解就算不写,只要满足要求,也是正确的方法覆盖重写。2. 子类方法的返回值必须【小于等于】父类方法的返回值范围。
小扩展提示:java.lang.Object类是所有类的公共最高父类(祖宗类),java.lang.String就是Object的子类。3. 子类方法的权限必须【大于等于】父类方法的权限修饰符。
小扩展提示:public > protected > (default) > private
备注:(default)不是关键字default,而是什么都不写,留空。*/
public class Demo01Override {}
public class Fu {public String method() {return null;}}
public class Zi extends Fu {@Overridepublic String method() {return null;}}

1.6 继承中方法的覆盖重写(应用)

// 本来的老款手机
public class Phone {public void call() {System.out.println("打电话");}public void send() {System.out.println("发短信");}public void show() {System.out.println("显示号码");}}
// 定义一个新手机,使用老手机作为父类
public class NewPhone extends Phone {@Overridepublic void show() {super.show(); // 把父类的show方法拿过来重复利用// 自己子类再来添加更多内容System.out.println("显示姓名");System.out.println("显示头像");}
}
public class Demo01Phone {public static void main(String[] args) {Phone phone = new Phone();phone.call();phone.send();phone.show();System.out.println("==========");NewPhone newPhone = new NewPhone();newPhone.call();newPhone.send();newPhone.show();}}

1.7 继承中构造方法的访问特点

public class Fu {public Fu() {System.out.println("父类无参构造");}public Fu(int num) {System.out.println("父类有参构造!");}}
public class Zi extends Fu {public Zi() {super(); // 在调用父类无参构造方法
//        super(20); // 在调用父类重载的构造方法System.out.println("子类构造方法!");}public void method() {//        super(); // 错误写法!只有子类构造方法,才能调用父类构造方法。}}
/*
继承关系中,父子类构造方法的访问特点:1. 子类构造方法当中有一个默认隐含的“super()”调用,所以一定是先调用的父类构造,后执行的子类构造。
2. 子类构造可以通过super关键字来调用父类重载构造。
3. super的父类构造调用,必须是子类构造方法的第一个语句。不能一个子类构造调用多次super构造。
总结:
子类必须调用父类构造方法,不写则赠送super();写了则用写的指定的super调用,super只能有一个,还必须是第一个。*/
public class Demo01Constructor {public static void main(String[] args) {Zi zi = new Zi();}}

1.8 super关键字的三种用法

public class Fu {int num = 10;public void method() {System.out.println("父类方法");}}
/*
super关键字的用法有三种:
1. 在子类的成员方法中,访问父类的成员变量。
2. 在子类的成员方法中,访问父类的成员方法。
3. 在子类的构造方法中,访问父类的构造方法。*/
public class Zi extends Fu {int num = 20;public Zi() {super();}public void methodZi() {System.out.println(super.num); // 父类中的num}public void method() {super.method(); // 访问父类中的methodSystem.out.println("子类方法");}}

1.9 this关键字的三种用法

public class Fu {int num = 30;}
/*
super关键字用来访问父类内容,而this关键字用来访问本类内容。用法也有三种:1. 在本类的成员方法中,访问本类的成员变量。
2. 在本类的成员方法中,访问本类的另一个成员方法。
3. 在本类的构造方法中,访问本类的另一个构造方法。
在第三种用法当中要注意:
A. this(...)调用也必须是构造方法的第一个语句,唯一一个。
B. super和this两种构造调用,不能同时使用。*/
public class Zi extends Fu {int num = 20;public Zi() {//        super(); // 这一行不再赠送this(123); // 本类的无参构造,调用本类的有参构造
//        this(1, 2); // 错误写法!}public Zi(int n) {this(1, 2);}public Zi(int n, int m) {}public void showNum() {int num = 10;System.out.println(num); // 局部变量System.out.println(this.num); // 本类中的成员变量System.out.println(super.num); // 父类中的成员变量}public void methodA() {System.out.println("AAA");}public void methodB() {this.methodA();System.out.println("BBB");}}

1.10 super与this关键字图解

public class Fu {int num = 10;public void method() {System.out.println("父类方法");}}
public class Zi extends Fu {int num = 20;@Overridepublic void method() {super.method(); // 调用了父类方法System.out.println("子类方法");}public void show() {int num = 30;System.out.println(num); // 30System.out.println(this.num); // 20System.out.println(super.num); // 10}}
public class Demo {public static void main(String[] args) {Zi zi = new Zi();zi.show();zi.method();}}

1.11 Java继承的三个特点

2. 抽象类

2.1 抽象的概念

2.2 抽象方法和抽象类的格式

/*
抽象方法:就是加上abstract关键字,然后去掉大括号,直接分号结束。
抽象类:抽象方法所在的类,必须是抽象类才行。在class之前写上abstract即可。如何使用抽象类和抽象方法:
1. 不能直接创建new抽象类对象。
2. 必须用一个子类来继承抽象父类。
3. 子类必须覆盖重写抽象父类当中所有的抽象方法。
覆盖重写(实现):子类去掉抽象方法的abstract关键字,然后补上方法体大括号。
4. 创建子类对象进行使用。*/
public abstract class Animal {// 这是一个抽象方法,代表吃东西,但是具体吃什么(大括号的内容)不确定。public abstract void eat();// 这是普通的成员方法
//    public void normalMethod() {//
//    }}

2.3 抽象方法和抽象类的使用

public class DemoMain {public static void main(String[] args) {//        Animal animal = new Animal(); // 错误写法!不能直接创建抽象类对象Cat cat = new Cat();cat.eat();}}
public class Cat extends Animal {@Overridepublic void eat() {System.out.println("猫吃鱼");}
}

2.4 抽象方法和抽象类的注意事项

public abstract class Fu {public Fu() {System.out.println("抽象父类构造方法执行!");}public abstract void eat();}
public class Zi extends Fu {public Zi() {// super();System.out.println("子类构造方法执行");}@Overridepublic void eat() {System.out.println("吃饭饭");}
}
public class DemoMain {public static void main(String[] args) {Zi zi = new Zi();zi.eat();}}
/*
一个抽象类不一定含有抽象方法,
只要保证抽象方法所在的类是抽象类,即可。这样没有抽象方法的抽象类,也不能直接创建对象,在一些特殊场景下有用途。*/
public abstract class MyAbstract {}




// 最高的抽象父类

// 最高的抽象父类
public abstract class Animal {public abstract void eat();public abstract void sleep();}

// 子类也是一个抽象类

// 子类也是一个抽象类
public abstract class Dog extends Animal {@Overridepublic void eat() {System.out.println("狗吃骨头");}// public abstract void sleep();
}

//金毛

public class DogGolden extends Dog {@Overridepublic void sleep() {System.out.println("呼呼呼……");}
}

//2哈

public class Dog2Ha extends Dog {@Overridepublic void sleep() {System.out.println("嘿嘿嘿……");}
}
public class DemoMain {public static void main(String[] args) {//        Animal animal = new Animal(); // 错误!//        Dog dog = new Dog(); // 错误,这也是抽象类Dog2Ha ha = new Dog2Ha(); // 这是普通类,可以直接new对象。ha.eat();ha.sleep();System.out.println("==========");DogGolden golden = new DogGolden();golden.eat();golden.sleep();}
}

2.5 发红包案例


public class User {private String name; // 姓名private int money; // 余额,也就是当前用户拥有的钱数public User() {}public User(String name, int money) {this.name = name;this.money = money;}// 展示一下当前用户有多少钱public void show() {System.out.println("我叫:" + name + ",我有多少钱:" + money);}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getMoney() {return money;}public void setMoney(int money) {this.money = money;}
}
import java.util.ArrayList;// 群主的类
public class Manager extends User {public Manager() {}public Manager(String name, int money) {super(name, money);}public ArrayList<Integer> send(int totalMoney, int count) {// 首先需要一个集合,用来存储若干个红包的金额ArrayList<Integer> redList = new ArrayList<>();// 首先看一下群主自己有多少钱int leftMoney = super.getMoney(); // 群主当前余额if (totalMoney > leftMoney) {System.out.println("余额不足");return redList; // 返回空集合}// 扣钱,其实就是重新设置余额super.setMoney(leftMoney - totalMoney);// 发红包需要平均拆分成为count份int avg = totalMoney / count;int mod = totalMoney % count; // 余数,也就是甩下的零头// 除不开的零头,包在最后一个红包当中// 下面把红包一个一个放到集合当中for (int i = 0; i < count - 1; i++) {redList.add(avg);}// 最后一个红包int last = avg + mod;redList.add(last);return redList;}
}
import java.util.ArrayList;
import java.util.Random;// 普通成员
public class Member extends User {public Member() {}public Member(String name, int money) {super(name, money);}public void receive(ArrayList<Integer> list) {// 从多个红包当中随便抽取一个,给我自己。// 随机获取一个集合当中的索引编号int index = new Random().nextInt(list.size());// 根据索引,从集合当中删除,并且得到被删除的红包,给我自己int delta = list.remove(index);// 当前成员自己本来有多少钱:int money = super.getMoney();// 加法,并且重新设置回去super.setMoney(money + delta);}
}
import java.util.ArrayList;public class MainRedPacket {public static void main(String[] args) {Manager manager = new Manager("群主", 100);Member one = new Member("成员A", 0);Member two = new Member("成员B", 0);Member three = new Member("成员C", 0);manager.show(); // 100one.show(); // 0two.show(); // 0three.show(); // 0System.out.println("===============");// 群主总共发20块钱,分成3个红包ArrayList<Integer> redList = manager.send(20, 3);// 三个普通成员收红包one.receive(redList);two.receive(redList);three.receive(redList);manager.show(); // 100-20=80// 6、6、8,随机分给三个人one.show();two.show();three.show();}}

3. 接口

3.1 接口的定义基本格式

/*
接口就是多个类的公共规范。
接口是一种引用数据类型,最重要的内容就是其中的:抽象方法。如何定义一个接口的格式:
public interface 接口名称 {// 接口内容
}备注:换成了关键字interface之后,编译生成的字节码文件仍然是:.java --> .class。如果是Java 7,那么接口中可以包含的内容有:
1. 常量
2. 抽象方法如果是Java 8,还可以额外包含有:
3. 默认方法
4. 静态方法如果是Java 9,还可以额外包含有:
5. 私有方法*/
public class Demo01Interface {public static void main(String[] args) {// 错误写法!不能直接new接口对象使用。
//        MyInterfaceAbstract inter = new MyInterfaceAbstract();// 创建实现类的对象使用MyInterfaceAbstractImpl impl = new MyInterfaceAbstractImpl();impl.methodAbs1();impl.methodAbs2();}}

接口

/*
在任何版本的Java中,接口都能定义抽象方法。
格式:
public abstract 返回值类型 方法名称(参数列表);注意事项:
1. 接口当中的抽象方法,修饰符必须是两个固定的关键字:public abstract
2. 这两个关键字修饰符,可以选择性地省略。(今天刚学,所以不推荐。)
3. 方法的三要素,可以随意定义。*/
public interface MyInterfaceAbstract {// 这是一个抽象方法public abstract void methodAbs1();// 这也是抽象方法abstract void methodAbs2();// 这也是抽象方法public void methodAbs3();// 这也是抽象方法void methodAbs4();}

3.2 接口的抽象方法使用


/*
接口使用步骤:
1. 接口不能直接使用,必须有一个“实现类”来“实现”该接口。
格式:
public class 实现类名称 implements 接口名称 {// ...
}
2. 接口的实现类必须覆盖重写(实现)接口中所有的抽象方法。
实现:去掉abstract关键字,加上方法体大括号。
3. 创建实现类的对象,进行使用。注意事项:
如果实现类并没有覆盖重写接口中所有的抽象方法,那么这个实现类自己就必须是抽象类。*/
public class Demo01Interface {public static void main(String[] args) {// 错误写法!不能直接new接口对象使用。
//        MyInterfaceAbstract inter = new MyInterfaceAbstract();// 创建实现类的对象使用MyInterfaceAbstractImpl impl = new MyInterfaceAbstractImpl();impl.methodAbs1();impl.methodAbs2();}}
public class MyInterfaceAbstractImpl implements MyInterfaceAbstract {@Overridepublic void methodAbs1() {System.out.println("这是第一个方法!");}@Overridepublic void methodAbs2() {System.out.println("这是第二个方法!");}@Overridepublic void methodAbs3() {System.out.println("这是第三个方法!");}@Overridepublic void methodAbs4() {System.out.println("这是第四个方法!");}
}

3.3 接口的默认方法定义和使用

/*
从Java 8开始,接口里允许定义默认方法。
格式:
public default 返回值类型 方法名称(参数列表) {方法体
}备注:接口当中的默认方法,可以解决接口升级的问题。*/
public interface MyInterfaceDefault {// 抽象方法public abstract void methodAbs();// 新添加了一个抽象方法
//    public abstract void methodAbs2();// 新添加的方法,改成默认方法public default void methodDefault() {System.out.println("这是新添加的默认方法");}}
public class MyInterfaceDefaultA implements MyInterfaceDefault {@Overridepublic void methodAbs() {System.out.println("实现了抽象方法,AAA");}
}
public class MyInterfaceDefaultB implements MyInterfaceDefault {@Overridepublic void methodAbs() {System.out.println("实现了抽象方法,BBB");}@Overridepublic void methodDefault() {System.out.println("实现类B覆盖重写了接口的默认方法");}
}
/*
1. 接口的默认方法,可以通过接口实现类对象,直接调用。
2. 接口的默认方法,也可以被接口实现类进行覆盖重写。*/
public class Demo02Interface {public static void main(String[] args) {// 创建了实现类对象MyInterfaceDefaultA a = new MyInterfaceDefaultA();a.methodAbs(); // 调用抽象方法,实际运行的是右侧实现类。// 调用默认方法,如果实现类当中没有,会向上找接口a.methodDefault(); // 这是新添加的默认方法System.out.println("==========");MyInterfaceDefaultB b = new MyInterfaceDefaultB();b.methodAbs();b.methodDefault(); // 实现类B覆盖重写了接口的默认方法}}

3.4 接口的静态方法定义和使用

/*
从Java 8开始,接口当中允许定义静态方法。
格式:
public static 返回值类型 方法名称(参数列表) {方法体
}
提示:就是将abstract或者default换成static即可,带上方法体。*/
public interface MyInterfaceStatic {public static void methodStatic() {System.out.println("这是接口的静态方法!");}}
/*
注意事项:不能通过接口实现类的对象来调用接口当中的静态方法。
正确用法:通过接口名称,直接调用其中的静态方法。
格式:
接口名称.静态方法名(参数);*/
public class Demo03Interface {public static void main(String[] args) {// 创建了实现类对象MyInterfaceStaticImpl impl = new MyInterfaceStaticImpl();// 错误写法!
//        impl.methodStatic();// 直接通过接口名称调用静态方法MyInterfaceStatic.methodStatic();}}

3.5 接口的私有方法定义和使用

/*
问题描述:
我们需要抽取一个共有方法,用来解决两个默认方法之间重复代码的问题。
但是这个共有方法不应该让实现类使用,应该是私有化的。解决方案:
从Java 9开始,接口当中允许定义私有方法。
1. 普通私有方法,解决多个默认方法之间重复代码问题
格式:
private 返回值类型 方法名称(参数列表) {方法体
}2. 静态私有方法,解决多个静态方法之间重复代码问题
格式:
private static 返回值类型 方法名称(参数列表) {方法体
}*/
public interface MyInterfacePrivateA {public default void methodDefault1() {System.out.println("默认方法1");methodCommon();}public default void methodDefault2() {System.out.println("默认方法2");methodCommon();}private void methodCommon() {System.out.println("AAA");System.out.println("BBB");System.out.println("CCC");}}
public interface MyInterfacePrivateB {public static void methodStatic1() {System.out.println("静态方法1");methodStaticCommon();}public static void methodStatic2() {System.out.println("静态方法2");methodStaticCommon();}private static void methodStaticCommon() {System.out.println("AAA");System.out.println("BBB");System.out.println("CCC");}}
public class MyInterfacePrivateAImpl implements MyInterfacePrivateA {public void methodAnother() {// 直接访问到了接口中的默认方法,这样是错误的!
//        methodCommon();}}
public class Demo04Interface {public static void main(String[] args) {MyInterfacePrivateB.methodStatic1();MyInterfacePrivateB.methodStatic2();// 错误写法!
//        MyInterfacePrivateB.methodStaticCommon();}
}

3.6 接口的常量定义和使用

/*
接口当中也可以定义“成员变量”,但是必须使用public static final三个关键字进行修饰。
从效果上看,这其实就是接口的【常量】。
格式:
public static final 数据类型 常量名称 = 数据值;
备注:
一旦使用final关键字进行修饰,说明不可改变。注意事项:
1. 接口当中的常量,可以省略public static final,注意:不写也照样是这样。
2. 接口当中的常量,必须进行赋值;不能不赋值。
3. 接口中常量的名称,使用完全大写的字母,用下划线进行分隔。(推荐命名规则)*/
public interface MyInterfaceConst {// 这其实就是一个常量,一旦赋值,不可以修改public static final int NUM_OF_MY_CLASS = 12;}

3.7 接口的内容小结

在Java 9+版本中,接口的内容可以有:

  1. 成员变量其实是常量,格式: [public] [static] [final] 数据类型 常量名称 = 数据值; 注意: 常量必须进行赋值,而且一旦赋值不能改变。 常量名称完全大写,用下划线进行分隔。

  2. 接口中最重要的就是抽象方法,格式: [public] [abstract] 返回值类型 方法名称(参数列表); 注意:实现类必须覆盖重写接口所有的抽象方法,除非实现类是抽象类。

  3. 从Java 8开始,接口里允许定义默认方法,格式: [public] default 返回值类型 方法名称(参数列表) { 方法体 } 注意:默认方法也可以被覆盖重写

  4. 从Java 8开始,接口里允许定义静态方法,格式: [public] static 返回值类型 方法名称(参数列表) { 方法体 } 注意:应该通过接口名称进行调用,不能通过实现类对象调用接口静态方法

  5. 从Java 9开始,接口里允许定义私有很乏,格式: 普通私有方法:private 返回值类型 方法名称(参数列表) { 方法体 } 静态私有方法:private static 返回值类型 方法名称(参数列表) { 方法体 }
    注意:private的方法只有接口自己才能调用,不能被实现类或别人使用。

3.8 继承父类并实现多个接口

/*
使用接口的时候,需要注意:1. 接口是没有静态代码块或者构造方法的。
2. 一个类的直接父类是唯一的,但是一个类可以同时实现多个接口。
格式:
public class MyInterfaceImpl implements MyInterfaceA, MyInterfaceB {// 覆盖重写所有抽象方法
}
3. 如果实现类所实现的多个接口当中,存在重复的抽象方法,那么只需要覆盖重写一次即可。
4. 如果实现类没有覆盖重写所有接口当中的所有抽象方法,那么实现类就必须是一个抽象类。
5. 如果实现类锁实现的多个接口当中,存在重复的默认方法,那么实现类一定要对冲突的默认方法进行覆盖重写。
6. 一个类如果直接父类当中的方法,和接口当中的默认方法产生了冲突,优先用父类当中的方法。*/
public class Demo01Interface {public static void main(String[] args) {Zi zi = new Zi();zi.method();}}
public interface MyInterface {public default void method() {System.out.println("接口的默认方法");}}
public interface MyInterfaceA {// 错误写法!接口不能有静态代码块
//    static {//
//    }// 错误写法!接口不能有构造方法
//    public MyInterfaceA() {//
//    }public abstract void methodA();public abstract void methodAbs();public default void methodDefault() {System.out.println("默认方法AAA");}}
public interface MyInterfaceB {// 错误写法!接口不能有静态代码块
//    static {//
//    }// 错误写法!接口不能有构造方法
//    public MyInterfaceA() {//
//    }public abstract void methodB();public abstract void methodAbs();public default void methodDefault() {System.out.println("默认方法BBB");}}
public class Fu {public void method() {System.out.println("父类方法");}}
public class Zi extends Fu implements MyInterface {}

3.9 接口之间的多继承

/*
1. 类与类之间是单继承的。直接父类只有一个。
2. 类与接口之间是多实现的。一个类可以实现多个接口。
3. 接口与接口之间是多继承的。注意事项:
1. 多个父接口当中的抽象方法如果重复,没关系。
2. 多个父接口当中的默认方法如果重复,那么子接口必须进行默认方法的覆盖重写,【而且带着default关键字】。*/
public class Demo01Relations {}
/*
这个子接口当中有几个方法?答:4个。
methodA 来源于接口A
methodB 来源于接口B
methodCommon 同时来源于接口A和B
method 来源于我自己*/
public interface MyInterface extends MyInterfaceA, MyInterfaceB {public abstract void method();@Overridepublic default void methodDefault() {}
}
public interface MyInterfaceA {public abstract void methodA();public abstract void methodCommon();public default void methodDefault() {System.out.println("AAA");}}
public interface MyInterfaceB {public abstract void methodB();public abstract void methodCommon();public default void methodDefault() {System.out.println("BBB");}}
public class MyInterfaceImpl implements MyInterface {@Overridepublic void method() {}@Overridepublic void methodA() {}@Overridepublic void methodB() {}@Overridepublic void methodCommon() {}
}

4. 多态

4.1 多态的格式和使用

/*
代码当中体现多态性,其实就是一句话:父类引用指向子类对象。格式:
父类名称 对象名 = new 子类名称();
或者:
接口名称 对象名 = new 实现类名称();*/
public class Demo01Multi {public static void main(String[] args) {// 使用多态的写法// 左侧父类的引用,指向了右侧子类的对象Fu obj = new Zi();obj.method();obj.methodFu();}
}
public class Fu {public void method() {System.out.println("父类方法");}public void methodFu() {System.out.println("父类特有方法");}}
public class Zi extends Fu {@Overridepublic void method() {System.out.println("子类方法");}
}

4.2 多态中成员变量方法的使用特点

public class Fu /*extends Object*/ {int num = 10;public void showNum() {System.out.println(num);}public void method() {System.out.println("父类方法");}public void methodFu() {System.out.println("父类特有方法");}}
public class Zi extends Fu {int num = 20;int age = 16;@Overridepublic void showNum() {System.out.println(num);}@Overridepublic void method() {System.out.println("子类方法");}public void methodZi() {System.out.println("子类特有方法");}
}
/*
访问成员变量的两种方式:1. 直接通过对象名称访问成员变量:看等号左边是谁,优先用谁,没有则向上找。
2. 间接通过成员方法访问成员变量:看该方法属于谁,优先用谁,没有则向上找。*/
public class Demo01MultiField {public static void main(String[] args) {// 使用多态的写法,父类引用指向子类对象Fu obj = new Zi();System.out.println(obj.num); // 父:10
//        System.out.println(obj.age); // 错误写法!System.out.println("=============");// 子类没有覆盖重写,就是父:10// 子类如果覆盖重写,就是子:20obj.showNum();}}
/*
在多态的代码当中,成员方法的访问规则是:看new的是谁,就优先用谁,没有则向上找。口诀:编译看左边,运行看右边。对比一下:
成员变量:编译看左边,运行还看左边。
成员方法:编译看左边,运行看右边。*/
public class Demo02MultiMethod {public static void main(String[] args) {Fu obj = new Zi(); // 多态obj.method(); // 父子都有,优先用子obj.methodFu(); // 子类没有,父类有,向上找到父类// 编译看左边,左边是Fu,Fu当中没有methodZi方法,所以编译报错。
//        obj.methodZi(); // 错误写法!}}

4.3 使用多态的好处

4.4 对象的向上转型

public abstract class Animal {public abstract void eat();}
public class Cat extends Animal {@Overridepublic void eat() {System.out.println("猫吃鱼");}// 子类特有方法public void catchMouse() {System.out.println("猫抓老鼠");}
}
/*
向上转型一定是安全的,没有问题的,正确的。但是也有一个弊端:
对象一旦向上转型为父类,那么就无法调用子类原本特有的内容。解决方案:用对象的向下转型【还原】。*/
public class Demo01Main {public static void main(String[] args) {// 对象的向上转型,就是:父类引用指向子类对象。Animal animal = new Cat(); // 本来创建的时候是一只猫animal.eat(); // 猫吃鱼//        animal.catchMouse(); // 错误写法!// 向下转型,进行“还原”动作Cat cat = (Cat) animal;cat.catchMouse(); // 猫抓老鼠// 下面是错误的向下转型// 本来new的时候是一只猫,现在非要当做狗// 错误写法!编译不会报错,但是运行会出现异常:// java.lang.ClassCastException,类转换异常Dog dog = (Dog) animal;}}
public class Dog extends Animal {@Overridepublic void eat() {System.out.println("狗吃SHIT");}public void watchHouse() {System.out.println("狗看家");}
}

4.5 对象的向下转型

/*
向上转型一定是安全的,没有问题的,正确的。但是也有一个弊端:
对象一旦向上转型为父类,那么就无法调用子类原本特有的内容。解决方案:用对象的向下转型【还原】。*/
public class Demo01Main {public static void main(String[] args) {// 对象的向上转型,就是:父类引用指向子类对象。Animal animal = new Cat(); // 本来创建的时候是一只猫animal.eat(); // 猫吃鱼//        animal.catchMouse(); // 错误写法!// 向下转型,进行“还原”动作Cat cat = (Cat) animal;cat.catchMouse(); // 猫抓老鼠// 下面是错误的向下转型// 本来new的时候是一只猫,现在非要当做狗// 错误写法!编译不会报错,但是运行会出现异常:// java.lang.ClassCastException,类转换异常Dog dog = (Dog) animal;}}

4.6 用instanceof关键字进行

/*
如何才能知道一个父类引用的对象,本来是什么子类?
格式:
对象 instanceof 类名称
这将会得到一个boolean值结果,也就是判断前面的对象能不能当做后面类型的实例。*/
public class Demo02Instanceof {public static void main(String[] args) {Animal animal = new Dog(); // 本来是一只狗animal.eat(); // 狗吃SHIT// 如果希望掉用子类特有方法,需要向下转型// 判断一下父类引用animal本来是不是Dogif (animal instanceof Dog) {Dog dog = (Dog) animal;dog.watchHouse();}// 判断一下animal本来是不是Catif (animal instanceof Cat) {Cat cat = (Cat) animal;cat.catchMouse();}giveMeAPet(new Dog());}public static void giveMeAPet(Animal animal) {if (animal instanceof Dog) {Dog dog = (Dog) animal;dog.watchHouse();}if (animal instanceof Cat) {Cat cat = (Cat) animal;cat.catchMouse();}}}

4.7 笔记本USB案例

public interface USB {public abstract void open(); // 打开设备public abstract void close(); // 关闭设备}
public class Computer {public void powerOn() {System.out.println("笔记本电脑开机");}public void powerOff() {System.out.println("笔记本电脑关机");}// 使用USB设备的方法,使用接口作为方法的参数public void useDevice(USB usb) {usb.open(); // 打开设备if (usb instanceof Mouse) { // 一定要先判断Mouse mouse = (Mouse) usb; // 向下转型mouse.click();} else if (usb instanceof Keyboard) { // 先判断Keyboard keyboard = (Keyboard) usb; // 向下转型keyboard.type();}usb.close(); // 关闭设备}}
// 鼠标就是一个USB设备
public class Mouse implements USB {@Overridepublic void open() {System.out.println("打开鼠标");}@Overridepublic void close() {System.out.println("关闭鼠标");}public void click() {System.out.println("鼠标点击");}
}
// 键盘就是一个USB设备
public class Keyboard implements USB {@Overridepublic void open() {System.out.println("打开键盘");}@Overridepublic void close() {System.out.println("关闭键盘");}public void type() {System.out.println("键盘输入");}
}
public class DemoMain {public static void main(String[] args) {// 首先创建一个笔记本电脑Computer computer = new Computer();computer.powerOn();// 准备一个鼠标,供电脑使用
//        Mouse mouse = new Mouse();// 首先进行向上转型USB usbMouse = new Mouse(); // 多态写法// 参数是USB类型,我正好传递进去的就是USB鼠标computer.useDevice(usbMouse);// 创建一个USB键盘Keyboard keyboard = new Keyboard(); // 没有使用多态写法// 方法参数是USB类型,传递进去的是实现类对象computer.useDevice(keyboard); // 正确写法!也发生了向上转型// 使用子类对象,匿名对象,也可以
//        computer.useDevice(new Keyboard()); // 也是正确写法computer.powerOff();System.out.println("==================");method(10.0); // 正确写法,double --> doublemethod(20); // 正确写法,int --> doubleint a = 30;method(a); // 正确写法,int --> double}public static void method(double num) {System.out.println(num);}}

5. final关键字

5.1 final关键字用于修饰类

/*
当final关键字用来修饰一个类的时候,格式:
public final class 类名称 {// ...
}含义:当前这个类不能有任何的子类。(太监类)
注意:一个类如果是final的,那么其中所有的成员方法都无法进行覆盖重写(因为没儿子。)*/
public final class MyClass /*extends Object*/ {public void method() {System.out.println("方法执行!");}}
// 不能使用一个final类来作为父类
public class MySubClass /*extends MyClass*/ {}

5.2 final关键字用于修饰成员方法

/*
当final关键字用来修饰一个方法的时候,这个方法就是最终方法,也就是不能被覆盖重写。
格式:
修饰符 final 返回值类型 方法名称(参数列表) {// 方法体
}注意事项:
对于类、方法来说,abstract关键字和final关键字不能同时使用,因为矛盾。*/
public abstract class Fu {public final void method() {System.out.println("父类方法执行!");}public abstract /*final*/ void methodAbs() ;
}
public class Zi extends Fu {@Overridepublic void methodAbs() {}// 错误写法!不能覆盖重写父类当中final的方法
//    @Override
//    public void method() {//        System.out.println("子类覆盖重写父类的方法!");
//    }
}

5.3 final关键字用于修饰局部变量

public class Student {private String name;public Student() {}public Student(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
/*
final关键字代表最终、不可改变的。常见四种用法:
1. 可以用来修饰一个类
2. 可以用来修饰一个方法
3. 还可以用来修饰一个局部变量
4. 还可以用来修饰一个成员变量*/
public class Demo01Final {public static void main(String[] args) {int num1 = 10;System.out.println(num1); // 10num1 = 20;System.out.println(num1); // 20// 一旦使用final用来修饰局部变量,那么这个变量就不能进行更改。// “一次赋值,终生不变”final int num2 = 200;System.out.println(num2); // 200//        num2 = 250; // 错误写法!不能改变!
//        num2 = 200; // 错误写法!// 正确写法!只要保证有唯一一次赋值即可final int num3;num3 = 30;// 对于基本类型来说,不可变说的是变量当中的数据不可改变// 对于引用类型来说,不可变说的是变量当中的地址值不可改变Student stu1 = new Student("赵丽颖");System.out.println(stu1);System.out.println(stu1.getName()); // 赵丽颖stu1 = new Student("霍建华");System.out.println(stu1);System.out.println(stu1.getName()); // 霍建华System.out.println("===============");final Student stu2 = new Student("高圆圆");// 错误写法!final的引用类型变量,其中的地址不可改变
//        stu2 = new Student("赵又廷");System.out.println(stu2.getName()); // 高圆圆stu2.setName("高圆圆圆圆圆圆");System.out.println(stu2.getName()); // 高圆圆圆圆圆圆}}

5.4 final关键字用于修饰成员

/*
对于成员变量来说,如果使用final关键字修饰,那么这个变量也照样是不可变。1. 由于成员变量具有默认值,所以用了final之后必须手动赋值,不会再给默认值了。
2. 对于final的成员变量,要么使用直接赋值,要么通过构造方法赋值。二者选其一。
3. 必须保证类当中所有重载的构造方法,都最终会对final的成员变量进行赋值。*/
public class Person {private final String name/* = "鹿晗"*/;public Person() {name = "关晓彤";}public Person(String name) {this.name = name;}public String getName() {return name;}//    public void setName(String name) {//        this.name = name;
//    }
}

6. 权限修饰符

/*
Java中有四种权限修饰符:public  >   protected   >   (default)   >   private
同一个类(我自己)        YES         YES             YES             YES
同一个包(我邻居)        YES         YES             YES             NO
不同包子类(我儿子)       YES         YES             NO              NO
不同包非子类(陌生人)      YES         NO              NO              NO注意事项:(default)并不是关键字“default”,而是根本不写。*/
public class Demo01Main {}
public class MyClass {public int num = 10;public void method() {System.out.println(num);}}
public class MyAnother {public void anotherMethod() {//        System.out.println(new MyClass().num);}}
import demo02.MyClass;public class MySon extends MyClass {public void methodSon() {//        System.out.println(super.num);}}
import demo02.MyClass;public class Stranger {public void methodStrange() {System.out.println(new MyClass().num);}}

7. 内部类

7.1 成员内部类的定义

/*
如果一个事物的内部包含另一个事物,那么这就是一个类内部包含另一个类。
例如:身体和心脏的关系。又如:汽车和发动机的关系。分类:
1. 成员内部类
2. 局部内部类(包含匿名内部类)成员内部类的定义格式:
修饰符 class 外部类名称 {修饰符 class 内部类名称 {// ...}// ...
}注意:内用外,随意访问;外用内,需要内部类对象。*/
public class Demo01InnerClass {public static void main(String[] args) {Body body = new Body(); // 外部类的对象// 通过外部类的对象,调用外部类的方法,里面间接在使用内部类Heartbody.methodBody();System.out.println("=====================");// 按照公式写:Body.Heart heart = new Body().new Heart();heart.beat();}}
public class Body { // 外部类public class Heart { // 成员内部类// 内部类的方法public void beat() {System.out.println("心脏跳动:蹦蹦蹦!");System.out.println("我叫:" + name); // 正确写法!}}// 外部类的成员变量private String name;// 外部类的方法public void methodBody() {System.out.println("外部类的方法");new Heart().beat();}public String getName() {return name;}public void setName(String name) {this.name = name;}
}

7.2 成员内部类的使用

/*
如何使用成员内部类?有两种方式:
1. 间接方式:在外部类的方法当中,使用内部类;然后main只是调用外部类的方法。
2. 直接方式,公式:
类名称 对象名 = new 类名称();
【外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();】*/
public class Demo01InnerClass {public static void main(String[] args) {Body body = new Body(); // 外部类的对象// 通过外部类的对象,调用外部类的方法,里面间接在使用内部类Heartbody.methodBody();System.out.println("=====================");// 按照公式写:Body.Heart heart = new Body().new Heart();heart.beat();}}

7.3 内部类的同名变量访问

// 如果出现了重名现象,那么格式是:外部类名称.this.外部类成员变量名
public class Outer {int num = 10; // 外部类的成员变量public class Inner /*extends Object*/ {int num = 20; // 内部类的成员变量public void methodInner() {int num = 30; // 内部类方法的局部变量System.out.println(num); // 局部变量,就近原则System.out.println(this.num); // 内部类的成员变量System.out.println(Outer.this.num); // 外部类的成员变量}}}
public class Demo02InnerClass {public static void main(String[] args) {// 外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();Outer.Inner obj = new Outer().new Inner();obj.methodInner();}}

7.4 局部内部类定义

/*
如果一个类是定义在一个方法内部的,那么这就是一个局部内部类。
“局部”:只有当前所属的方法才能使用它,出了这个方法外面就不能用了。定义格式:
修饰符 class 外部类名称 {修饰符 返回值类型 外部类方法名称(参数列表) {class 局部内部类名称 {// ...}}
}小节一下类的权限修饰符:
public > protected > (default) > private
定义一个类的时候,权限修饰符规则:
1. 外部类:public / (default)
2. 成员内部类:public / protected / (default) / private
3. 局部内部类:什么都不能写*/
class Outer {public void methodOuter() {class Inner { // 局部内部类int num = 10;public void methodInner() {System.out.println(num); // 10}}Inner inner = new Inner();inner.methodInner();}}
public class DemoMain {public static void main(String[] args) {Outer obj = new Outer();obj.methodOuter();}}

7.5 局部内部类final问题

/*
局部内部类,如果希望访问所在方法的局部变量,那么这个局部变量必须是【有效final的】。备注:从Java 8+开始,只要局部变量事实不变,那么final关键字可以省略。原因:
1. new出来的对象在堆内存当中。
2. 局部变量是跟着方法走的,在栈内存当中。
3. 方法运行结束之后,立刻出栈,局部变量就会立刻消失。
4. 但是new出来的对象会在堆当中持续存在,直到垃圾回收消失。*/
public class MyOuter {public void methodOuter() {int num = 10; // 所在方法的局部变量class MyInner {public void methodInner() {System.out.println(num);}}}}

7.6 匿名内部类及注意事项

public interface MyInterface {void method1(); // 抽象方法void method2();}
public class MyInterfaceImpl implements MyInterface {@Overridepublic void method1() {System.out.println("实现类覆盖重写了方法!111");}@Overridepublic void method2() {System.out.println("实现类覆盖重写了方法!222");}
}
/*
如果接口的实现类(或者是父类的子类)只需要使用唯一的一次,
那么这种情况下就可以省略掉该类的定义,而改为使用【匿名内部类】。匿名内部类的定义格式:
接口名称 对象名 = new 接口名称() {// 覆盖重写所有抽象方法
};对格式“new 接口名称() {...}”进行解析:
1. new代表创建对象的动作
2. 接口名称就是匿名内部类需要实现哪个接口
3. {...}这才是匿名内部类的内容另外还要注意几点问题:
1. 匿名内部类,在【创建对象】的时候,只能使用唯一一次。
如果希望多次创建对象,而且类的内容一样的话,那么就需要使用单独定义的实现类了。
2. 匿名对象,在【调用方法】的时候,只能调用唯一一次。
如果希望同一个对象,调用多次方法,那么必须给对象起个名字。
3. 匿名内部类是省略了【实现类/子类名称】,但是匿名对象是省略了【对象名称】
强调:匿名内部类和匿名对象不是一回事!!!*/
public class DemoMain {public static void main(String[] args) {//        MyInterface obj = new MyInterfaceImpl();
//        obj.method();//        MyInterface some = new MyInterface(); // 错误写法!// 使用匿名内部类,但不是匿名对象,对象名称就叫objAMyInterface objA = new MyInterface() {@Overridepublic void method1() {System.out.println("匿名内部类实现了方法!111-A");}@Overridepublic void method2() {System.out.println("匿名内部类实现了方法!222-A");}};objA.method1();objA.method2();System.out.println("=================");// 使用了匿名内部类,而且省略了对象名称,也是匿名对象new MyInterface() {@Overridepublic void method1() {System.out.println("匿名内部类实现了方法!111-B");}@Overridepublic void method2() {System.out.println("匿名内部类实现了方法!222-B");}}.method1();// 因为匿名对象无法调用第二次方法,所以需要再创建一个匿名内部类的匿名对象new MyInterface() {@Overridepublic void method1() {System.out.println("匿名内部类实现了方法!111-B");}@Overridepublic void method2() {System.out.println("匿名内部类实现了方法!222-B");}}.method2();}}

7.7 类作为成员变量类型

// 游戏当中的英雄角色类
public class Hero {private String name; // 英雄的名字private int age; // 英雄的年龄private Weapon weapon; // 英雄的武器public Hero() {}public Hero(String name, int age, Weapon weapon) {this.name = name;this.age = age;this.weapon = weapon;}public void attack() {System.out.println("年龄为" + age + "的" + name + "用" + weapon.getCode() + "攻击敌方。");}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Weapon getWeapon() {return weapon;}public void setWeapon(Weapon weapon) {this.weapon = weapon;}
}
public class Weapon {private String code; // 武器的代号public Weapon() {}public Weapon(String code) {this.code = code;}public String getCode() {return code;}public void setCode(String code) {this.code = code;}
}
public class DemoMain {public static void main(String[] args) {// 创建一个英雄角色Hero hero = new Hero();// 为英雄起一个名字,并且设置年龄hero.setName("盖伦");hero.setAge(20);// 创建一个武器对象Weapon weapon = new Weapon("AK-47");// 为英雄配备武器hero.setWeapon(weapon);// 年龄为20的盖伦用多兰剑攻击敌方。hero.attack();}}

7.8 接口作为成员变量类型

public class Hero {private String name; // 英雄的名称private Skill skill; // 英雄的技能public Hero() {}public Hero(String name, Skill skill) {this.name = name;this.skill = skill;}public void attack() {System.out.println("我叫" + name + ",开始施放技能:");skill.use(); // 调用接口中的抽象方法System.out.println("施放技能完成。");}public String getName() {return name;}public void setName(String name) {this.name = name;}public Skill getSkill() {return skill;}public void setSkill(Skill skill) {this.skill = skill;}
}
public interface Skill {void use(); // 释放技能的抽象方法}
public class SkillImpl implements Skill {@Overridepublic void use() {System.out.println("Biu~biu~biu~");}
}
public class DemoGame {public static void main(String[] args) {Hero hero = new Hero();hero.setName("艾希"); // 设置英雄的名称// 设置英雄技能
//        hero.setSkill(new SkillImpl()); // 使用单独定义的实现类// 还可以改成使用匿名内部类
//        Skill skill = new Skill() {//            @Override
//            public void use() {//                System.out.println("Pia~pia~pia~");
//            }
//        };
//        hero.setSkill(skill);// 进一步简化,同时使用匿名内部类和匿名对象hero.setSkill(new Skill() {@Overridepublic void use() {System.out.println("Biu~Pia~Biu~Pia~");}});hero.attack();}}

7.9 接口作为方法的参数

import java.util.ArrayList;
import java.util.List;/*
java.util.List正是ArrayList所实现的接口。*/
public class DemoInterface {public static void main(String[] args) {// 左边是接口名称,右边是实现类名称,这就是多态写法List<String> list = new ArrayList<>();List<String> result = addNames(list);for (int i = 0; i < result.size(); i++) {System.out.println(result.get(i));}}public static List<String> addNames(List<String> list) {list.add("迪丽热巴");list.add("古力娜扎");list.add("玛尔扎哈");list.add("沙扬娜拉");return list;}}

7.10 发红包案例

import red.OpenMode;/*
场景说明:红包发出去之后,所有人都有红包,大家抢完了之后,最后一个红包给群主自己。
大多数代码都是现成的,我们需要做的就是填空题。
我们自己要做的事情有:1. 设置一下程序的标题,通过构造方法的字符串参数2. 设置群主名称3. 设置分发策略:平均,还是随机?红包分发的策略:1. 普通红包(平均):totalMoney / totalCount,余数放在最后一个红包当中。2. 手气红包(随机):最少1分钱,最多不超过平均数的2倍。应该越发越少。*/
public class Bootstrap {public static void main(String[] args) {MyRed red = new MyRed("传智播客双元课程");// 设置群主名称red.setOwnerName("王思聪");// 普通红包
//        OpenMode normal = new NormalMode();
//        red.setOpenWay(normal);// 手气红包OpenMode random = new RandomMode();red.setOpenWay(random);}}
import java.util.ArrayList;public interface OpenMode {/*** 请将totalMoney分成count份,保存到ArrayList<Integer>中,返回即可。** @param totalMoney            总金额为方便计算,已经转换为整数,单位为分。* @param totalCount            红包个数* @return ArrayList<Integer> 元素为各个红包的金额值,所有元素的值累和等于总金额。*/ArrayList<Integer> divide(int totalMoney, int totalCount);
}

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashMap;/*** 红包的框架 RedPacketFrame** AWT / Swing / JavaFX** @author 不是我*/
public abstract class RedPacketFrame extends JFrame {private static final long serialVersionUID = 1L;private static final String DIR = "day11-code\\pic";private ArrayList<Integer> moneyList = null;private static int initMoney = 0;private static int totalMoney = 0; // 单位为“分”private static int count = 0;private static HashMap<JPanel, JLabel> panelLable = new HashMap<>();// 设置字体private static Font fontYaHei = new Font("微软雅黑", Font.BOLD, 20);private static Font msgFont = new Font("微软雅黑", Font.BOLD, 20);private static Font totalShowFont = new Font("微软雅黑", Font.BOLD, 40);private static Font nameFont = new Font("微软雅黑", Font.BOLD, 40);private static Font showNameFont = new Font("微软雅黑", Font.BOLD, 20);private static Font showMoneyFont = new Font("微软雅黑", Font.BOLD, 50);private static Font showResultFont = new Font("微软雅黑", Font.BOLD, 15);/*** 窗体大小 WIDTH:400 HEIGHT:600*/private static final int FRAME_WIDTH = 416; // 静态全局窗口大小private static final int FRAME_HEIGHT = 650;private static JLayeredPane layeredPane = null;/// private static JPanel contentPane = null;/*** page1:输入页面 - InputPanel . 组件和初始化!*/private static JPanel inputPanel = new JPanel();// private static JTextField input_total = new JTextField("200"); // 测试用// private static JTextField input_count = new JTextField("3"); // 测试用private static JTextField input_total = new JTextField();private static JTextField input_count = new JTextField();private static JTextField input_people = new JTextField("30");private static JTextField input_msg = new JTextField("恭喜发财  ,  大吉大利");private static JTextField input_total_show = new JTextField("$ " + input_total.getText().trim());private static JLabel input_inMoney = new JLabel(); // 不可见private static JLabel input_bg_label = new JLabel(new ImageIcon(DIR + "\\01_input.jpg"));static {// 设置位置input_total.setBounds(200, 90, 150, 50);input_count.setBounds(200, 215, 150, 50);input_people.setBounds(90, 275, 25, 30);input_msg.setBounds(180, 340, 200, 50);input_total_show.setBounds(130, 430, 200, 80);input_inMoney.setBounds(10, 535, 380, 65);input_bg_label.setBounds(0, 0, 400, 600); // 背景// 设置字体input_total.setFont(fontYaHei);input_count.setFont(fontYaHei);input_people.setFont(fontYaHei);input_msg.setFont(msgFont);input_msg.setForeground(new Color(255, 233, 38)); // 字体颜色 为金色input_total_show.setFont(totalShowFont);input_inMoney.setFont(fontYaHei);// 透明input_people.setOpaque(false);input_total_show.setOpaque(false);// 编 辑 -- 不可编辑input_people.setEditable(false);input_total_show.setEditable(false);// 边界 -- 无input_total.setBorder(null);input_count.setBorder(null);input_people.setBorder(null);input_msg.setBorder(null);input_total_show.setBorder(null);}/*** page2:打开页面 - openPanel . 组件和初始化!*/private static JPanel openPanel = new JPanel();private static JTextField open_ownerName = new JTextField("谁谁谁");private static JLabel open_label = new JLabel(new ImageIcon(DIR + "\\02_open_2.gif"));private static JLabel open_bg_label = new JLabel(new ImageIcon(DIR + "\\02_open_1.jpg"));static {// 设置 位置.open_ownerName.setBounds(0, 110, 400, 50);open_bg_label.setBounds(0, 0, 400, 620);open_label.setBounds(102, 280, 200, 200);open_ownerName.setHorizontalAlignment(JTextField.CENTER);// 设置字体open_ownerName.setFont(nameFont);open_ownerName.setForeground(new Color(255, 200, 163)); // 字体颜色 为金色// 背景色// open_name.setOpaque(false);open_ownerName.setBackground(new Color(219, 90, 68));// 不可编辑open_ownerName.setEditable(false);// 边框open_ownerName.setBorder(null);}/*** page3:展示页面 - showPanel . 组件和初始化!*/private static JPanel showPanel = new JPanel();private static JPanel showPanel2 = new JPanel();private static JScrollPane show_jsp = new JScrollPane(showPanel2);private static JLabel show_bg_label = new JLabel(new ImageIcon(DIR + "\\03_money_1.jpg"));private static JTextField show_name = new JTextField("用户名称");private static JTextField show_msg = new JTextField("祝福信息");private static JTextField show_money = new JTextField("99.99");private static JTextField show_result = new JTextField(count + "个红包共" + (totalMoney / 100.0) + "元,被抢光了");static {// 分别设置水平和垂直滚动条自动出现// jsp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);// jsp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);/** 两部分 页面 . 1.本人获得的红包-- showPanel 2.别人获得的红包-- show_jsp*/show_name.setBounds(125, 180, 100, 30);show_name.setOpaque(false);show_name.setBorder(null);show_name.setFont(showNameFont);show_msg.setBounds(0, 220, 400, 30);show_msg.setOpaque(false);show_msg.setBorder(null);show_msg.setFont(msgFont);show_msg.setHorizontalAlignment(JTextField.CENTER);show_money.setBounds(0, 270, 250, 40);show_money.setOpaque(false);show_money.setBorder(null);show_money.setFont(showMoneyFont);show_money.setForeground(new Color(255, 233, 38)); // 字体颜色 为金色show_money.setHorizontalAlignment(SwingConstants.RIGHT);show_result.setBounds(10, 460, 400, 20);show_result.setOpaque(false);show_result.setBorder(null);show_result.setFont(showResultFont);show_result.setForeground(new Color(170, 170, 170)); // 字体颜色 为灰色// 设置 图片.show_bg_label.setBounds(0, 0, 400, 500);}static {// 页面和 背景的对应关系.panelLable.put(inputPanel, input_bg_label);panelLable.put(openPanel, open_bg_label);panelLable.put(showPanel, show_bg_label);}private void init() {// 层次面板-- 用于设置背景layeredPane = this.getLayeredPane();
//        System.out.println("层次面板||" + layeredPane);// System.out.println(layeredPane);// 初始化框架 -- logo 和基本设置initFrame();// 初始化 三个页面 -- 准备页面initPanel();// 2.添加 页面 --第一个页面, 输入 panel 设置到 页面上.setPanel(inputPanel);// 3.添加 监听addListener();}
import red.OpenMode;import java.util.ArrayList;public class NormalMode implements OpenMode {@Overridepublic ArrayList<Integer> divide(final int totalMoney, final int totalCount) {ArrayList<Integer> list = new ArrayList<>();int avg = totalMoney / totalCount; // 平均值int mod = totalMoney % totalCount; // 余数,模,零头// 注意totalCount - 1代表,最后一个先留着for (int i = 0; i < totalCount - 1; i++) {list.add(avg);}// 有零头,需要放在最后一个红包当中list.add(avg + mod);return list;}
}
import red.OpenMode;import java.util.ArrayList;
import java.util.Random;public class RandomMode implements OpenMode {@Overridepublic ArrayList<Integer> divide(final int totalMoney, final int totalCount) {ArrayList<Integer> list = new ArrayList<>();// 随机分配,有可能多,有可能少。// 最少1分钱,最多不超过“剩下金额平均数的2倍”// 第一次发红包,随机范围是0.01元~6.66元// 第一次发完之后,剩下的至少是3.34元。// 此时还需要再发2个红包// 此时的再发范围应该是0.01元~3.34元(取不到右边,剩下0.01)// 总结一下,范围的【公式】是:1 + random.nextInt(leftMoney / leftCount * 2);Random r = new Random(); // 首先创建一个随机数生成器// totalMoney是总金额,totalCount是总份数,不变// 额外定义两个变量,分别代表剩下多少钱,剩下多少份int leftMoney = totalMoney;int leftCount = totalCount;// 随机发前n-1个,最后一个不需要随机for (int i = 0; i < totalCount - 1; i++) {// 按照公式生成随机金额int money = r.nextInt(leftMoney / leftCount * 2) + 1;list.add(money); // 将一个随机红包放入集合leftMoney -= money; // 剩下的金额越发越少leftCount--; // 剩下还应该再发的红包个数,递减}// 最后一个红包不需要随机,直接放进去就得了list.add(leftMoney);return list;}
}
import red.RedPacketFrame;public class MyRed extends RedPacketFrame {/*** 构造方法:生成红包界面。** @param title 界面的标题*/public MyRed(String title) {super(title);}
}

Java语言高级(第一部分)常用API 继承与多态 ->(个人学习记录笔记)相关推荐

  1. Java语言中几个常用的包

    Java语言中几个常用的包 Java采用包结构来组织和管理类和接口文件.本文介绍Java语言类库中几个常用的包,因为这几个包在软件开发与应用中经常需要用到,其中有些包是必要的.若是离开它,还真不能做事 ...

  2. 我们一起来排序——使用Java语言优雅地实现常用排序算法

    破阵子·春景 燕子来时新社,梨花落后清明. 池上碧苔三四点,叶底黄鹂一两声.日长飞絮轻. 巧笑同桌伙伴,上学径里逢迎. 疑怪昨宵春梦好,元是今朝Offer拿.笑从双脸生. 排序算法--最基础的算法,互 ...

  3. java中的事件都继承自_下列说法中不正确的是()。A.Java语言中的事件都是继承自Java.awt.AW-TEvent类B.AWTEve...

    下列说法中不正确的是().A.Java语言中的事件都是继承自Java.awt.AW-TEvent类B.AWTEve 更多相关问题 [单选] 月经后期而至,量少,色淡,质清稀,少腹隐痛,喜暖喜按,脉沉迟 ...

  4. Java核心类库之(常用API、字符串类、集合类、泛型)

    目录 1 常用API 1.1 Math类 1.2 System类 1.3 Object类 1.4 Objects类 1.5 Arrays类 1.6 基本类型包装类 1.6.1 Integer类概述和使 ...

  5. 在java语言中 ()方法是不可以继承的_Java 语言中,构造方法是不可以继承的。( )_学小易找答案...

    [简答题]需求分析完整话术 [简答题] [单选题]适用于场地面积有限,集装箱吞吐量较大的水陆联运码头的起重机系统是( )系统 [单选题]利用叉车或半挂车.汽车承载货物,连同车辆一起开上开下船,到达目的 ...

  6. 《Java语言高级特性(阿里云大学)》笔记 第7~14章 类库+正则+国际化+比较器(文档+思维导图)

    课程链接:https://edu.aliyun.com/course/1012 第1~6章 关于线程:https://blog.csdn.net/weixin_43494837/article/det ...

  7. java语言代码大全_Java常用语言汇总

    Java有哪些常用语?不介绍Java 常用语,对Java 的总体介绍就是不完整的.尽管促使Java 诞生的源动力是可移植性和安全性,但在Java 语言终成型的过程中,其他一些因素也起了重要的作用.接下 ...

  8. Java基础知识回顾之三 ----- 封装、继承和多态

    前言 在上一篇中回顾了java的修饰符和String类,这篇就来回顾下Java的三大特性:封装.继承.多态. 封装 什么是封装 在面向对象程式设计方法中,封装是指一种将抽象性函式接口的实现细节部份包装 ...

  9. Java的三大特性:封装、继承、多态

    一.类的概念: 类一般包括两个部分:属性(成员变量)和方法(成员方法) 方法组成部分:修饰符(可选) 返回值类型(必须) 方法名(必须)参数列表(可选) package com.classTest.p ...

最新文章

  1. 使用Docker-Docker for Web Developers(2)
  2. java语言怎样判断文件夹_JAVA语言之如何判断文件,判断文件夹是否存在的代码...
  3. python安装扩展常用的工具是_Python 安装扩展库常用的是 _______ 工具_学小易找答案...
  4. 项目奖金一般是多少_二级建造师一个月薪资平均有多少?
  5. solaris10下vim安装
  6. weblogic启动项目失败查看_weblogic启动报错常见错误解决办法
  7. jmeter分布式步骤
  8. 同域下iframe父页面和子页面调用
  9. 【mysql】使用脚本对mysql状态进行监控
  10. python转义字符表
  11. Jmeter5.0脚本录制
  12. pdf转换成word后有文字叠加_PDF转换成Word后进行处理
  13. 软件项目管理实践经验谈
  14. c语言中的static inline
  15. 领导的沉默,背后到底隐藏着什么?
  16. Aurora ip核的使用详解
  17. linux 安装防病毒软件,04Linux环境下Norton防病毒软件安装和使用.doc
  18. 程序员中的老司机们,30 后的路该开向哪里?----转自程序人生
  19. Holtek合泰单片机 《四》 从TM定时器中断到led灯1s闪烁
  20. SHARD_ROW_ID_BITS

热门文章

  1. QTP自动化测试-打开运行报告
  2. STM32-电源【ADC供电、VDDA、VSSA、VREF、VBAT等】
  3. jzoj zsy家今天的饭_jzoj zsy家今天的饭_有它拌饭,碗我都能舔干净!老干妈竟然被轻松超越了?...
  4. linux如何查看端口是否开放?
  5. java json转map数组_java将 json数组转map
  6. 你们周报一般写多少字?我周报写4000字,领导让我缩减,但我担心缩减了没法体现工作量!...
  7. PVE安装Openwrt 旁路由
  8. 用户运营浅谈-我的AARRR模型
  9. 华为耳机如何关闭早问候
  10. ①、iOS-RAC的开发用法-底层分析以及总结