S2 Java面向对象编程 Java OOP
目录
封装
类与对象
对象创建的内存
这个地址不一定连续的
调用方法
show()方法运行完毕后
成员变量和局部变量
name age 是成员变量
i j 是局部变量
私有 private
this
构造方法 实例化对象时给的对象赋值
老方法 这样太麻烦了
新方法
这样就OK了,但是
解决方法
构造方法是对象构造之前实例化
无参构造方法的特点
关于无参构造方法
重载
同样是方法构造名相同,参数不同
构造方法的特点
构造方法注意事项
标准类的制作
标准类的定义
public class Student {
// 封装字段
private String name;
private int 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;
}
// 构造方法
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {
}
// 字符串显示
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
Getter and Setter 共有方法
Constructor 自动构造方法
ToString() 字符串显示
集合
集合和数组的区别
这样报错就说明不能这样拿取值,这里可以自己退出来,利用
al.get(下标)
的方法获取值
不知道他的类型就等他报错
从集合中那拿数据就是Object类型的
集合结论
遍历集合
获取集合长度
利用
集合对象.size()
就可以获取集合的长度了
注意:集合和数组的一点区别是,集合是有多少数据就有多长,数组是定义是就得定义长度
泛型集合
原来的集合可以放其他的数据类型,但是取值强制转换类型是会保错,因为里面有其他的数据类型,这里就用到一个泛型集合了
泛型集合定义
存放数据取数据
泛型集合遍历
案例
包装类
Integer是new 出来的,就说明有一个构造方法
把普通类型放到别的类里面,里面有许多的方法可以用
继承
继承概念
继承前不可以调用父类的方法和属性,继承后可以调用父类的方法和属性
如:yakecom() 和 familyName
关键词
extends
这里是要理解的
注意:儿子可以找父亲拿东西,但父亲不可以找儿子拿东西
继承的好处
继承变量访问
super 与 this 关键词
super 我自己有但我不用,用父亲的
this 使用自己的
新建其他的方法一定要把出参方法带上
这样也是可以的
重写
概念
重写
重写的方法名要和父类相同
重写方法注意事项
语法上是可以的
案例
新建 人 类 新建工作方法
public class People {
// 工作
public void work(){
System.out.println("工作");
}
}
新建老师类 继承 人 类 重写工作方法
public class Teacher extends People{
@Override
public void work() {
System.out.println("教书");
}
}
新建学生类 重写工作方法
public class Student extends People {
@Override
public void work() {
System.out.println("学习");
}
}
定义导包
导包
也可以不导包
但是这样非常的麻烦
这个是python 中的导包
这个One 是一个标识符
权限修饰符
final修饰符
final 修饰变量是不可以修改值的
final 修饰类不可以被继承,不能有儿子(子类),但可以有父亲(父类)
final 修饰方法不可以被重写
final 修饰引用数据类型
可以打破我不可以被引用的规则
被 final 修饰的不可以被赋值 (“=”)
但是利用 add() 方法是可以的
final 和 常量差不多
static 静态修饰符
概念
基础static
调用方法同理
深入static
如果非要用的话,只能实例化了
总结
多态
什么是多态
体验多态
多态卡尔只能调用父类方法
生活实例
多态有什么用
案例 宠物店
package ren;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
System.out.println("请问要购买什么动物");
System.out.println("1.猫 2.狗");
Scanner scanner = new Scanner(System.in);
System.out.println("请选择");
String choice = scanner.next();
System.out.println("用户选择是"+choice);
Animal pet = buy(choice);
pet.show();
}
private static Animal buy(String choice) {
if (choice.equals("1")){
Cat cat = new Cat();
cat.name = "咪咪";
return cat;
}else if(choice.equals("2")){
Dog dog = new Dog();
dog.name = "汪汪";
return dog;
}
return null;
}
}
结论
否则调父类的方法
多态的转型
如果我想调用,猫和狗的特有方法的话,可以强制类型转换 类似于装箱拆箱
多态访问特性
抽象
抽象的引入
体验抽象
抽象的特点
特点
父子都是抽象类的话,子类不用重写抽象方法
案例
接口
概念
USB 是一个规范,只要你符合我的USB接口,接口利用
定义
要实现xxx
接口和抽象很像
子类只能调用不可以修改
特点
抽象方法中有构造方法
抽象类,定义变量并不是默认就有 static final 的
案例:我的电脑
构建开始方法
新增插入
风扇类
先实例化一个风扇,在调用pc insertUsb1 把值传进去就可以了
弹出设备
接口应用场景
接口和抽象的区别
特点
接口与接口 -继承
-多继承
继承接口案例
一定要先继承后连接接口
包装类
特点
实操
String int 互相转换
自动装箱拆箱
日期
概念
SimpleDateFormat对象
时间转换
日期转换工具类
parse可以把中文的显示转换为英文的显示输出 如:Thu Sep 06 00:00:00 CST 2029
运行
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateUtile {
// 统一格式
//yyyy-MM-dd
static String fmtStr = "yyyy-MM-dd";
// 日期转字符串
public static String Date2Str(Date date){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(fmtStr);
return simpleDateFormat.format(date);
}
// 字符串转日期
public static Date Str2Date(String strDate) throws ParseException {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(fmtStr);
return simpleDateFormat.parse(strDate);
}
}
扩展日历
案例:二月天
异常处理
体系
Throwable 可抛出;未测试
runable 可运行的
flyable 可飞行的
Exception 例外;一般情况以外的人(或事物);规则的例外;例外的事物
Runtime Exception 执行时异常
Throwable 就是一个普通的类
JVM
try与catch
捕捉所有的异常
输出异常
finally
概念
编译时异常
运行时异常
“甩锅” 异常声明
抛异常
throws
放在方法后面的
throw
用在方法体里面的
手动抛出异常
案例:年龄设置异常
自定义异常
这个方法比较使用,见名知意
要记得交给父级处理
总结
常用类
Math
abs
返回这个数的绝对值
运行效果
ceil
只要小数位上有数据小数点前面的加一
运行效果
floor
只要小数点后面的位上有数,小数点后面的变成0
运行效果
round
按照四舍五入的方式返回值
运行效果
max
返回两个数中最大数
可以放小数
运行效果
min
返回两个数中的最小数
可以放小数
运行效果
pow
返回a的b次幂的值,相当于a的b次方
运行效果
random
获取0 - 1 之间的随机小数
运行效果
System
exit
终止当前的程序
结束编码
运行效果
currentTimeMillis
获取当前时间,返回一个时间戳,以毫秒为单位
运行效果
Object
Arrays
集合框架
集合家族
Collection集合
参考文档:jdk在线文档
他是接口不可以实例化
collection 有许多的方法详细见上面的 jdk在线文档
接口回顾
Collection 常用方法
演示
add() 添加数据 括号放添加的数据 返回一个是否添加成功 boolean
remove() 移除数据 括号放移除数据的下标 返回一个是否移除成功 boolean
clear() 清楚所有数据 无参数 无返回值 void
contains() 判断集合中是否存在我指定的元素 括号放要找的元素 返回一个是否找到此数据 boolean
isEmpty() 判断集合是否为空 无参数 返回一个是否为空 booolean
size() 集合的长度 无参数 返回集合的长度 int
运行效果
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
ArrayList<Object> arrayList = new ArrayList<>();
// 添加元素
boolean add1 = arrayList.add("佳慧");
boolean add2 = arrayList.add("郭哈");
boolean add3 = arrayList.add("惠民");
System.out.println(add1+"\t"+add2+"\t"+add3);
// 移除元素
Object remove = arrayList.remove(0);
System.out.println(remove);
// 清空集合
arrayList.clear();
// 判断集合中是否存在我指定元素
boolean b = arrayList.contains("惠民");
System.out.println(b);
// 判断集合是否为空
boolean empty = arrayList.isEmpty();
System.out.println(empty);
// 集合的长度
int size = arrayList.size();
System.out.println(size);
}
}
接口多态
Collection 遍历
迭代器:可以为你供应新的东西
演练
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
public class Test {
public static void main(String[] args) {
// 接口多态
Collection arrayList = new ArrayList<>();
// 添加内容
arrayList.add("hello");
arrayList.add("java");
arrayList.add("nice to meet you");
// 遍历集合 [成员1, 成员2, 成员3]
Iterator iterator = arrayList.iterator();
// 第一次拿数据
Object next = iterator.next();
System.out.println(next);
// 第二次拿数据
Object next1 = iterator.next();
System.out.println(next1);
// 第三次拿数据
Object next2 = iterator.next();
System.out.println(next2);
}
}
如果我要拿数据,但超过了他的长度的话,会保存
判断有没有下一个数据
迭代器遍历
如果是接口多态我就用迭代器遍历
如果是ArrayList 可以直接用下标遍历
接口多态
可以利用 WinForm 里面的遍历数据朗读者的经验来写
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Test {
public static void main(String[] args) {
// 接口多态
Collection arrayList = new ArrayList<>();
// 添加内容
arrayList.add("hello");
arrayList.add("java");
arrayList.add("nice to meet you");
// 遍历集合 [成员1, 成员2, 成员3]
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
System.out.println(next);
}
}
}
ArrayList集合
扩展:抽象类和接口类之间的关系
list 集合
list 是可重复的
list 特有方法
演练
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
// 接口多态
List arrayList = new ArrayList<>();
// 添加内容
arrayList.add("hello");
arrayList.add("java");
arrayList.add("nice to meet you");
arrayList.add(1,"你好");
// 取数据
Object remove = arrayList.remove(2);
System.out.println(remove);
// 修改数据
Object javac = arrayList.set(1, "javac");
System.out.println(javac);
// 获取数据
Object o = arrayList.get(1);
System.out.println(o);
}
}
三种遍历
Listlterator 迭代器
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class Test {
public static void main(String[] args) {
List<Object> arrayList = new ArrayList<>();
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("d");
arrayList.add("e");
ListIterator<Object> listIterator = arrayList.listIterator();
listIterator.add("f");
listIterator.add("g");
while(listIterator.hasNext()){
Object next = listIterator.next();
System.out.println(next);
}
System.out.println("============================");
while(listIterator.hasPrevious()){
Object next1 = listIterator.previous();
System.out.println(next1);
}
}
}
增强 for 循环
栈和队列
对列是先进先出
栈是先进后出
栈
对列
顺序表
结构
特性
链表
特性
ArrayList 与 LinkedList
LinkedList
特有方法
Set 集合
特点
不可以用普通 for 循环遍历
哈希值
实际演示
这几张图表示,哈希值不可以完全是内存地址
HashSet
案例
LinkedHashSet
实例
TreeSet
实例
泛型
泛型类
泛型集合
泛型类的定义
实例
泛型类的创建
创建加实例化
泛型方法
扩展实例
他并不会受到泛型类的影响
泛型注意事项
泛型接口
演练
双列
常用方法
遍历
双列集合增删改查
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test2 {
public static void main(String[] args) {
// 双列集合的遍历
// 实例化一个集合对象
// Map<key,value>
Map<String, Integer> map = new HashMap<>();
// 增
// 放入测试数据
map.put("孙武kong",66);
map.put("luo",76);
map.put("wu",76);
map.put("太难",96);
System.out.println("-----------------------------");
// 删
Integer remove = map.remove("luo");
System.out.println(remove);
System.out.println("-----------------------------");
// 改
Integer taiNan = map.put("太难", 666);
System.out.println(taiNan);
System.out.println("-----------------------------");
// 查
// 多种方式进行遍历,目标是拿到所有的份数
// 方式1 , entry 对象集合
Set<Map.Entry<String, Integer>> entries = map.entrySet();
for (Map.Entry<String, Integer> item:entries
){
// 获取键
String key = item.getKey();
// 获取值
Integer value = item.getValue();
// 输出
System.out.println("键:"+key);
System.out.println("值:"+value);
// 分界线
System.out.println("=====================");
}
// 方式二遍历
// 拿所有的键的set 集合
// 遍历set 集合
Set<String> strings = map.keySet();
for (String key :
strings) {
Integer integer = map.get(key);
System.out.println(integer);
}
System.out.println("=========================");
// 遍历方式3,直接拿值的集合
Collection<Integer> values = map.values();
// 遍历值的集合
for (Integer val :
values) {
System.out.println("值是:"+val);
System.out.println("====================");
}
}
}
案例:学生Map集合
演练:有序集合包无序集合
演练
package ShangKe;
import java.util.ArrayList;
import java.util.HashMap;
public class Test {
public static void main(String[] args) {
// 定义一个无序双列集合
HashMap<String, String> kd = new HashMap<>();
// 添加数据
kd.put("001","足球");
kd.put("996","手机");
System.out.println(kd);
// 定义一个无序双列集合
HashMap<String, String> kd2 = new HashMap<>();
// 添加数据
kd2.put("123","火腿肠");
kd2.put("789","泡面");
System.out.println(kd2);
// 定义一个有序集合
ArrayList<HashMap<String, String>> kdList = new ArrayList<>();
kdList.add(kd);
kdList.add(kd2);
for (HashMap<String, String> hm:
kdList){
System.out.println(hm);
}
}
}
效果
无序集合包有序集合
演练
package ShangKe;
import java.util.ArrayList;
import java.util.HashMap;
public class Test2 {
public static void main(String[] args) {
// 无序包有序
// 彭鸿骏小组成员列表
ArrayList<String> hjList = new ArrayList<>();
hjList.add("彭鸿骏");
hjList.add("王琦");
hjList.add("柯贤林");
// 定义班级无序容器
HashMap<String, ArrayList<String>> a1107 = new HashMap<>();
// 为班级创建一个学习小组
a1107.put("鸿骏学习小组",hjList);
// 构建第二个学习小组
ArrayList<String> ymList = new ArrayList<>();
ymList.add("吴迎蒙");
ymList.add("谢鸥");
ymList.add("吴超");
// 班级新增学习小组
a1107.put("迎蒙学习小组",ymList);
System.out.println(a1107);
}
}
效果
案例:统计字符串出现次数
Collections类
Collections 常用方法
示例
排序
反转
乱序
案例:对象集合年龄排序
后面会说到内部类
案例:查找字符出现次数
package ShangKe;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test3 {
public static void main(String[] args) {
System.out.println("字符串的遍历");
// 新建键值对集合
HashMap<String, Integer> hashMap = new HashMap<>();
// 字符集
String con = "abaabbacd";
// 获取 entrySet 对象
Set<Map.Entry<String, Integer>> entries = hashMap.entrySet();
// 循环获取字符
for (int i = 0; i < con.length(); i++) {
// 获取字符
char c = con.charAt(i);
// 字符转字符串
String s = String.valueOf(c);
// 通过键查找值
Integer integer = hashMap.get(s);
// 判断值是否存在
if (integer == null){
hashMap.put(s,1);
}else{
integer+=1;
hashMap.put(s,integer);
}
}
// 遍历双列集合
for (Map.Entry<String, Integer> item :
entries) {
// 获取 键
String key = item.getKey();
// 获取 值
Integer value = item.getValue();
System.out.print(key + "(" + value + ")" + " ");
}
}
}
运行效果
复习
java IO
io 是什么
input 输入
output 输出
fiel 类
fiel 构造方法
创建方法
创建文件
创建文件夹
创建多个文件夹
判断与获取方法
import java.io.File;
import java.io.IOException;
public class Test2 {
public static void main(String[] args) throws IOException {
// 创建文件对象
File file = new File("n\\h");
// // 创建文件
// boolean newFile = file.createNewFile();
// System.out.println("创建文件:"+newFile);
// 创建目录
boolean mkdirs = file.mkdirs();
System.out.println(mkdirs);
// 判断路径文件是否是目录
boolean directory = file.isDirectory();
System.out.println("判断路径文件是否是目录:"+directory);
// 判断是否是文件
boolean file1 = file.isFile();
System.out.println("判断是否是文件:"+file1);
// 判断路径名的文件是否存在
boolean exists = file.exists();
System.out.println("判断路径名的文件是否存在:"+exists);
// 获取此路径的绝对路径字符串
String absolutePath = file.getAbsolutePath();
System.out.println("获取此路径的绝对路径字符串:"+absolutePath);
// 获取此路径名字字符串
String path = file.getPath();
System.out.println("获取此路径名字字符串:"+path);
// 获取文件或目录的名称
String name = file.getName();
System.out.println("获取文件或目录的名称:"+name);
// 返回此路径下表示的所有目录和目录的名称字符串数组
String[] list = file.list();
System.out.println("返回此路径下表示的所有目录:");
for (String t :
list) {
System.out.println(t);
}
// 返回此路径下表示的所有文件和File对象数组
File[] files = file.listFiles();
System.out.println("返回此路径下表示的所有文件和File对象数组:");
for (File a :
files) {
System.out.println(a);
}
}
}
演练
删除文件
演练
递归
关于递归
演练 求1-10的和
非递归
递归方式求和
演练 求1-10的阶乘
打印文件路径
import java.io.File;
public class Test3 {
public static void main(String[] args) {
File file = new File("D:\\");
getAllFilePath(file);
}
private static void getAllFilePath(File scrFile) {
// 获得目录下所有内容
File[] files = scrFile.listFiles();
// 判断是否是文件
if (files != null){
// 增强 for 循环判断
for (File file : files){
// 判断是否是文件夹
if (file.isDirectory()){
// 是:递归调用
getAllFilePath(file);
}else{
// 不是:获取绝对路径输出在控制台
System.out.println(file.getAbsolutePath());
}
}
}
}
}
字节流
关于
流向
分类
字节流的超类
able - 有某种能力
字节输出流实用对象
体验 字节输出流对象
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class ZiJieLiu {
public static void main(String[] args) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("kk.txt");
fileOutputStream.write(97);
fileOutputStream.close();
}
}
字节流写数据的三种方式
演练 字节流写数据
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class ZiJieLiu {
public static void main(String[] args) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("kk.txt");
String mas = "你好,欢迎学习Java";
byte[] bytes = mas.getBytes();
fileOutputStream.write(bytes);
fileOutputStream.close();
}
}
字节流写数据的小问题
字节流写数据加异常处理
体验 字节流读数据
慢慢的读
读完全部
遍历读数据
案例:拷贝视频
一个字节一个字节的拷贝
缺点:慢
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Copy {
public static void main(String[] args) throws IOException {
// 一个字节一个字节的拷贝
// 文件路径
String filePath = "这波让我装到了.mp4";
String copyPath = "拷贝" + filePath ;
// 获取一个读操作的文件对象
FileInputStream fileInputStream = new FileInputStream(filePath);
// 获取一个写操作的文件对象
FileOutputStream fileOutputStream = new FileOutputStream(copyPath);
// 一个字节一个字节的读
int read = fileInputStream.read();
while (read != -1) {
fileOutputStream.write(read);
read = fileInputStream.read();
}
// 复制完成
System.out.println("复制成功!");
// 关闭资源
fileInputStream.close();
fileOutputStream.close();
}
}
利用 byte 数组来拷贝
优点:快
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyShuZuBan {
public static void main(String[] args) throws IOException {
// 文件路径
String filePath = "这波让我装到了.mp4";
String copyPath = "拷贝" + filePath;
// 获取一个读操作的文件对象
FileInputStream fileInputStream = new FileInputStream(filePath);
// 获取一个写操作的文件对象
FileOutputStream fileOutputStream = new FileOutputStream(copyPath);
// 定义字节数组
byte[] bytes = new byte[1024];
// 第一次读
int read = fileInputStream.read(bytes);
// 循环
while (read != -1) {
// 存数据
fileOutputStream.write(bytes, 0, read);
// 再读一次
read = fileInputStream.read(bytes);
}
// 关闭资源
fileInputStream.close();
fileOutputStream.close();
// 输出成功
System.out.println("拷贝成功");
}
}
字节缓存流
关于
字节缓冲输出流
字节缓冲输入流
实例
字节缓冲流复制视频
字符流
关于
获取字符串的字节数组
byte[ ] bys = s.getBytes(“UTF-8”);
byte[ ] bys = s.getBytes(“GBK”);
编码表
字符集
编码与解码
代码 字符流的读与写操作体验
字符流中相关的类
体验 字符输入流与字符输出流
字符输出流写数据的五种方式
关闭与刷新的方法
演练 写入数据的五种方法
写一个字符数据
写一个字符数组
写一个字符数组的一部分
写一个字符串
写一个字符串的一部分
字符流读数据的两种方式
演练 字符流读数据的两种方式
一个字符一个字符的读
利用字符数组来读
演练 字符流复制文件
一次一个字符
一次一个字符数组
FileReader与FileWritter
体验 字符流复制文件
一次一个字符
##### 一次一个字符数组
小结
字符缓冲流
体验字符缓冲流
写数据
读数据
演练 字符缓冲流复制文件
总结
案例
对象序列化流
关于
对象序列化流 objectOutputStream
演练 存对象
对象反序列化流 ObjectInputStream
读对象
三个问题待解决
问题 反序列化时类如果发生变化会报错
问题 某个属性不想参与序列化
三个问题答案
Properties集合
演练 作业Map集合的使用
Properties 特有方法
Properties和IO流集合的方法
存数据
读数据
存读数据
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
public class Test04 {
public static void main(String[] args) throws IOException {
// 存数据
cun();
// 读数据
qv();
}
// 取数据
private static void qv() throws IOException {
Properties properties = new Properties();
// 字符流输入
FileReader fileReader = new FileReader("kk.txt");
// 让集合加载字符六中的内容
properties.load(fileReader);
// 获取集合的内容
String root = properties.getProperty("root");
String age = properties.getProperty("name");
System.out.println(root);
System.out.println(age);
}
// 存数据
public static void cun() throws IOException {
Properties properties = new Properties();
properties.setProperty("root", "root123456");
properties.setProperty("name", "王小毛");
// 存数据
FileWriter fileWriter = new FileWriter("kk.txt");
properties.store(fileWriter, null);
fileWriter.close();
}
}
效果
多线程
认识多任务
认识进程
认识线程
多线程方式一
使用线程类完成多线程功能
演练 多线程
设置和获取线程名称
演练 线程名字的设置与获取
获取子线程名字
实例化线程是直接起名字
获取当前进程对象
线程优先级
设置线程优先级
小结线程优先级
线程控制
守护线程
线程生命周期
多线程方式二
另一种线程实现方式
演练 方式2实现线程
演练 实例化线程并给线程起名字
效果
小结 两种线程的实现方式
线程同步
案例 电影院卖票
线程上锁
上锁示范
可以不需要object,可以直接用this
同步方法
Lock锁