
Java期末复习知识点总结
·
一、Java程序概述
1、特性
简单性、高性能、编译性、解释性、分布式处理、健壮性、安全性、面向对象、 开源、跨平台
2、


3、JDK、JRE、JVM
JDK:Java开发工具包
包含:JAVA开发工具(jdk\bin)
基础开发库(jdk\jre\lib\rt.jar)
基础开发库的源码(jdk\src.zip)
Java SE 开发工具包的 javac命令负责编译应用程序
java:java解释器,用于执行Java应用程序
JRE: Java运行时环境
JVM: 负责加载.class并运行.class文件
4、
二、变量、数据类型和运算符
1、标识符:
由字母、数字、下划线(_)、美元符($)组成,但不能包含 @、%、空格等其它特殊字符
不能以数字开头
2、变量
变量名必须是一个有效的标识符
变量名不可以使用java关键字
变量名不能重复
3、数据类型
3.1 基本数据类型

类型转换:
小到大,直接转 大到小,强制转 浮变整,小数没
低 ------------------------------------> 高
byte,short,char→ int→ long→float→double
3.2 引用数据类型 :类、接口、数组
4、运算符
-
计算结果的数据类型,与最大数据类型一致
-
byte,short,char三种比int小的整数,运算时会先自动转换成int

int a = 1;
System.out.println("*************");
System.out.println(a++);//打印结果是1,打印完以后再变化,自增成2
System.out.println(a);
int b = 1;
System.out.println(++b);//打印结果是2,因为符号在前,先自增
int c = 1;
System.out.println(c--);//打印结果是1,符号在后,先打印,再自减
System.out.println(c);//自减过后变成了0
int d = 1;
System.out.println(--d);//打印结果是0,符号再前,先自减再打印
//因为受之前代码的影响,c的初始值是0
System.out.println(--c-c-c--);//-1-(-1)-(-1)=-1+1+1=1
System.out.println(c);//-2
5、数据的输入和输出
1)数据输出
System.out.println()
System.out.print()
System.out.printf()
2)数据输入
通过Scanner类创建一个输入的类对象
Scanner sc=new Scanner(System.in)
然后sc对象通过调用下列方法,读取用户输入的各种数据类型
(1)nextByte (2)nextDouble (3)nextFloat
(4)nextInt (5)nextLong (6)nextShort
(7)nextLine:该方法得到一个String的类型数据
eg:int a=sc.nextInt()
三、流程控制
1、分支结构
package liucheng;
import java.util.Scanner;
/*本类用于判断学员分数的档位*/
public class TestScore {
public static void main(String[] args) {
//1.提示并接收学员的分数
System.out.println("请输入你的分数:");
int score = new Scanner(System.in).nextInt();
/*90分及以上 优秀
*80-89 良好
*70-79 中等
*60-69 及格
*60分及以下 不及格 */
/**为了增强程序的健壮性,如果用户输入的数据不符合规则,就结束*/
if(score <0 || score >100 ) {
System.out.println("输入数据不合法,请重新输入!!!");
}else {
//2.判断分数的段位,并输出结果
if(score >= 90) {//大于90
System.out.println("优秀!");
//}else if(score>=80 && score <=89) {
}else if(score>=80) {//[80,90)
System.out.println("良好!");
}else if(score>=70) {//[70,80)
System.out.println("中等!");
}else if(score>=60) {//[60,70)
System.out.println("及格!");
}else {//小于60
System.out.println("不及格!");
}
}
}
}
2、switch结构
switch case 语句用来判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。 当一个case成立,从这个case向后穿透所有case,包括default,直到程序结束或者遇到break程序才结束
package liucheng;
//根据学生成绩(成绩在0~100之间)输出等级:
//当成绩大于90(含90),输出A;
//当成绩在80-90之间(含80),输出B ;
//当成绩在60-80之间(含60),输出C;
//当成绩小于60,输出D,用switch语句实现。
import java.util.Scanner;
public class SwitchTest {
public static void main(String[] args) {
System.out.println("input your score:");
Scanner sc=new Scanner(System.in);
int score=sc.nextInt();
switch(score/10){
case 10:
case 9:System.out.println("A");break;
case 8:System.out.println("B");break;
case 7:
case 6:System.out.println("C");break;
default:
System.out.println("D");
}
}
}
注意:
-
1、switch 语句中的变量类型可以是: byte、short、int 、char、String(jdk1.5以后支持)
-
2、switch 语句可以拥有多个 case 语句
-
3、每个 case 后面跟一个要比较的值和冒号,且此值的数据类型必须与变量的数据类型一致
-
4、当变量值与 case 语句值相等时,开始执行此case 语句的内容,执行完会判断此行代码是否有break,如果有,结束执行,如果没有,会继续向后执行穿透所有case,包括default
-
5、switch 语句可以包含一个 default 分支,该分支一般是写在switch 语句的最后
-
6、如果在default之前的case有break,则default不会执行
3、循环结构
1)for循环
package liucheng;
//编写一个Java应用程序,使用for循环输出所有能整除41580的数(包括1和其本身)。
//按照由大到小的顺序输出
//要求每行显示10个。循环变量名为i,用于统计个数的变量名为count。
public class Liucheng {
public static void main(String[] args) {
int count=0;
for(int i=41580;i>0;i--){
if(41580%i==0){
System.out.print(i+" ");
count++;
if(count%10==0)
System.out.println();
}
}
}
}
2)嵌套for循环
package liucheng;
/**本类用于测试完成99乘法表*/
public class TestFor99Excel {
public static void main(String[] args) {
for (int i = 1; i <= 9; i++) {//控制行数,打印9行
for (int j = 1; j <= i; j++) {//控制列数,i行打印i列
//System.out.println("*");--打印左直角三角形
//System.out.println("2*3=6");2--i 3--j 6--i*j
//拼接打印算式,后面拼接一个"\t"表示这是表格格式,\t也被称作制表符
System.out.print(j+"*"+i+"="+(i*j)+"\t");
}
System.out.println();//空白行用来换行
}
}
}
3)break和continue
break: 直接结束当前循环,跳出循环体,简单粗暴
break以后的循环体中的语句不会继续执行,循环体外的会执行
注意如果是嵌套for循环,在内层循环遇到了break,只会跳出当前这一层内循环哦
continue: 跳出本轮循环,继续下一轮循环
4)while循环
先判断后执行
5)do-while循环
先执行,再判断,循环体代码保证最少执行一次
package liucheng;
//1.编写程序,读入整数并判断读入的正数和负数个数,
//输入为0时结束程序。
import java.util.Scanner;
public class Liucheng01 {
public static void main(String[] args) {
/*int num,zsum=0,fsum=0;
System.out.println("please input some numbers:");
Scanner sc=new Scanner(System.in);
do{
num=sc.nextInt();
if(num>0)
zsum++;
else if (num<0)
fsum++;
}while(num!=0);
System.out.println(zsum);
System.out.println(fsum);
*/
int num,zsum=0,fsum=0;
System.out.println("please input some numbers:");
Scanner sc=new Scanner(System.in);
while((num=sc.nextInt())!=0){
if(num>0)
zsum++;
else if (num<0)
fsum++;
}
System.out.println(zsum);
System.out.println(fsum);
}
}
6)三中循环区别
-
for:知道循环次数
-
while/do while:当循环次数不确定时
-
while:先判断,不符合规则,不执行代码
-
do while:代码最少被执行一次,再去判断,符合规则,再次执行代码
四、数组
数组Array,标志是[ ] ,用于储存 多个相同类型数据 的集合
1、一维数组
1)创建数组
-
动态初始化
-
int[] a=new int[5];
-
静态初始化
-
int[] b = new int[]{1,2,3,4,5};
-
int[] c = {1,2,3,4,5};
数组名是个引用类型的变量,它保存着的是数组的地址,不是数组中的数据
package array;
//有一个数列:8,4,2,1,23,344,12
//循环输出数列的值
//求数列中所有数值的和
//猜数游戏:从键盘中任意输入一个数据,判断数列中是否包含此数
import java.util.Arrays;
import java.util.Scanner;
public class Array {
public static void main(String[] args) {
int a[]= {8,4,2,1,23,344,12},sum=0;
for(int i=0;i<a.length;i++) {
System.out.print(a[i]+"\t");
sum+=a[i];
}
System.out.println("sum is "+sum);
Arrays.sort(a);//对数组进行排序
for(int i=0;i<a.length;i++)
System.out.print(a[i]+"\t");
int b,c=0;
boolean x=false; //用Boolean语句判断
System.out.println("请输入一个数");
Scanner s=new Scanner(System.in);
int d=s.nextInt();
for (int i=0;i<a.length;i++){
b=a[i];
if (d==b){
x=true;
break;
}
}
if (x){ //只有Boolean为true的时候if(x)才输出
System.out.println("包含");
}
}
}
public static void m3() {
//1.创建数组--动态
int[] a = new int[10];
//2.遍历数组,给数组中的每个元素赋值
for(int i = 0 ; i <a.length ; i++) {
//100是自定义的数据,表示生成的随机整数的范围是[0,100)
a[i] = new Random().nextInt(100);
//a[i] = new Random().nextInt(100)+1;//取值范围前后都+1-->[1,101)
}
//3.使用数组的工具类查看数组中的元素
System.out.println(Arrays.toString(a));
}
2、二维数组
1)创建数组
int[][] a = { {3,5},{7,9},{1,2}};
int [][] a = new int[2][3];
package array;
//利用随机数产生一个10行,10列的整型矩阵。完成如下操作:
//输出矩阵
//输出矩阵中元素的最大值及最大值所在的位置(行、列值)
//输出矩阵的转置矩阵。
public class Array02 {
public static void main(String[] args) {
int m[][]=new int[10][10];
int max=0,li=0,col=0;
for(int i=0;i<m.length;i++) {//行的遍历(a.length是行数)
for(int j=0;j<m[0].length;j++) {//列的遍历(a[i].length是列数)
m[i][j]=(int) (Math.random()*100);
System.out.print(m[i][j]+"\t");
if(m[i][j]>max) {
max=m[i][j];
li=i;
col=j;
}
}
System.out.println();
}
System.out.println("转置矩阵:");
//转置矩阵
for(int x=0;x<m[0].length;x++) {
for(int y=0;y<m.length;y++)
System.out.print(m[y][x]+"\t");
System.out.println();
}
System.out.println("max is "+max);
System.out.println("lineis "+li);
System.out.println("col is "+col);
}
}
五、字符串
1)String类



package string;
import java.util.Scanner;
//注册新用户,输入用户名和密码,要求密码长度不能小于6位。
//编程实现登录验证,用户名为“TOM”,密码为“1234567” 。
public class String01 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
String name,passwd;
System.out.print("input name:");
name=sc.next();
System.out.print("input passwd:");
passwd=sc.next();
if(passwd.length()<6)
System.out.println("passwd<6");
else if(name.equalsIgnoreCase("TOM")&&passwd.equals("1234567"))//name.equalsIgnoreCase忽略大小写
System.out.println("登录成功!");
else
System.out.println("登录失败!");
}
}
package string;
import java.util.Scanner;
//判断.java文件名是否正确,判断邮箱格式是否正确
//合法的邮箱名中至少要包含“@”和“.”, 并检查“@”是否在“.”之前
public class String02 {
public static void main(String[] args) {
String email,file;
Scanner sc=new Scanner(System.in);
System.out.println("input email:");
email=sc.next();
int index1=email.indexOf('@');//返回出现第一个匹配的位置如果没有找到字符或字符串,则返回-1
int index2=email.indexOf('.');
if(index1!=-1&&index2>index1)
System.out.println("合法");
else
System.out.println("不合法");
System.out.println("input file:");
file=sc.next();
if(file.endsWith(".java"))
System.out.println("合法");
else
System.out.println("不合法");
}
}
package string;
//编写一个Java应用程序,检查一个字符串是否为回文串
//(从前读它和从后读它都是一样的。例如:”abcba”)。
public class String03 {
public static void main(String[] args) {
String str="abcba";
boolean flag=true;
for(int i=0;i<str.length()/2;i++) {
if(str.charAt(i)!=str.charAt(str.length()-i-1)) {
flag=false;
break;
}
}
if(flag)
System.out.println("huiwen");
else
System.out.println(" nohuiwen");
}
}
2)StringBuffer类

package string;
import java.util.Scanner;
//编写一个Java应用程序,使用随机数生成指定长度的字母和数字编码并输出,编码长度可以通过键盘输入。
//算法:26个字母和10个数字,对应36个符号;随机生成0-35的数字分别对应字母和数字。
public class StringBuffer02 {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int len=scanner.nextInt();
StringBuffer code=new StringBuffer();
for(int i=1;i<=len;i++) {
int ram=(int)(Math.random()*36);
System.out.println(ram);
if(ram<=9)
code.append((char)('0'+ram));
else {
code.append((char)('A'+ram-10));
}
}
System.out.println(code);
}
}
六、面向对象编程
1、类与对象的关系
类:
-
用来描述现实事物的,是一类事物的模板。
-
Java语言最基本单位就是类 ,类似于类型。
-
类里有 属性和行为( 方法)
对象:
-
对象是类的一个 实例,是一类事物的具体体现。
-
对象是具体存在的,具备该类事物的属性和行为。
类是对一类事物的描述,是抽象的。
对象是一类事物的实例,是具体的。
类是对象的模板,对象是类的实体。
2、类的创建
package cn.tedu.oop;
/**本类用来练习面向对象
* 分析手机事物:--通过类来描述
* 属性:品牌 价格 尺寸 颜色
* 功能:打电话 发短信 听直播
* */
//1.通过class关键字创建手机类--用来描述手机这一类事物--特征+行为
//类是一类事物的抽象,只抽象的规定这一类事物的特征和行为
class Phone{
//特征(属性)--类的成员变量来描述--位置:类里方法外
String brand;//品牌
double price;//价格
double size;//尺寸
String color;//颜色
//行为(功能)--类的方法来描述--修饰符 返回值类型 方法名(参数列表){方法体}如果方法的返回值类型是void,不允许有返回值
public void call() {
System.out.println("正在打电话");
}
}
//在一个java文件中可以写多个class,但是被public修饰的只能有一个,而且这个类的名字就是文件名
public class TestCreateClass {
public static void main(String[] args) {
//2.在main()中通过new关键字来创建对应类的对象
Phone p = new Phone();
//3.通过.来完成对象功能的调用
p.call();
//4.通过.来查看对象的属性值
System.out.println(p.brand);
System.out.println(p.price);
System.out.println(p.size);
System.out.println(p.color);
}
}
对象在内存中的存储:
-
一般来讲局部变量存在栈中,方法执行完毕内存就被释放
-
对象(new出来的东西)存在堆中,对象不再被使用时,内存才会被释放
-
每个堆内存的元素都有地址值
-
对象中的属性都是有默认值的
3、成员变量和局部变量的区别
package cn.tedu.oop;
/**本类用于测试变量的使用*/
public class TestVariable2 {
//定义成员变量:
//1)位置:类里方法外
//2)无需手动初始化,会自动赋予对应类型的默认值
//3)作用域:在整个类中生效,类消失,变量才会消失
static int count;
//3.变量有一个使用的原则:就近原则
static int sum = 200;
public static void main(String[] args) {
//1.定义局部变量:
//1)位置:在方法里/局部代码块里
//2)必须手动初始化
//3)作用域:在方法/局部代码块中,对应的代码执行完局部变量就被释放
int sum = 100;//定义在方法中的局部变量sum
System.out.println(sum);//变量的就近原则:使用的都是自己附近的变量,100
System.out.println(count);
for (int i = 0; i < 10; i++) {//局部变量i只能在循环中使用
System.out.println(i);
}
//System.out.println(i);//报错:无法引用变量i:i cannot be resolved to a variable
}
}
4、方法重载
方法名相同、参数列表不同
参数列表不同包括:参数数目不同,参数出现顺序不同,参数的类型不同.
5、构造方法
构造方法是一种特殊的方法,它是一个与 类同名 且 没有返回值类型 的方法
如果没有定义构造方法,系统会生成一个默认的无参的构造方法
构造方法只能用new在创建对象时调用,不能通过对象名调用
package object;
/*设计一个等边三角形的类Trival,要求如下:
属性包括三角形的边side(double类型)
构造方法包括:无参构造方法和为side指定初值的有参构造方法
方法包括:获取三角形面积findArea()。*/
public class Trival {
double a,b,c;
//无参构造方法
public Trival() {
}
//有参构造方法
public Trival(double a, double b, double c) {
super();
this.a = a;
this.b = b;
this.c = c;
}
public double findArea() {
double l=(a+b+c)/2;
double s=Math.sqrt(l*(l-a)*(l-b)*(l-c));
return s;
}
public static void main(String[] args) {
Trival t =new Trival();//无参方法调用
t.a=3;
t.b=4;
t.c=5;
Trival t2=new Trival(7,8,9);//有参方法调用
System.out.println(t.findArea());
System.out.println(t2.findArea());
}
}
6、this和static
this:
-
this代表类的当前对象
-
利用“this.”可以调用当前对象的成员
-
this可以实现构造方法的调用
-
利用this()可以调用构造方法 必须写在构造方法的第一条
static:
-
静态属性用static修饰的属性,称为类属性(不是类的属性) 用于描述一个类下所有对象共享的属性 比如:员工的最低工资,学生的学校名称等等 可通 过类名直接调用,也可通过对象调用
-
静态方法用static修饰的方法,叫类方法 静态方法中不能访问非静态成员(属性和方法) 如果一个方法中没有访问非静态成员,则这个方法可以声明成静态的。
-
使用在类外,静态属性和静态方法可以通过类名直接调用,也可以通过对象名调用。 在类外,非静态属性和非静态方法只能通过对象名调用。
7、包
创建包使用关键字 package ( package必须写在程序的第一行 )
导入包使用关键字 import (只能引入其他包中的public类)
8、可见性修饰符


9、访问器方法
package object;
public class Car {
private String brand;
private String color;
private double speed;
public Car(String brand,String color) {
speed=0;
this.brand=brand;
this.color=color;
}
public String getBrand() {
return brand;
}
//获取属性方法:get属性名,没有参数,返回属性,返回值类型是属性类型
public String getColor() {
return color;
}
//设置属性的方法:set属性名,有形参,形参赋值给属性,没有返回值
public void setColor(String color) {
this.color = color;
}
public double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public static void main(String[] args) {
Car car=new Car("benz","black");
System.out.println(car.getBrand());
car.setSpeed(200);
System.out.println(car.getSpeed());
}
}
七、面向对象高级特性
1)继承
-
Java是 单重继承的
-
面向对象中在已有类的基础上扩展出新类的方式称为继承
-
父子类在一个包中,子类可以继承父类中的非私有属性和方法;父子类不在一个包中,子类可以继承 public 类中的public 属性和 protected 属性
属性看左边,方法看右边
package cn.tedu.design;
//1.通过归纳总结,使用关键字class抽象封装形成一个"类"组件来描述一类事物
class Car{
//2.属性--通过成员变量来描述
//2.1 属性的封装--通过关键字private对属性进行封装
private String brand;//品牌
private String color;//颜色
private double price;//价格
private double size;//尺寸
//3.行为--通过方法来描述
public void start(){
System.out.println("我的车车启动啦~");
}
public void stop(){
System.out.println("哎呀妈,我的车车熄火了~");
}
//2.2 给被封装的属性提供公共的属性值设置和访问方式--GetXxx()、SetXxx()
//快捷方式:右键->Generate->Getter and Setter->Shift全选->ok
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public double getSize() {
return size;
}
public void setSize(double size) {
this.size = size;
}
}
//4.创建一个宝马类并且继承汽车类--通过关键字extends建立继承关系
class BMW extends Car{
String color = "五彩斑斓的黑";
//6.子类对父类方法不满意时可以重写父类中的方法
//重写遵循两同两小一大原则,重写后,子类对象使用重写后的方法
@Override
public void stop(){
System.out.println("宝马当然要帅气的停的稳当些啦~");
}
}
//5.创建一个保时捷类并且继承汽车类--通过关键字extends建立继承关系
class BSJ extends Car{
String color = "黑不溜秋的白";
//7.新增子类特有功能--父类不可使用,只有子类对象可使用此功能
public void fly(){
System.out.println("启动加速度,我要起飞啦UP~UP~");
}
}
/*本类用于完成OOP汽车设计综合案例*/
public class DesignCar {
//创建程序的入口函数
public static void main(String[] args) {
//8.创建一个纯纯的父类对象进行测试
Car c = new Car();
System.out.println(c.getColor());//null,需要使用get()/默认值
c.start();//父类自己的功能
c.stop();//父类自己的功能
//c.fly();//父类不能使用子类的特有功能
//9.创建一个纯纯的子类宝马类对象
BMW b = new BMW();
System.out.println(b.color);//五彩斑斓的黑,子类新定义的同名属性
b.start();//没重写,使用的是父类的功能
b.stop();//重写了,使用的是自己重写以后的功能
//10.创建一个纯纯的子类保时捷类对象
BSJ b2 = new BSJ();
System.out.println(b2.getColor());//null
System.out.println(b2.color);//黑不溜秋的白
b2.start();//使用的是继承过来的父类中的功能
b2.fly();//使用的是子类特有的功能
}
}
继承中的构造方法:
-
可以通过这个关键字使用父类的内容,Super代表的是父类的一个引用对象
-
注意:在构造方法里,出现的调用位置必须是第一行
public class Person {
protected String id;
protected String name;
protected String birthday;
public Person(){}
public Person(String id,String name){
this.id=id;
this.name=name;
}
}
public class Teach extends Person{
public Teach(){
super();
}
public Teach(String id,String name){
super(id,name);
}
}
this与super的区别

2)多态
一种功能有多种实现。通过方法的重载和覆盖可以实现多态。
-
子类对象可以当作父类对象使用
-
父类对象不能当作子类对象使用
-
用 instanceof 操作符测试一个对象是否是一个类的实例
方法重载:
-
参数列表不同包括:参数数目不同,参数出现顺序不同,参数的类型不同.
-
静态绑定
方法覆盖(重写):
-
子类与父类之间 方法头相同 方法体不同
-
动态绑定
final作用:
-
修饰类:不能被继承
-
修饰方法:不能被覆盖
-
修饰属性:不能重新赋值
-
修饰常量:不能重新赋值
3)抽象类
-
抽象类:用abstract修饰的类。
-
只能用于继承,不能用于创建对象
-
抽象方法:用abstract修饰的方法只有方法头没有方法体。
抽象方法只能定义在抽象类中
package cn.tedu.oop;
//1.创建父类Animal
/*2.被abstract修饰的类是抽象类
* 如果一个类中包含了抽象方法,那这个类必须被声明成一个抽象类*/
//4.2添加抽象方法后,本类需要用abstract修饰
abstract class Animal{
//3.创建普通方法
public void eat(){
System.out.println("吃啥都行~");
}
public void play(){
System.out.println("玩啥都行~");
}
//4.1创建抽象方法
/*1.被abstract修饰的方法是抽象方法,抽象方法没有方法体*/
public abstract void fly();
public abstract void fly2();
}
//2.创建子类Pig,并与Animal类建立继承关系
/*3.当一个子类继承了抽象父类以后,有两种解决方案:
* 方案一:变成抽象子类,“躺平,我也不实现,继续抽象”
* 方案二:实现抽象父类中的所有的抽象方法,“父债子偿”*/
//4.3子类需要处理,继续抽象/实现父类所有抽象方法
//abstract class Pig extends Animal{--方案一
class Pig extends Animal{//方案二
@Override//注解,标识这是一个重写的方法
public void fly() {
System.out.println("我爸的债我终于还清了,我家的猪终于飞起来了~");
}
@Override
public void fly2() {
System.out.println("抽象父类中的所有抽象方法都需要被实现");
}
}
/*本类用作抽象测试的入门案例*/
public class AbstractDemo {
public static void main(String[] args) {
/*4.抽象类不可以实例化!!!-创建对象*/
//5.测试抽象父类是否可以创建对象
//Animal a = new Animal();
//6.创建多态对象进行测试
Animal a = new Pig();
a.eat();//调用抽象父类的普通方法
a.fly();//调用抽象父类的抽象方法
}
}
4)接口
-
Java中的接口可以多重继承、接口只能继承接口,不能继承类
-
接口定义与类定义相似,但只能包含 静态常量和抽象方法。
-
一种用于描述类对外提供功能规范的、能够多重继承的、特殊的抽象类。
-
通过interface关键字来定义接口
-
通过implements让子类来实现接口
-
接口不能实例化, 但是接口对象可以指向它的实现类对象。 List Set Map都是接口使用时先实现List <String> list = new ArrayList <>();
-
接口的所有成员方法都具有( public, abstract )修饰的特性
1、 定义一个接口Eatable,其中定义void eat ()抽象方法,以描述可食用功能的规范;
2、定义抽象类水果Fruit,包含一个表示颜色的属性和一个打印属性基本信息的方法;
package inter;
public interface IEatable {
void eat();
}
public abstract class Fruit {
String color;
public void show() {
System.out.println("color is "+color);
}
}
public class Apple extends Fruit implements IEatable{
@Override
public void eat() {
System.out.println("apple can be eaten");
}
public static void main(String[] args) {
}
}
八、异常处理
异常是指在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序
Java的异常处理是通过5个关键字来实现的: try、catch、 finally、throws(用在方法声明处)、throw(用在方法内部)
异常处理只有两种方式: try-catch 和 throws,所以必须二选一

九、集合框架
Java集合框架提供了一套性能优良、使用方便的接口和类,它们位于 java.util包中

Collection 接口存储一组 不唯一,无序的对象
List 接口存储一组 不唯一,有序(插入顺序)的对象
Set 接口存储一组 唯一,无序的对象
Collection保存单一元素,而Map保存相关联的键值对。
1)List接口实现类
ArrayList实现了 长度可变的数组,在内存中分配连续的空间。遍历元素和随机访问元素的效率比较高
LinkedList采用链表存储方式。插入、删除元素时效率比较高
List接口常用方法:

2)ArrayList集合类
package arraylist;
//编写一个用户管理类(UserManager),在类中定义一个Vector或ArrayList的成员变量,该变量保存所有的用户,用户对应的类型为User。在类中定义如下几个方法:
//添加一个用户。
//删除一个用户。
//判断一个用户是否存在。
//显示所有用户信息(User对象有toString方法可以显示用户信息)。
//User类:有个名字属性、有个toString方法,返回用户信
import java.util.*;
public class UserManager {
ArrayList<User> users=new ArrayList<>();//泛型:数据类型参数化——为了安全
public void addUser(User u) {
users.add(u);
}
public void removeUser(int i) {
users.remove(i);
}
public void removeUser(User i) {
users.remove(i);
}
// public void removeUser(String name) {
// for(int i=0;i<users.size();i++) {
// User u=(User)users.get(i);
// }
// }
public boolean isExistUser(User u) {
return users.contains(u);
}
// public void display (){
// for(int i=0;i<users.size();i++) {
// User u=(User)users.get(i);
// System.out.println(u);
// }
// }
public void display() {
Iterator<User> it=users.iterator();//获取集合users的迭代器it
while(it.hasNext()){
//hasnext方法是判断集合中是否有元素
User u=it.next();//next()获取集合中的元素
System.out.println(u);
}
// for(User u:users) {
// System.out.println(u);
// }
}
public static void main(String[] args) {
UserManager um=new UserManager();
User u1=new User("zhang1");
User u2=new User("zhang2");
User u3=new User("zhang3");
um.addUser(u1);
um.addUser(u2);
um.addUser(u3);
um.display();
um.removeUser(2);
System.out.println("------------------------------");
um.display();
um.removeUser(u1);
System.out.println("------------------------------");
um.display();
}
}

3)Map接口

package test;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/*本类用于测试Map接口*/
public class TestMap {
public static void main(String[] args) {
//1.创建Map对象
/*Map中的数据要符合映射规则,一定注意要同时指定 K 和 V 的数据类型
* 至于这个K和V要指定成什么类型的数据,取决于你的具体需求 */
Map<Integer,String> map = new HashMap<>();//注意导包:java.util
//2.常用方法测试
map.put(9527,"白骨精");//向集合中添加数据
map.put(9528,"黑熊精");
map.put(9528,"者行孙");
map.put(9529,"黄毛怪");
System.out.println(map);//查看集合中的元素
/*总结1:Map中存放的都是无序的数据
总结2 :Map中的key不可以重复,如果重复,此Key对应的Value会被覆盖
打印结果:{9527=白骨精, 9528=者行孙, 9529=黄毛怪},没有黑熊精*/
//3.测试常用方法
//map.clear();//清空集合
System.out.println(map.containsKey(9528));//true,查看是否包含指定的Key
System.out.println(map.containsValue("土地老儿"));//false,查看是否包含指定的Value
System.out.println(map.equals("者行孙"));//false,判断"者行孙"与map对象是否相等
System.out.println(map.get(9528));//者行孙,根据指定的Key来获取对应的Value
System.out.println(map.hashCode());//102939160,获取哈希码值
System.out.println(map.isEmpty());//false,判断集合是否为空
System.out.println(map.remove(9528));//删除指定的元素
System.out.println(map.get(9528));//null,说明映射关系已被移出
System.out.println(map.size());//2,获取集合中元素的个数
Collection<String> values = map.values();//把map集合中的所有Vlaue收集起来放到Collection中
System.out.println(values);//[白骨精, 黄毛怪]
}
}
4)遍历集合
-
迭代器Iterator
*获取Iterator :Collection 接口的iterate()方法
boolean hasNext(): 判断是否存在另一个可访问的元素
Object next(): 返回要访问的下一个元素
例子:
List users=new ArrayList();
Iterator it=users.iterator();//获取集合users的迭代器it
while(it.hasNext()) {//hasnext方法是判断集合中是否有元素
User u=(User)it.next();//next()获取集合中的元素
System.out.println(u);
}
-
增强for型循环
语法:for(元素类型t 元素变量x : 数组或集合对象){
引用了x的java语句
}
ArrayList<String> users=new ArrayList();
for(String x:users) {
System.out.println(x);
}
ArrayList<User> users=new ArrayList<>();
for(User u:users) {
System.out.println(u);
}
5)泛型集合
泛型就是指参数化类型,也就是说所操作的数据类型被指定为一个参数。
语法:类名<声明自定义泛型>
ArrayList<String> users=new ArrayList();
ArrayList<User> users=new ArrayList<>();//User为一个类
HashMap<String,String> countries=new HashMap<>();
6)基本数据类型的封装类
byte -----Byte
short -----Short
int -----Integer
long-----Long
float -----Float
double ------Double
char------Character
boolean------Boolean
Java基本数据类型存储在栈中
封装类实例对象存储在堆中
基本数据类型,数据存储相对简单,运算效率比较高。
集合中的元素要求必须是对象类型,因此需要使用数据类型的封装类。
十、文件与流
_流_是指一连串流动的字符,是以先进先出的方式发送信息的通道。


1.File类中的( )方法可以用来判断文件或目录是否存在。B
A.exists() B. exists() C.fileExist() D.fileExists()
2.File 类中的( )方法可以用来获取文件的大小。A
A.length() B.size() C.getLength() D.getSize()
3、文本文件的读写过程中,需要处理下列( B)异常。
A.ClassNotFoundException B.IOEception C.SQLEception D.RemoteExcepition
4.字符流是以( )传输数据的。C
A.1个字节 B.8个字节 C.16位Unicode字符 D.1比特
5.( )方法 可以用来清空流。D
6.以下声明( )是对BufferedReader的正确声明。A
-
JDK 中与输入输出相关的包和类都集中存放在 java.io 包中。
-
Java IO最重要的 5 个 类: File 、 InputStream 、 OutputStream 、 Reader 和 Writer 。
-
按 Java 的命名惯例,凡是以 InputStream 结尾的类型为字节输入流,以 OutputStream 结尾的类型为字节输出流。凡是以 Reader 结尾的类均为字符输入流,以 Writer 结尾的类均为字符输出流。
-
File 类是对文件和文件夹的一种抽象表示(引用或指针)。
-
DataInputStream 类直接从底层输入流读取 Java 的八种基本类型数据, DataOutputStream 类能够将 Java 基本类型数据写出到一个底层输出流。
-
Java 通过 ObjectOutputStream 类实现对象的序列化,通过 ObjectInputStream 类实现对象的反序列化。
-
只有实现 Java.io. Serializable 接口的类的对象才能被序列化和反序列化。用关键字 transient 修饰的对象变量将不会序列化。
-
POI 是 Apache 软件基金会的开放源码程序库,它提供通过 Java 语言对 Microsoft Office 文件进行读写的 API ,支持 Office97-2008 文档格式。
十一、JDBC技术
1、JDBC API
内容:供程序员调用的接口与类,集成在 java.sql和 javax.sql包中,
如:DriverManager类 、Connection接口 、Statement接口、 ResultSet接口
2、DriverManager作用:管理各种不同的JDBC驱动
3、JDBC 作用:负责连接各种不同的数据库
4、JDBC API 主要功能:与数据库建立连接、执行SQL 语句、处理结果
-
DriverManager :依据数据库的不同,管理JDBC驱动
-
Connection :负责连接数据库并担任传送数据的任务
-
Statement :由 Connection 产生、负责执行SQL语句
-
ResultSet:负责保存Statement执行后所产生的查询结果

Statement常用方法:

ResultSet常用方法

PreparedStatement的用法:
继承自 Statement接口,比Statement对象使用起来更加灵活,更有效率

package JDBCtest;
import java.sql.*;
public class JDBCTest {
public static void main(String[] args) {
try {//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
System.out.println("driver success");
//2.建立连接
String url="jdbc:mysql://localhost:3306/test";
String user="root";
String passwd="123456";
Connection conn=DriverManager.getConnection(url,user,passwd);
Statement stmt=conn.createStatement();
//4.生成sql语句
String sql="select * from user";
//5.语句对象执行sql语句
ResultSet rs=stmt.executeQuery(sql);
//6.遍历结果集
while(rs.next()) {
System.out.println(rs.getInt("id"));
}
// sql="insert into user values('2','lisi')";
// stmt.executeUpdate(sql);
//释放资源
stmt.close();
conn.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
十二、图形用户界面
GUI 组件 (Component) :构成 GUI 界面的基本元素,具有坐标位置、尺寸、字体、颜色等属性,能获得焦点、可被操作、可响应事件等。例如:在 swing 组件中, JLabel 类用来实现不可编辑信息, JButton 类用来实现命令按钮, JTextFiled 类用来实现单行文本框, JPasswordField 类用来实现密码框, JTextArea 用来实现多行文本框等。
顶级容器 JFrame 的布局管理器默认为 BorderLayout ,中间容器 JPanel 的布局管理器默认为 FlowLayout 。
1、GUI界面由GUI组件构成,Java中有两套GUI组件类
-
awt组件(java.awt包中)
-
swing组件(javax.swing包中)
2、图形类可分为三组:容器类、组件类、辅助类
-
容器类:如JFrame、JPanel和JApplet等,用来包含其他组件。
-
组件类:如JButton、JTextField、JTextArea、JComboBox、JList、JRadioButton、JMenu等,都是JComponent类的子类。
-
辅助类:如Color、Font、FontMetrics、Dimension和LayoutManager等,是组件和容器用于绘制和放置对象的。
3、
1)创建框架(使用JFrame)
1. public void setSize(int width , int height):窗体大小
2. public void setVisible(boolean b):窗体是否可见
3. setLocationRelativeTo(null):设置框架的位置,若该组件为null,那么框架在屏幕中居中
4. setForeground(Color c):以参数c设置窗口的前景颜色
5. setBackground(Color c):以参数c设置窗口的背景颜色。
6. getContentPane():获得内容面板,框架是一种复合容器,它本身并不容纳组件,向框架添加组件实际上是添加到框架上的内容窗格中
7. public void setDefaultCloseOperation(int operation)
8. JFrame.EXIT_ON_CLOSE 当框架关闭时结束程序
2)标签
添加:标签等组件不会自动显示,必须用 add( 标签对象名 ) 方法把它放到容器中。
向 JFrame 添加标签等组件的方法是:
1. 先由 getContentPane() 方法获得主窗口的内容面板
2. 再调用 add( 组件对象名 ) 将组件加入。
JLabel() :创建空标签
JLabel(String text) :创建内容为text 的标签
JLabel(String text,int align) :创建内容为text ,对齐方式为align 的标签,align 为水平对齐方式,其值可以为:JLabel.LEFT 、JLabel.RIGHT 、JLabel.CENTER
JLabel(String text,Icon icon,int align)
3)按钮
作用:接收用户的单击输入,产生动作事件从而响应某种操作。
JButton() : 创建一个无显示文字的按钮
JButton(String text) :创建一个显示文字为text 的按钮
4)Jpanel面板
是一个中间容器,用于容纳组件,但它本身必须添加到其他容器中使用。
构造方法
JPanel() :创建一个空面板。
JPanel 添加组件的方法:
add( 组件) :向面板中添加组件。
5)Java布局管理器
* FlowLayout(流式布局)
* BorderLayout (边界布局):把容器分为5个区:东区(EAST)、南区
(SOUTH)、西区(WEST)、北区(NORTH)和 中区(CENTER)。这几个区的分布规律是“上 北下南,左西右东中”。每个区域中只能放1 个组件。
* GridBagLayout(网格包布局)
- 手工布局
6)为事件注册监听器

8)
文本框(JTextField):用来接受用户键盘输入的单行文本。
单选按钮(JRadioButton):从一组选项中选中唯一的一个选项,选项之间是互斥的。
要在一组单选按钮中实现多选一,必须将它们分组, 使用ButtonGroup创建组,然后用add()方法将单选 按钮加入到组中。
复选框(JCheckBox):对多个选项的同时选择,选项之间不互斥。
文本区( JTextArea):用于接受来自用户的多行文本。
方法:
* String getText():获取多行文本区中的文本
* void setText(String s):设置多行文本区中的文本
滚动面板(JScrollPane):
对话框:JOptionPane():JavaSwing 内部已实现好的,以静态方法的形式提供调用,能够快速方便的弹出要求用户提供值或向其发出通知的标准对话框。
菜单组成:
1. 一个菜单栏(JMenuBar)
2. 每个菜单栏中包含多个菜单(JMenu)
3. 每个菜单中包含多个菜单项(JMenuItem)
package mainpro;
import java.awt.*;
import java.sql.*;
import javax.swing.*;
import publicmodule.DbOp;
public class Login extends JFrame implements ActionListener{
private static final long serialVersionUID = 377287301994613384L;
static String user2;//设置静态属性(后面修改密码时可直接通过类名.属性名调用获取用户名)
//添加标签
Label lbname = new Label("用户名");
Label lbpassword = new Label("密码");
//设置按钮
Button ok=new Button("确定");
Button cancel=new Button("取消");
//添加文本框
JTextField tf_name = new JTextField();//账号
JPasswordField tf_password = new JPasswordField();//用户名
//构造函数
public Login() {
setLayout(null);//将容器的布局设为绝对布局
setTitle("登录");//容器标题
setSize(400, 250);//设置容器大小
//设置标签、文本框、按钮位置
lbname.setBounds(100, 50, 50, 20);
tf_name.setBounds(160, 50, 100, 20);
lbpassword.setBounds(100, 80, 50, 20);
tf_password.setBounds(160, 80, 100, 20);
ok.setBounds(110, 110, 80, 25); // 保存按钮
cancel.setBounds(200, 110, 80, 25);// 关闭按钮
cancel.addActionListener(this);//事件监听对象,并且this指本身这个对象,这个类会实现监听器这个接口。
//添加组件
add(lbname);
add(tf_name);
add(lbpassword);
add(tf_password);
add(ok);
add(cancel);
setLocationRelativeTo(null); // 使窗体在屏幕上居中放置
setVisible(true); // 使窗体可见
//为确定按钮注册监听器
ok.addActionListener(new ActionListener() {
//产生的事件对象的处理方法
public void actionPerformed(ActionEvent e) {
if(e.getSource()==ok) {
//获取输入的账号和密码
user2= tf_name.getText();
String passwd=new String(tf_password.getPassword());
String isadmin;
//判断输入的账号密码是否为空
if(user2 == null || "".equals(user2.trim())) {//trim()的作用是去掉字符串两端的多余的空格
JOptionPane.showMessageDialog(null, "账号不能为空");
return;
}
if(passwd == null || "".equals(passwd.trim())) {
JOptionPane.showMessageDialog(null, "密码不能为空");
return;
}
//查找是否有该用户
String sql="select * from user where username ='"+user2+"' and password ='"+passwd+"' ";
// System.out.println(sql);//测试使用
//设置结果集
ResultSet currentId=DbOp.executeQuery(sql);
// System.out.println(currentId);
try {
//如果存在该用户则进入到图书管理系统界面
if(currentId.next() ) {
isadmin=currentId.getString("is_admin");//获取该用户是否是管理员,
dispose();//退出登录界面
ShowMain show=new ShowMain();
show.setRights(isadmin);//查看用户是否是管理员
//如果不存在该用户会显示报错信息
}else {
JOptionPane.showMessageDialog(null, "用户不存在或密码错误");
}
} catch (HeadlessException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
});
}
//测试使用
public static void main(String[] args) {
new Login();
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==cancel)
dispose();
}
}
十三、多线程
程序(program)是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象。
进程(process)是程序的一次执行过程,或是正在运行的一个程序。动态过程:有它自身的产生、存在和消亡的过程。——生命周期
线程(thread), 进程可进一步细化为线程,是一个程序内部的一条执行路径。
-
Thread类的特性
-
每个线程都是通过某个特定Thread对象的run()方法来完成操作的,经常把run()方法的主体称为线程体
-
通过该Thread对象的start()方法来调用这个线程
-
创建线程的两种方式:
1.继承Thread类
1) 定义子类继承Thread类。
2) 子类中重写Thread类中的run()方法。
——将此线程执行的操作声明在run()方法中
3) 创建Thread子类对象,即创建了线程对象。
4) 调用线程对象start方法:启动线程,调用run方法。
2.实现Runnable接口
1)定义子类,实现Runnable接口。
2)子类中重写Runnable接口中的run方法。
3)通过Thread类含参构造器创建线程对象。
4)将Runnable接口的子类对象作为实际参数传递给Thread类的构造器中。
5)调用Thread类的start方法:开启线程,调用Runnable子类接口的run方法。
Thread类的有关方法
-
void start(): 启动线程,并执行对象的run()方法
-
run(): 线程在被调度时执行的操作
-
String getName(): 返回线程的名称
-
void setName(String name):设置该线程名称
-
static currentThread(): 返回当前线程
-
static void yield():线程让步。暂停当前正在执行的线程,把执行机会让给优先级相同或更高的线程,若队列中没有同优先级的线程,忽略此方法
-
join() :当某个程序执行流中调用其他线程的 join() 方法时,调用线程将被阻塞,直到 join() 方法加入的 join 线程执行完为止 、 低优先级的线程也可以获得执行
-
static void sleep(long millis):(指定时间:毫秒) 令当前活动线程在指定时间段内放弃对CPU控制,使其他线程有机会被执行,时间到后重排队。 抛出InterruptedException异常
-
stop(): 强制线程生命期结束
-
boolean isAlive():返回boolean,判断线程是否还活着

需求:设计4个售票窗口,总计售票100张。用多线程的程序设计并写出代码
package cn.tedu.tickets;
/*需求:设计多线程编程模型,4个窗口共计售票100张*/
/*本类通过继承Thread类的方式实现多线程售票案例*/
public class TestThread {
public static void main(String[] args) {
//5.创建多个线程对象 Ctrl+D 复制当前行
TicketThread t1 = new TicketThread();
TicketThread t2 = new TicketThread();
TicketThread t3 = new TicketThread();
TicketThread t4 = new TicketThread();
//6.以多线程的方式启动
t1.start();
t2.start();
t3.start();
t4.start();
}
}
//1.自定义线程售票业务类
class TicketThread extends Thread{
//3.定义变量,用来保存票数
//int tickets = 100;//不可以,会卖400张票
//7.解决4个线程卖了400张票的BUG
static int tickets = 100;//静态资源属于类资源,被全局所有对象共享,只有一份
//2.把业务写在重写run()里
@Override
public void run() {
//4.通过循环结构来一直卖票
while (true){
try {
//8.如果数据能够经受住sleep的考验,才能说明数据没有了安全隐患--人为制造问题
//问题1:产生了重卖:同一张票卖给了多个人
//问题2:产生了超卖:超出了规定票数,甚至卖出了0和-1这样的票数
Thread.sleep(10);//让程序休眠10ms
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName()+"="+tickets--);
//做判断,如果没有票了,就退出死循环
if(tickets <= 0) break;//注意,死循环一定要设置出口
}
}
}
推荐内容
阅读全文
AI总结
更多推荐
相关推荐
查看更多
llama_index

LlamaIndex(前身为GPT Index)是一个用于LLM应用程序的数据框架
halo

强大易用的开源建站工具。
freeCodeCamp

freeCodeCamp.org的开源代码库和课程。免费学习编程。
热门开源项目
活动日历
查看更多
直播时间 2025-04-25 15:00:00


直播时间 2025-04-23 19:00:00

GitTalk:国内首个微服务编排框架Juggle实战解析
直播时间 2025-04-22 18:31:56

字节AI 黑科技!从 Manus Agent 入门 Eino
直播时间 2025-04-09 14:34:18

樱花限定季|G-Star校园行&华中师范大学专场
直播时间 2025-04-07 14:51:20

樱花限定季|G-Star校园行&华中农业大学专场
目录
所有评论(0)