一、javase
(一)计算机概述
Java程序开发运行流程
三个步骤
- 编写代码
- 编译代码
- 运行代码
一些idea的快捷键
psvm + 回车 --> 自动生成主方法
public static void main(String[] args) {
}
sout+ 回车-->自动生成输出语句
System.out.printin();
TODO:
使用TODO来标记代码,一般是用来表示待完成或者待解决的部分
public class A {
//TODO: 缺少一个主方法需要补产
}
ctrl + D : 向下复制一行
关键字:被Java赋予了特定涵义的英文单词
- 关键字的字母全部小写
- 常用的代码编辑器,针对关键字有特殊的颜色标记,非常直观。
Java 基础语法
常量概述
常量:在程序的执行过程中,其值不会发生改变的量 (数据)
常量的分类:
- 字符串常量: 被双引号包裹的内容
- 整数常量: 所有整数
- 小数常量: 所有小数
- 字符常量: 被单引号所包裹的内容,内部只能存放单个字符,多一个少一个都不行
- 布尔常量: true false
- 如果低仅只是打印的话,意义不大.
会在后面学习的运算符当中进行使用。
- 如果低仅只是打印的话,意义不大.
- 空常量: null --> 不能直接打印
进制介绍
进制:指进位制,是人们规定的一种进位方式表示某一位置上的数,运算时是逢X进一位。
- 十进制——逢十进一
- 二进制——逢二进一
- 八进制——逢八进一
进制转换示例
二进制到十进制的转换
- 公式:系数*基数的权次幂 相加
- 系数:每一[位]上的数
- 基数:几进制,就是几
- 权:从数值的右侧,以0开始,逐个+1增加
常见进制:二进制,八进制,十进制,十六进制
每一个字节,在计算机底层,都是以二进制的形式进行体现的。
不同进制的书写格式
- 十进制: Java中,数值默认都是10进制,不需要加任何修饰。
- 二进制:数值前面以0b开头,b大小写都可以。
- 八进制:数值前面以0开头。
- 十六进制:数值前面以0x开头,x大小写都可以。
变量
内存中的存储空间,空间中存储着经常发生改变的 (数据)
变量的定义和使用
- 定义:数据类型变量名=数据值;
- 使用:根据变量名进行使用
Debug工具
Debug:供程序员使用的程序调试工具
它可以用于查看程序的执行流程,也可以用于追踪程序执行过程来调试程序
Debug操作流程
Debug调试,又被称为断点调试,断点其实是一个标记,告诉Debug从标记的地方开始查看
- 如何加断点
- 如何运行加了断点的程序
- 看哪里
- 点哪里
- 如何删除断点
变量的注意事项:
- 变量名不允许重复
- 一条语句可以定义多个变量 中间需要使用逗号分隔了
- 变量在使用之前,一定要进行赋值
标识符概述
标识符:就是给类,方法,变量等起名字的符号。
标识符命名规则
- 由数字、字母、下划线()和美元符(S)组成
- 不能以数字开头
- 不能是关键字
- 区分大小写
小驼峰命名法
适用于——方法、变量
- 规范1:标识符是一个单词的时候,首字母小写
- eg1: name
- 规范2:标识符由多个单词组成的时候,第一个单词首字母小写,其他单词首字母大写
- eg2: firstName
大驼峰命名法
适用于——类
- 规范1:标识符是一个单词的时候,首字母大写
- eg1: Student
- 规范2:标识符由多个单词组成的时候,每个单词的首字母大写
- eg2:GoodStudent
数据类型介绍
基本数据类型
整数类型:
byte
short
int
long
小数类型:
float
double
字符类型:
char
布尔类型:
boolean
注意:
在定义Long类型变量的时候,需要加入L的标识(大小写都可以,建议大写)
public static void main(String[] args)
// 整数类型变量
byte num1 = 10;
short num2 = 20;
int num3 = 30;
long num4 = 1234567891234567899L;
System.out.println(num1);
System.out.println(num2);
System.out.println(num3):
System.out.printn(num4);
System.out.println("----------")
// 小数类型变量
float num5 = 12.3F;
System.out.printin(num5);
double num6 = 12.3;
System.out.printn(num6);
// 字符类型变量
char c1 ='中';
System.out.printin(c1);
char c2 = 97;
System.out.println(c2);
// 布尔类型变量
boolean flag = false;
System.out.printin(flag);
boolean flag2 = true;
System.out.println(flag2);
// 字符串类型变量的定义使用: String
String name = "张三";
键盘录入:
Scanner 键盘录入:
- 找到Scanner符咒
- 召唤Scanner精灵
- 指挥Scanner干活
键盘录入(输入文字)示例
public static void main(String[] args) {
// 召唤Scanner精灵,起名叫sc
Scanner sc = new Scanner(System.in);
System.out.printn("请输入一个整数:");
int age = sc.nextInt();
System.out.printin(age);
}
引用数据类型
(二)运算符
运算符和表达式
- 运算符:对常量或者变量进行操作的符号
- 表达式:用运算符把常量或者变量连接起来符合iava语法的式子就可以称为表达式不同运算符连接
表达式体现的是不同类型的表达式。
数值拆分代码例子
public static void main(String[] args) { /* 需求:键盘录入一个三位数,将其拆分为个位、十位、百位后,打印在控制台 分析: 1: 使用Scanner健盘录入一个三位数 2: 个位的计算:数值 % 10 3: 十位的计算: 数值 / 10 % 10 4: 百位的计 算:数值 10 /10 % 10 */ // 1: 使用Scanner键盘录入一个三位数 Scanner sc = new Scanner(System.in); System.out.println("请输入一个三位数:"); int num = sc.nextInt() ; // 2: 个位的计算:数值 % 10 int ge = num % 10; // 3: 十位的计算: 数值 / 10 % 10 int shi = num / 10 % 10; // 4: 百位的计算: 数值 / 10 /10 % 10 int bai = num / 10 / 10 % 10; System.out.println(ge); System.out.println(shi); System.out.println(bai); }
字符串的"+"操作
当"+"操作中出现字符串时,这个"+"是字符串连接符,而不是算术运算。
public static void main(String[] args) { /* 字符串的 + 操作 当加号操作中出现字符串时,这个 + 是字符串连接符,而不是算术运算。 */ // 陌景生666 System.out.println("陌景生" + 666); // 100年太短,只争朝夕 System.out.println(1 + 99 + "年太短,只争朝夕"); }
自增自减运算符
自增自减运算符:
++变量的值自身加一
--变量的值自身减一
单独使用:
符号在前在后,没有区别
参与运算使用:
++在前: 变量先完成自增长,然后再参与运算
++在后: 会先将该变量原本记录的值,提取出来参与运算,然后变量再进行自增长
注意事项: 自增自减运算符只能操作变量,不能操作常量
注意事项:
单独使用的时候,++和- 无论是放在变量的前边还是后边,结果是一样的。
参与操作的时候
如果放在变量的后边,先将该变量原本的值,取出来参与操作,随后再进行自增(++),自减(--)。inta=10:
int b = a++:
如果放在变量的前边,变量先完成自增长,然后再参与运算
int a = 10:
int b = ++a;
隐式转换介绍
- 把一个取值范围小的数值或者变量,赋值给另一个取值范围大的变量
- 运算中的隐式转换
- 取值范围小的数据,和取值范围大的数据进行运算,小的会先提升为大的之后,再进行运算
- byte,short,char三种数据在运算的时候,都会提升为int,然后再进行运算
强制转换介绍
把一个取值范围大的数值或者变量,赋值给另一个取值范围小的变量不允许直接赋值,需要加入强制转换
格式: 目标数据类型 变量名 = (标数据类型)被强转的数据
int a = 130;
byte b = (byte) a;
注意: 强转有可能会出现精度的损失.
大的给小的,不能直接给,需要进行类型转换
原码反码补码
- 原码
- 数据的二进制体现形式,一个字节由8个二进制位组成
- 高位:二进制数据中,最左侧的数据,通过高位代表符号位
0代表正数
1代表负数
其余位表示数值大小
- 反码
- 正数的反码与其原码相同负数的反码是对其原码逐位取反,但符号位除外
- 补码
- 正数的补码与其原码相同
- 负数的补码是在其反码的末位加1
赋值运算符
基本赋值运算符:
= : 将符号右侧的数据,赋值给左侧的变量
扩展赋值运算符(自带强转效果):
+= : 将符号左右两边的数据,做加法运算,再将结果赋值给左边
-= : 将符号左右两边的数据,做减法运算,再将结果赋值给左边
*= :略
/= : 略
%= : 略
-
关系运算符
- 作用: 用于数据之间的比较
- 分类: (>) (>=) (<) (<=) (==) (!=)
逻辑运算符
逻辑运算符: 用于【整合】多个关系表达式,成为一个逻辑条件
1.连接多个关系表达式
2.连接true或false
最终得到的结果都是boolean类型的true或false.
逻辑运算符分类 :
&(与) : 并且——符号连两边同时为true结果才为true|(或) : 或者——有真则真
!(非) : 取反
^(异或) :相同为false,不同为true
应用场景;
需求: 键盘录入学生成绩,如果是90~100之间,程序输出[优秀]
判断条件(score >= 90 & score <= 100)
需求:键盘录入工人工号,只要3号或者5号或者7号
判断条件(id == 3 id == 5 id == 7)
短路逻辑运算符
注意事项
- 逻辑与 &,无论左边 true false,右边都要执行
- 短路与 &&,如果左边为 true,右边执行;如果左边为 false,右边不执行
- 逻辑或|,无论左边 true false,右边都要执行
- 短路或||,如果左边为 false,右边执行;如果左边为 true,右边不执行
三元运算符格式
三元运算符格式:
关系表达式 ? 值1 : 值2;
判断条件 ? 值1 : 值2;
执行流程:
首先计算关系表达式的值如果值为true,取值1如果值为false,取值2
需求:求两个整数的最大值
案例:求三个整数的最大值
需求:键盘录入三个整数,找出最大值并打印在控制台。
分析:
使用 Scanner 键盘录入三个整数
用三元运算符获取前两个整数的最大值,并用临时变量保存起来。
用三元运算符,让临时最大值,和第三个整数,进行比较,并记录结果。
输出结果
public static void main(String[] args) {
// 1.使用 Scanner 键盘录入三个整数
Scanner sc = new Scanner(System.in);
System.out.println("请输入三个整数:");
int num1 = sc.nextInt();
int num2 = sc.nextInt();
int num3 = sc.nextInt();
// 2.用三元运算符获取前两个整数的最大值,并用临时变量保存起来。
int temp = num1 > num2 ? num1 : num2;
// 3.用三元运算符,让临时最大值,和第三个整数,进行比较,并记录结果.
int max = temp > num3 ? temp : num3;
// 4.输出结果
System.out.println("最大值是:" + max);
}
运算符优先级
(三)分支语句
流程控制
流程控制语句:通过一些语句,来控制程序的[执行]流程
流程控制语句分类
- 顺序结构(按照顺序依次执行)
- 分支结构 (if、switch)
- 循环结构 (for、whiledo..while)
if语句
if语句格式1
if (关系表达式) { 语句体; }
执行流程:
- 首先计算关系表达式的值
- 如果关系表达式的值为true就执行语句体
- 如果关系表达式的值为false就不执行语句体
- 继续执行后面的语句内容
if语句格式2
if (关系表达式) { 语句体1; } else { 语句体2; }
if语句格式3
if (判断条件1){ 语句体1; }else if (判断条件2) { 语句体2; } …… else { 语句体n+1; }
执行流程
首先计算判断条件1的值
如果值为true就执行语句体1; 如果值为fa se就计算判断条件2的值如果值为true就执行语句体2;如果值为false就计算判断条件3的值
……
如果没有任何判断条件为true,就执行语句体n+1。
案例:考试奖励
需求:小明快要期末考试了,小明爸爸对他说,会根据他不同的考试成绩,送他不同的礼物,假如你可以控制小明的得分,请用程序实现小明到底该获得什么样的礼物,并在控制台输出。
public static void main(String[] args) {
/*
需求: 键盘录入考试成绩,根据成绩所在范围,程序打印出不同的奖励。
分析:
1.键盘录入考试成绩
2.由于奖励种类较多,属于多种判断,采用if...else...if格式实现
3.为每种判断设置对应的条件
4.为每种判断设置对应的奖励
标准:
95~100: 山地自行车一辆
90~94: 游乐场玩一次
80~89: 变形金刚玩具一个
80分以下: 挨揍
*/
// 1.录入考试成绩
Scanner sc = new Scanner(System.in);
System.out.println("请输入您的成绩:");
int score = sc.nextInt();
// 2.由于奖励种类较多,属于多种判断,采用if...else...if格式实现
// 3.为每种判断设置对应的条件
if (score < 0 || score > 100){
System.out.println("您的成绩输入有误");
}else if (score >= 95 && score <= 100) {
// 4.为每种判断设置对应的奖励
System.out.println("山地自行车一辆");
}else if(score >=90&&score <=94){
System.out.println("游乐场玩一次");
}else if(score >=80&&score <=89){
System.out.println("变形金刚玩具一个");
}else
System.out.println("挨顿揍");
}
if语句的注意事项
- if 语句中,如果大括号控制的是一条语句,大括号可以省略不写
- if 语句的 ( ) 和 } 之间不要写分号
switch语句
switch语句格式
switch(表达式){ case 值1: 语句体1; break; case 值2: 语句体2; break; …… default: 语句体n+1; break; }
格式说明
- 表达式:(将要匹配的值) 取值为byte、short、int、char,JDK5以后可以是枚举,JDK7以后可以是Stringo
- case:后面跟的是要和表达式进行比较的值 (被匹配的值)
- break:表示中断,结束的意思,用来结束switch语句。
- default:表示所有情况都不匹配的时候,就执行该处的内容,和if语句的else相似。
执行流程
- 拿着表达式的值,依次和case后面的值进行匹配,匹配成功,就会执行对应的语句,在执行的过程中,遇到break就会结束
- 如果所有的case都不匹配,就会执行default里面的语句体,然后程序结束掉。
使用场景(建议)
- 如果要进行的判断,是范围性的判断,建议使用if
- 如果要进行的判断,是固定值的匹配,建议使用switch
例子:判断星期几的
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int week = sc.nextInt();
switch(week){
case 1:
System.out.println("星期一");
break;
case 2:
System.out.println("星期二");
break;
case 3
System.out.println("星期三");
break;
case 4:
System.out.printn("星期四");
break;
case 5:
System.out.println("星期五")
break;
case 6:
System.out.println("星期六");
break;
case 7:
System.out.println("星期日");
break;
default:
System.out.println("数据有误");
break;
}
面向对象基础
类和对象
四句代码出窗体(长宽高位置)
窗体绘制
import javaxswing.JFrame;
JFrame frame=new JFrame();
framesetSize(514,538);
frame.setVisible(true);
类的组成
类的组成:属性和行为
- 属性:在类中通过成员变量来体现
public class Student (
String name =“张三”
int age = 23;
}
- 行为:在类中通过成员方法来体现
类和对象的关系
- 类:是对事物的一种描述,可以将类理解为一张设计图
- 对象:真实存在的事物
根据设计图,可以创建出具体存在的事物
成员变量
类的定义
对象的创建和使用
使用方法
/*
创建对象的格式:
类名 对象名 = new 类名();
使用成员变量的格式:
对象名.变量名;
注意:
1.打印对象名的时候,会出现对象在内存中的地址值.com.itheima.demo1.Student@b4c966a
2.成员变量就算没有赋值, 也可以直接使用,但使用的是默认初始化值
整数: 0
小数: @.@布尔: false
字符:\U0000'空白字符
字符串: null
3.引用数据类型:引用、记录了一份地址值的变该变量所对应的数据类型就是引用数据类型(类、数组、接口)
*/
public class Student{
String name = "张三";
int age = 23;
}
public static void main(String[] args) {
Student stu = new Student();
System.out.printin(stu);
System.out.println(stu.name);
System.out.printin(stu.age);
}
改进:
public class Student{
String name;
int age;
}
public static void main(String[] args) {
Student stu = new Student();
System.out.printin(stu);
System.out.println(stu.name + "-----" + stu.age);
stu.name="花果山水帘洞";
stu.age="1000";
System.out.println(stu.name + "-----" + stu.age);
}
成员方法
成员方法的定义格式
格式:
public void 方法名() {
// 方法体
}
示例:
public class Student {
String name;
int age;
/*
成员方法的定义格式:
public void 方法名(){
// 方法体
}
*/
public void show(){
System.out.println("学生学习JavaSE");
System.out.println("学生学习JavaWeb");
System.out.println("学生学习JavaEE");
System.out.printn("学生睡觉");
System.out.println("学生吃饭");
}
}
//-------------------------------------------------
public class TestStudent {
/*
成员方法的调用格式:
对象名.方法名();
*/
public static void main(String[] args) {
Student stu = new Student();
stu.name = "钢门吹雪";
stu.age = 23;
System.out.println(stu.name + "---" + stu.age);
stu.show();
}
成员方法的调用格式
- 格式: 对象名.方法名();
- 范例: stu.show();
- 方法必须先创建才可以使用,该过程称为方法定义
- 方法创建后并不是直接运行的,需要手动使用后才执行,该过程称为方法调用
方法的作用
- 提高代码的复用性
- 提高代码的可阅读性
方法的注意事项
- 方法不调用就不执行
- 方法与方法之间是平级关系,不能嵌套定义
- 方法的定义顺序和执行顺序无关
public class Student {
String name;
int age;
/*
成员方法的定义格式:
public void 方法名(){
// 方法体
}
*/
public void study(){
System.out.println("学生学习JavaSE");
System.out.println("学生学习JavaWeb");
System.out.println("学生学习JavaEE");
}
public void eat(){
System.out.println("学生吃饭");
}
public void sleep(){
System.out.println("学生睡觉");
}
//-------------------------------------------------
public class TestStudent {
/*
成员方法的调用格式:
对象名.方法名();
*/
public static void main(String[] args) {
Student stu = new Student();
stu.name = "钢门吹雪";
stu.age = 23;
System.out.println(stu.name + "---" + stu.age);
stu.study();
stu.sleep();
stu.eat();
stu.study();
}
方法调用过程
- 保存程序运行时产生的对象
- 创建的对象放在堆内存中
- main(程序入口点)方法,方法放在栈内存
- 局部变量在所属的方法中,成员变量在堆内存的内存当中
- 赋值时赋得是地址
成员变量和局部变量的区别
案例:
phone.java
public class Phone {
String brand;
int price;
public void call(){
System.out.printn("手机打电话");
}
public void sendMessage(){
System.out.println("群发短信");
}
}
TestPhone.java
public class TestPhone {
public static void main(String[] args) {
Phone p = new Phone();
p.brand ="大米"
p.price = 1999:
System.out.println(p.brand + "---" + p.price);
p.call();
p.sendMessage();
}
}
带参数的方法
public void call (){
System.out.println("手机打电话");
}
public void call () {
System.out.println("给xxx打电话");
}
public void call() {
String name = "xxx";
System.out.printIn("给” + name +"打电话");
}
// 以上三种方法过于麻烦
带参数方法的定义格式
- 格式:
public void 方法名 ( 据类型 变量名1,数据类型 变量名2...){
// 方法体
}
- 范例:
public void add (int a, int b) {
…………
}
注意:
- 方法定义时,参数中的数据类型与变量名都不能缺少,缺少任意一个程序将报错
- 方法定义时,多个参数之间使用逗号(,)分隔
带参数方法的调用格式
格式
对象名.方法名(参数);
范例:
p.cal1("钢门吹雪");
格式
对象名.方法名(参数1,参数2);
范例:
p.add(10,20);
注意
参数的数量与类型必须与方法定义中的设置相匹配,否则程序将报错方法调用时,
public class Phone{
String brand;
int price;
public void call(String name){
System.out.println("给" + name +"打电话");
}
public void sendMessage(){
System.out.println("群发短信");
}
}
// ---------------------------------------------------
public class TestPhone {
public static void main(String[] args) {
Phone p = new Phone();
p.call( name:"阿Q");
p.call( name:"辛德勒");
}
}
形参和实参
- 形参:全称形式参数,是指在定义方法时,所声明的参数
- 实参:全称实际参数,调用方法时,所传入的参数
注意:
- 方法调用时,形参和实参的数量和类型必须相匹配,否则将出现编译错误
带参数方法调用过程
- 形参在内存中的体现就是一个变量,放在栈中存储
为什么要有带返回值的方法
我们经常会根据一个方法产出的结果,来去组织另外一段代码逻辑为了拿到这个方法产生的结果,就需要定义带有返回值的方法
格式:
public 数据类型 方法名 (数据类型 变量名1,数据类型 变量名2... ){
return 数据值;
}
范例:
public int add (int a, int b) {
int c = a + b;
return c;
}
带返回值方法的调用格式
格式: 对象名.方法名(参数...);
范例: p.add(10,20);
格式: 数据类型 变量名 = 对象名方法名(参数...);
范例: int result = p.add(10,20);
方法的通用格式
格式:
public 返回值类型 方法名( 参数 ) {
// 方法体;
return 数据
}
定义方法时,要做到两个明确
- 明确参数:主要是明确参数的类型和数量
- 明确返回值类型:主要是明确方法操作完毕之后是否有结果数据,如果有,写对应的数据类型,如果没有,写void
调用方法时
- void类型的方法,直接调用即可非void类型的方法,
- 推荐用变量接收调用
方法注意事项
- 方法不调用就不执行
- 方法与方法之间是平级关系,不能嵌套定义
- 方法的编写顺序和执行顺序无关
- 方法的返回值类型为void,表示该方法没有返回值,没有返回值的方法可以省略return语句不写如果要编写return,后面不能跟具体的数据
- return语句下面,不能编写代码,因为永远执行不到,属于无效的代码
面向对象应用
public class App {
public static void main(String[] args) {
// 创建窗体对象
JFrame frame = new JFrame();
// 调用成员方法,设置宽和高
frame.setSize( width: 514,height: 538);
// 调用成员方法,设置窗体居中
frame.setLocationRelativeTo(null);
// 调用成员方法,设置窗体置顶
frame.setAlwaysOnTop(true);
// 调用成员方法,设置关闭模式
frame.setDefaultcloseOperation(3);
// 调用成员方法,设置窗体标题
frame.setTitle("2048小游戏");
// 调用成员方法,设置窗体可见
frame.setVisible(true);
}
}
方法加强
当局部变量和成员变量出现了重名的情况
Java使用的是就近原则
this 关键字
- 介绍:this代表当前类的对象引用
- 作用: 用于区分局部变量和成员变量的重名问题
this: 代表当前类对象的引用(地址)哪一个对象调用的this,this就代表哪一个对象
方法中调用成员方法
- this 可以用于调用本类的成员变量和成员方法
- 调用成员变量:如果跟局部变量没有重名,this可以省略
- 调用成员方法:this可以直接省略
权限修饰符
- private : 只能在本类当中进行访问
- (default) : 同一个类中,同一个包下进行访问
- protected : TODO: 学完面向对象继再说
- public : 同一个类,同一个包,不同包
注意: 自己创建的类,如果在不同的包下,也需要编写导包代码
展开目录结构:ATL+1
方法重载
- 在同一个类中,定义了多个同名的方法,但每个方法具有不同的参数类型或参数个数,这些同名的方法,就构成了重载关系
- 简单记:同一个类中,方法名相同,参数不同的方法参数不同:个数不同、类型不同、顺序不同
- 注意: 识别方法之间是否是重载关系,只看方法名和参数,跟返回值无关.
调用方法的时候.Java虚拟机会通过参数的不同来区分同名的方法
方法重载的好处
不用记忆过多繁琐的方法名字
构造方法概述
构建、创造对象的时候,所调用的方法
格式
- 方法名与类名相同,大小写也要一致
- 没有返回值类型,连void都没有
- 没有具体的返回值 (不能由retrun带回结果数据)
执行时机:
- 创建对象的时候调用、每创建一次对象,就会执行一次构造方法
- 不能手动调用构造方法
构造方法作用
作用:用于给对象的数据 (成员变量)进行初始化
构造方法的注意事项
- 构造方法的创建
- 如果没有定义构造方法,系统将给出一个默认的无参数构造方法
- 如果定义了构造方法,系统将不再提供默认的构造方法
- 构造方法的重载
- 构造方法也是方法,允许重载关系出现
- 推荐的使用方式
- 无参数构造方法,和带参数构造方法,都自己手动给出
class Student {
int age;
public Student(){
}
public Student(int age){
this.age = age;
}
}
封装
- 面向对象三大特征之一(封装,继承,多态
- 隐藏实现细节,仅对外暴露公共的访问方式
封装常见的体现
将代码抽取到方法中,这是对功能的一种封装
将属性抽取到类当中,这是对数据的一种封装
标准JavaBean类
- 成员变量
- 使用 private 修饰
- 构造方法
- 提供一个无参构造方法
- 提供一个带参的构造方法
- 成员方法
- 提供每一个成员变量对应的 setXxx() /getXxx()
对象在方法中的传递
对象在方法中作为参数传递, 传递的其实就是该对象所记录的地址值
(四) API
API介绍
API(Application ProgrammingInterface): 应用程序编程接口
窗体结构介绍
JButton
JButton 构造方法
JButton()
创建一个没有设置文本或图标的按钮。
JButton(String text)
创建一个带文本的按钮。
public class Demo1JButton {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setTitle("JButton按钮演示");
frame.setSize( width: 514, height: 538);
frame.setLocationRelativeTo(null);
frame .setAlwaysOnTop(true);
frame.setDefaultcloseOperation(3):
// 1.通过窗体对象,取消默认布局
frame.setLayout(null);
// 2. 创建按钮对象
JButton btn = new JButton();
btn.setBounds( x: 50, y: 50, width: 100, height: 100);
JButton btn2 = new JButton( text:"点我啊~");
btn2.setBounds( x: 150, y: 150, width: 200, height: 200);
// 。通过窗体对象,获取到面板对象,并调用add方法添加按钮组件
frame.getcontentPane().add(btn);
frame.getContentPane().add(btn2);
frame.setVisible(true);
}
}
JLable
- 用于展示文本和图片
JLabel构造方法
JLabel() 创建一个不含图像,不含文本的 JLabel 对象
JLabel(String text) 使用指定的文本创建一个 JLabel 对象
JLabel(Icon image) 创建一个具有指定图像的 JLabel 对象
// 1. 创建JLable对象,展示文本
JLabel jl1 = new JLabe( text:"淡黄的长裙~");
jl1.setBounds( x: 50, y: 50, width: 100, height: 10);
JLabel jl2 = new JLabel( text: "蓬松的头发~");
jl2.setBounds( x: 150, y: 50, width: 100, height: 100);
2.创建JLabel对象,展示图片
JLabel jl3 = new JLabel(new ImageIcon( filename: "p: limagellA-16.png"));
jl3.setBounds( x: 50, y: 150, width: 100, height: 100);
3.将JLabel对象添加到面板当中。
frame.getContentPane() .add(jl1);
frame.getcontentPane() .add(j2)frame.getcontentPane() .add(jl3);
JLabel jl4 = new JLabel(new ImageIcon( filename: "路径"));
数字方块展示2048
public class APP {
public static void main(String[] args) {
// 1.创建窗体对象
JFrame frame = new JFrame();
// 2.调用成员方法,设置宽和高
frame.setSize(524, 548);
// 3.调用成员方法,设置窗体居中
frame.setLocationRelativeTo(null);
// 4.调用成员方法,设置窗体置顶
frame.setAlwaysOnTop(true);
// 5.调用成员方法,设置关闭模式
frame.setDefaultCloseOperation(3);
// 6.调用成员方法,设置窗体标题
frame.setTitle("2048小游戏");
// 7.调用成员方法,设置窗体可见
frame.setVisible(true);
// 8.取消默认布局
frame.setLayout(null);
// 16个JLabel图片
// 第一个水平的图片
JLabel image_1 = new JLabel(new ImageIcon("D:\\A_LIUXU_CodeBase\\JAVA\\image\\A-16.png"));
image_1.setBounds( 50, 50, 100, 100);
frame.getContentPane().add(image_1);
JLabel image_2 = new JLabel(new ImageIcon("D:\\A_LIUXU_CodeBase\\JAVA\\image\\A-16.png"));
image_2.setBounds( 150, 50, 100, 100);
frame.getContentPane().add(image_2);
JLabel image_3 = new JLabel(new ImageIcon("D:\\A_LIUXU_CodeBase\\JAVA\\image\\A-16.png"));
image_3.setBounds( 250, 50, 100, 100);
frame.getContentPane().add(image_3);
JLabel image_4 = new JLabel(new ImageIcon("D:\\A_LIUXU_CodeBase\\JAVA\\image\\A-16.png"));
image_4.setBounds( 350, 50, 100, 100);
frame.getContentPane().add(image_4);
// 第二个水平
JLabel image_5= new JLabel(new ImageIcon("D:\\A_LIUXU_CodeBase\\JAVA\\image\\A-16.png"));
image_5.setBounds( 50, 150, 100, 100);
frame.getContentPane().add(image_5);
JLabel image_6 = new JLabel(new ImageIcon("D:\\A_LIUXU_CodeBase\\JAVA\\image\\A-16.png"));
image_6.setBounds( 150, 150, 100, 100);
frame.getContentPane().add(image_6);
JLabel image_7 = new JLabel(new ImageIcon("D:\\A_LIUXU_CodeBase\\JAVA\\image\\A-16.png"));
image_7.setBounds( 250, 150, 100, 100);
frame.getContentPane().add(image_7);
JLabel image_8 = new JLabel(new ImageIcon("D:\\A_LIUXU_CodeBase\\JAVA\\image\\A-16.png"));
image_8.setBounds( 350, 150, 100, 100);
frame.getContentPane().add(image_8);
// 第三个水平
JLabel image_9= new JLabel(new ImageIcon("D:\\A_LIUXU_CodeBase\\JAVA\\image\\A-16.png"));
image_9.setBounds( 50, 250, 100, 100);
frame.getContentPane().add(image_9);
JLabel image_10 = new JLabel(new ImageIcon("D:\\A_LIUXU_CodeBase\\JAVA\\image\\A-16.png"));
image_10.setBounds( 150, 250, 100, 100);
frame.getContentPane().add(image_10);
JLabel image_11 = new JLabel(new ImageIcon("D:\\A_LIUXU_CodeBase\\JAVA\\image\\A-16.png"));
image_11.setBounds( 250, 250, 100, 100);
frame.getContentPane().add(image_11);
JLabel image_12 = new JLabel(new ImageIcon("D:\\A_LIUXU_CodeBase\\JAVA\\image\\A-16.png"));
image_12.setBounds( 350, 250, 100, 100);
frame.getContentPane().add(image_12);
// 第四个水平
JLabel image_13= new JLabel(new ImageIcon("D:\\A_LIUXU_CodeBase\\JAVA\\image\\A-16.png"));
image_13.setBounds( 50, 350, 100, 100);
frame.getContentPane().add(image_13);
JLabel image_14 = new JLabel(new ImageIcon("D:\\A_LIUXU_CodeBase\\JAVA\\image\\A-16.png"));
image_14.setBounds( 150, 350, 100, 100);
frame.getContentPane().add(image_14);
JLabel image_15 = new JLabel(new ImageIcon("D:\\A_LIUXU_CodeBase\\JAVA\\image\\A-16.png"));
image_15.setBounds( 250, 350, 100, 100);
frame.getContentPane().add(image_15);
JLabel image_16 = new JLabel(new ImageIcon("D:\\A_LIUXU_CodeBase\\JAVA\\image\\A-16.png"));
image_16.setBounds( 350, 350, 100, 100);
frame.getContentPane().add(image_16);
// 设置一个背景
JLabel background = new JLabel(new ImageIcon("D:\\A_LIUXU_CodeBase\\JAVA\\image\\background.png"));
background.setBounds(40, 40, 420, 420);
frame.getContentPane().add(background);
frame.setVisible(true);
}
}
(五)循环语句
for 循环语句
for循环格式:
for(初始化语句; 条件判断语句; 条件控制语句){
循环体语句;
}
- 执行流程:
- 执行初始化语句
- 执行条件判断语句,看其结果是true还是false
- 如果是false,循环结束
- 如果是true,继续执行
- 执行循环体语句
- 执行条件控制语句
- 回到原来继续
例子1:在控制台输出1-5和5-1的数据
需求:在控制台输出1-5和5-1的数据
分析:
1。从1开始到5结束,设置初始化从1开始
2。设置判断条件为没有到5的时候继续执行,执行到超过5程序结束
3。从1到5,每次增加1,设置条件控制每次+1
4。将反复进行的事情写入循环结构内部,打印对应数据
// 1 2 3 4 5 6
public static void main(string[] args) {
for(int i = 1; i <= 5; i++){
// i= 1 2 3 4 5
System.out.println(i);
}
}
// 5 4 3 2 1
public static void main(string[] args) {
for(int i = 5; i >= 1; i--){
// i= 5 4 3 2 1
System.out.println(i);
}
}
例子2:求1-5之间的数据和,并把求和结果在控制台输出
需求:求1-5之间的数据和,并把求和结果在控制台输出
public static void main(Stringl] args){
// 1.求和的最终结果必须保存起来,需要定义一个变量,用于保存求和的结果,初始值为0
int sum = 0;
// 2.在循环中初始化一个变量从1开始,不断++,增长到5
for(int i = 1; i <= 5; i++)
// i = 1 2 3 4 5
// 3.循环的过程中,将能够代表(1-5)的i变量和sum进行累加
sum += i;
// 4.当循环执行完毕时,将最终数据打印出来
System.out.println("1-5之间的数据和为:" + sum);
}
案例:求偶数和、求1-100之间的偶数和,并把求和结果在控制台输出
public static void main(string[] args) {
// 1.需求是要求和,定义求和变量。
int sum = 0;
// 2.循环中获取1-100之间的每一个数值
for(int i = 1; i <= 100; i++){
// 3.循环的过程中,对每一个数值进行if判断,判断是否是偶数
if(i % 2 == 0){
// 4.是偶数的话,跟求和变量累加
sum += i;
}
}
System.out.println(sum);
}
案例:水仙花
水仙花数是一个三位数
eg:111 222 333 370 371 520 999
水仙花数的个位、十位、百位的数字立方和 等于 原数
public static void main(String[] args){
// 1. 通过循环获取所有的三位数100-999
for(int i = 100; i <= 999; i++){
// 2.将每一个三位数拆分为个位,十位,百位
int ge = i %10;
int shi = i / 10 % 10;
int bai = i / 10 / 10 % 10;
// 3.加入if判断条件,计算是否是水仙花数,是的话输出打印。
if(ge*ge*ge + shi*shixshi + baixbaixbai == i){
System.out.println(i);
}
}
实现统计换行效果
public static void main(String[] args){
int count = 0;
for(int i = 100; i <= 999; i++){
int ge = i %10;
int shi = i / 10 % 10;
int bai = i / 10 / 10 % 10;
if(ge*ge*ge + shi*shixshi + baixbaixbai == i){
System.out.print(i + "----");
count++;
if(count % 2 ==0){
System.out.println
}
}
}
for循环注意事项:
- 循环中定义的变量,在每一轮循环结束后,都会从内存中释放
- 注意 ()和[]之间分号
- 若在for语句后加上分号(;)则后续的大括号语句不执行
- for (int i = 1; i <= 5; i++);
for( ;; ){
// 循环体
}
for 循环嵌套
外循环执行一次,内循环执行一圈.
for(int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){
// j = 0 1 2 3
System.out.print("*"):
System.out.println();
}
}
2048 循环改进
for(int i = 0; i < 4; i++){
// i= 1 2 3
for(int j = 0; j < 4; j++){
// j=01 2 3
JLabel image = new JLabel(new ImageIcon( filename: "p: limagellA-16.png"));
image.setBounds( x: 50 + 100 * j, y: 50 + 100 * width: 100,height: 100);
frame .getContentPane() .add(image);
}
}
while 循环语句
public class Demo1While {
/*
while循环格式:
初始化语句;
while (条件判断语句) {
循环体语句;
条件控制语句;
}
需求: 使用while循环在控制台打印5次HeTLoWorld
*/
public static void main(String[] args) {
int i = 1;
while (i <= 5){
System.out.printin("HelloWorld");
i++;
}
}
}
while循环语句注意事项
- 注意 ()和之间分号
- 无限循环
do...while 循环语句
初始化语句;
do{
循环体语句;
条件控制语句;
} while(条件判断语句);
需求: 在控制台打印5次HeLLoWorld
特点: 无论判断条件是否满足,都至少会执行一次循环体,
public static void main(String[] args) {
int i = 6;
do {
System.out.printIn("HelloWorld");
i++;
} while (i <= 5);
}
三种循环的区别
三种循环的区别:
- 执行循环体(先判断后执行for循环和while循环先判断条件是否成立,然后决定是否
- do...while循环先执行一次循环体,然后判断条件是否成立,是否继续执行循环体(先执行后判断)
for 和 while 的区别:
- for循环中,控制循环的变量,因为归属for循环的语法结构中,在for循环结束后,就不能再次被访问到了
- while循环中,控制循环的变量,对于while循环来说不归属其语法结构中,在while循环结束后,该变量还可以继续使用
跳转控制语句
break: 用于结束循环或switch语句
注意: 只能在循环和switch当中进行使用,通常会配合判断条件进行使用。
continue: 跳过某次循环,继续下一次循环
注意: 只能在循环当中进行使用,通常会配合判断条件进行使用,
break和continue都只能操作自己所在的那一层循环,如果想要操作指定的一层,可以使用标号。
案例-1:
键盘录入一个1-100之间的整数,如果输入有误,请给出提示并继续录入需求:直到用户输入了正确的数据,程序结束
/*
分析:
1。使用Scanner做键盘录入
2。 使用 if 语句判断数据是否在 1-100之间
3。录入数据和判断的代码可能不止一次,使用循环语句包裹
4。循环次数不明确,使用无限循环
5。若是录入了正确的数据,使用 break 结束循环
*/
public static void main(String[] args) {
// 1.使用Scanner做键盘录入
Scanner sc = new Scanner(System.in);
while(true){
System.out.println("请输入一个1-100之间的整数:");
int num = sc.nextIntO ;
// 2. 使用 if 语句判断数据是否在 1-100之间
if (num >= 0 && num <= 100)
{
//正确的数据
System.out.println("您的输入为:" + num);
break;
}else
{
System.out.println("您的输入有误,请检查");
}
}
}
(六)数组
数组介绍
什么是数组?
数组指的是一种容器,可以用来存储同种数据类型的多个值
总结:数组容器在存储数据的时候,需要结合数据类型考虑。(boolean byte short double)例如:int类型的数组容器
建议:容器的类型,和存储的数据类型保持一致
数组的定义与静态初始化
数组的定义
格式一: 数据类型[]数组名
范 例:int[] array
格式二:数据类型数组名[]
范 例: int array[]
数组静态初始化
- 初始化:就是在内存中,为数组容器开辟空间,并将数据存入容器中的过程
- 完整格式:数据类型[] 数组名 = new数据类型[] [ 元素1,元素2,元素3... };
- 范例: int[] array = { 11,22,33 };
- 范例: double[] array2 = { 11.1,22.2,33.3}
- 打印数组名会出现数组容器在内存中的地址值
public class Demo2Array {
/*
数组的静态初始化:
1。完整格式:
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素2...};
2。简化格式:
数据类型[] 数组名 = {元素1, 元素2,元素2...};
*/
public static void main(String[] args) {
// 数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素2...};
// 创建了一个int类型的数组,数组名叫arr,数组中存储了 11 22 33 这个三个数据
int[] arr = new int[]{11,22,33};
System.out.println(arr); // 此时输出的是数组的地址
// 数据类型[] 数组名 = {元素1,元素2,元素2...};
double[] dArr = {12.3,22.3,33};
System.out.println(dArr); // 此时输出的是数组的地址
}
}
数组元素访问
格式:数组名[索引];
索引:索引是数组容器中空间的编号,编号从0开始,逐个+1增长
例子:
public class Demo3Array {
数组的元素访问格式:
数组名[索引]
public static void main(String[] args) {
int[] arr = {11,22,33,44,55};
// 需求1: 将元素44取出来打印在控制台
System.out.printin(arr[3]):
// 需求2: 修改0号元素位置元素为66,修改后取出并打印,
arr[0] = 66;
System.out.println(arr[0]);
}
}
数组遍历
数组遍历:将数组中所有的内容取出来,取出来之后可以 (打印,求和,判断..)
注意:遍历指的是取出数据的过程,不要局限的理解为,遍历就是打印!
例子:
/*
数组的遍历:
将数组中所有的元素取出来,并打印在控制台
数组中的属性: 救组名.length
*/
// 输出例子
public static void main(String[] args) {
int[] arr = {11,22,33,44,55};
System.out.printin(arr[0]);
System.out.printin(arr[1]);
System.out.printin(arr[2]);
System.out.printin(arr[3]);
System.out.printin(arr[4]);
}
改进一:
public static void main(String[] args) {
int[] arr = {11,22,33,44,55};
for(int i=0; i<= 5; i++)
{
System.out.printin(arr[i]);
}
}
改进二:
public static void main(String[] args) {
int[] arr = {11,22,33,44,55};
for(int i=0; i<= 5; i++)
{
System.out.println(arr[i]);
}
}
改进三:
public static void main(String[] args) {
int[] arr = {11,22,33,44,55};
for(int i=0; i<= arr.length; i++)
{
System.out.println(arr[i]);
}
}
数组动态初始化
动态初始化:初始化时只指定数组长度,由系统为数组分配初始值
格式:数据类型[]数组名 = new 数据类型[数组长度];
两种初始化的区别对比
- 动态初始化:手动指定数组长度,由系统给出默认初始化值。
- 静态初始化:手动指定数组元素,系统会根据元素个数,计算出数组的长度
public class Demo5Array{
/*
数组的动态初始化:
概念:
初始化时只指定数组长度,由系统为数组分配初始值
整数 : 0
小数 : 0.0
字符 : '\u0000' 空白字符
布尔 : false
引用数据类型: null
格式:
数据类型[] 数组名 = new 数据类型[数组的长度];
*/
public static void main(String[] args){
// 数据类型[] 数组名 = new 数据类型[数组的长度];
int[] arr = new int[3];
System.out.println(arr[0]); // 0
System.out.println(arr[1]); // 0
System.out.println(arr[2]); // 0
}
}
数组常见问题
数组越界异常
当访问了数组中不存在的索引,就会引发索引越界异常
public class DemolArrayException {
// 数组索引越界异常:
// ArrayIndex0utofBoundsException当访问了不存在的索引,就会引发此异常.
public static void main(String[] args) {
int[] arr = {11,22,33};
System.out.printin(arr[0]);
System.out.printin(arr[1]);
System.out.println(arr[3]);
}
}
空指针异常
当引用数据类型变量被赋值为null之后,地址的指向被切断,还继续访问堆内存数据,就会引发空指针异常
public static void main(Stringl] args) {
int[] arr = new int[2];
//把nul1赋值给数组
arr = null;
//输出元素
System.out.println(arr[1]);
}
数组常见操作
案例-1:数组求和
public class DEMO {
/*
需求: 已知数组元素为 {11,22,33,44,55}请将数组中偶数元素取出并求和,最后打印求和结果
分析:
1。静态初始化数组
2。定义求和变量了。
3。遍历数组取出每一个元素
4。判断当前元素是否是偶数,是的话跟求和变量做累加操作
5。打印求和变量
*/
public static void main(String[] args) {
// 1. 静态初始化数组
int[] arr = {11,22,33,44,55};
// 2.定义求和变量
int sum = 0;
// 3.遍历数组取出每一个元素
for (int i = 0; i < arr.length; i++) {
// 4.判断当前元素是否是偶数,是的话跟求和变量做累加操作
if (arr[i] % 2 == 0) {
sum += arr[i];
}
}
// 5。打印求和变量
System.out.println(sum);
}
案例-2: 数组求最值
public class Test2 {
/*
需求: 已知数组元素为 {5,44,33,55,22]请找出数组中最大值并打印在控制台
分析:
1.定义max变量准备记录插台上的变化
2.遍历数组获取每一个元素
3.让每一个元素跟max进行比较,如果找到更大的,就让max记录该元素
4.打印max变量所记录的值。
*/
public static void main(String[] args) {
int[] arr = {5,44,33,55,22};
// 1.定义max变量准备记录插台上的变化
int max = arr[0];
// 2.遍历数组获取每一个元素
for (int i = 1; i < arr.length; i++) {
//3.让每一个元素跟max进行比较,如果找到更大的,就让max记录该元素
if(arr[i] > max){
max = arr[i];
}
}
// 4.打印max变量所记录的值
System.out.println(max);
}
}
例子-3:数据交换
public class Test3 {
*/
需求: 实现两个变量的数据交换
*/
public static void main(String[] args) {
int a = 10;
int b = 20:
// 交换的代码
int c = a;
a= b;
b = c;
// a = 20
// b = 10
System.out.printin(a); // 20
System.out.println(b); // 10
}
}
public class Test4 {
/*
需求: 将数组中第一个和最后一个元素进行交换。
*/
public static void main(String[] args) {
int[] arr = {11,22,33,44,55};
// arr[0] arr[4]
// 交换的代码
int c = arr[0];
arr[o] = arr[4];
arr[4] = c;
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
例子-4:数组反转
public class Test5 {
/*
数组反转
步骤:
1。定义两个变量,start和end来表示开始和结束的指针.
2.确定交换条件,start < end 允许交换
3。循环中编写交换逻辑代码
4。每一次交换完成,改变两个指针所指向的索引 start++,end--
5。循环结束后,遍历数组并打印,查看反转后的数组
*/
public static void main(String[] args) {
int[] arr = {11,22,33,44,55};
// 1.定义两个变量,start和end来表示开始和结束的指针。
// 2.确定交换条件,start < end 允许交换
// 4.每一次交换完成,改变两个指针所指向的索引 start++, end--
for (int start = 0, end = arr.length - 1; start < end; start++, end--) {
// 3.循环中编写交换逻辑代码
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
// 5.循环结束后,遍历数组并打印,查看反转后的数组
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
(七)二维数组
二维数组介绍
二维数组静态初始化
格式:数据类型[][] 数组名= new 数据类型[][] {[元素1,元素2],[元素1,元素2]};
范例: int[][] arr = new int[][]{{11,22},{33,44}};
简化格式:数据类型[][] 数组名 = {{元素1,元素2},{元素1,元素2}};
范例: int[][] arr = {{11,22},{33,44}};
public class DemolArray
/*
二维数组:
也是一种容器,容器中存储的都是一维数组。
完整格式:
数据类型[][] 数组名 = new 数据类型[][] 元素1,元素2},[元素1,元素2}};
简化格式:
数据类型[][] 数组名 = {元素1,元素2},{元素1,元素2}};
*/
public static void main(String[] args) (
int[][] arr = {
{11,22}
{33,44}
};
System.out.println(arr);
// [[I@10f87f48
System.out.println(arr[0]); // [I@b4c966a
System.out.println(arr[1]); // [I@b4c966a
System.out.println(arr[0][1]); // 22
}
}
二维数组元素访问
格式:数组名[索引][索引];
范例: int[][] arr = new int[][]{{11,22},{33,44}};
arr[1][e];
二维数组遍历
public class Test1Array {
/*
需求:
己知一个二维数组 arr = {{11 ,22 ,33),{33 ,44 ,55}}; 遍历该数组,取出所有元素并打印
步骤:
1。遍历二维数组,取出里面每一个一维数组
2。在遍历的过程中,对每一个一维数组继续完成遍历,获取内部存储的每一个元素
*/
public static void main(Stringl] args){
int[][] arr = {{11 ,22 ,33} ,{3344, 5517}};
1.遍历二维数组,取出里面每一个一维数组
for (int i = 0; i < arr.length; i++) {
// arr[i] 代表每一个一维数组。
2.在遍历的过程中,对每一个一维数组继续完成遍历,获取内部存储的每一个元素
for (int j = 0; j < temp.length; j++) {
System.out.println(arr[i][j]);
}
}
}
}
二维数组动态初始化
格式:数据类型[][] 数组名 = new 数据类型[m][n];
m表示这个二维数组,可以存放多少个一维数组
n表示每一个一维数组,可以存放多少个元素
范例: int[][] arr = new int[2][3];
该数组可以存放2个一维数组,每个一维数组中可以存放3个int类型元素
public class Demo3Array {
public static void main(String[] args) {
int[][] arr = new int[2][3];
int[] arr1 = {11,22,33};
int[] arr2 = {44,55,66};
arr[0] = arr1;
arr[1] = arr2;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.println(arr[i][j]);
}
}
}
}
2048游戏改进
public class App {
public static void main(String[] args) {
int[][]datas = {
{0, 2, 2, 4},
{2, 2, 4, 4},
{0, 8, 2, 4},
{0, 32, 0, 64}
};
// 创建窗体对象
JFrame frame = new JFrame();
// 设置宽和高
frame.setSize( width: 514, height: 538);
// 设置窗体居中
frame.setLocationRelativeTo(null);
// 设置窗体置顶
frame.setAlwaysOnTop(true);
// 设置关闭模式
frame.setDefaultcloseOperation(3);
frame.setDefaultCloseOperation(3)
//设置窗体标题
frame.setTitle("2048小游戏");
// 取消默认布局
frame.setLayout(null);
for (int i = 0;i< 4; i++) {
// i=0 1 2 3
for (int j = 0;i < 4; j++) {
//j= @123
JLabel image = new JLabel(new ImageIcon( filenanie: "p: imagelA-"+datas[i][j]+".png"));
image.setBounds( x: 50 + 100 * j, y: 50 + 100 * i, width: 100, height: 100);
frame .getContentPane() .add(image);
}
}
JLabel background = new JLabel(new ImageIcon( filename: "p: lmagellA-Background.jpg"));
background.setBounds( x: 40 y: 40, width: 420, height: 420);
frame .getContentPaneO .add(background):
// 设置窗体可见
frame.setVisible(true);
}
(八)面向对象高级
继承
继承介绍
继承:让类与类之间产生关系 (子父类关系),子类可以直接使用父类中非私有的成员
继承的格式
- 格式: public class 子类名 extends 父类名[
- 范例: public class Zi extends Fu {
- Fu:是父类,也被称为基类、超类
- zi:是子类,也被称为派生类
public class TestExtends{
public static void main(String[] args) {
Coder c = new Coder();
c.name ="钢门吹雪";
System.out.println(c.name);
}
}
class Employee {
String name;
int age;
double salary;
}
class Coder extends Employee {
}
class Manager extends Employee {
}
继承的好处和弊端
继承的好处
- 提高了代码的复用性
- 提高了代码的维护性
- 让类与类之间产生了关系,是多态的前提
继承的弊端
- 增强了代码的耦合性(代码与代码之间存在关联都可以将其称之为"耦合")
什么时候使用继承?
- 当类与类之间,存在相同(共性)的内容,并且产生了 is a 的关系,就可以考虑使用继承,来优化代码。
Java 中继承的特点
- Java只支持单继承,不支持多继承,但支持多层继承
- 单继承: 子类只能继承一个父类
- 不支持多继承:子类不能同时继承多个父类
- 多层继承:子类 A 继承父类 B ,父类B 可以 继承父类 C
成员变量
思考:子父类中,如果出现了重名的成员变量,使用的时候会优先使用??
- 根据就近原则使用子类的成员变量
- 子父类中如果出现了重名的成员变量,可以使用super关键字进行区分
成员方法
思考:子类继承父类后,是否可以自己继续定义方法?
子父类中如果出现了重名的成员方法优先使用子类的方法但这其实是子类方法对父类方法进行了重写
方法重写
方法重写概述
- 在继承体系中,子类出现了和父类中一模一样的方法声明方法名和参数完全一致
方法重写的应用场景
- 当子类需要父类的功能,而功能主体子类有自己特有内容,可以重写父类中的方法这样,即沿袭了父类的功能,又定义了子类特有的内容
方法重写的注意事项
- 父类中私有方法不能被重写
- 子类重写父类方法时,访问权限必须大于等于父类
- 权限修饰符
继承中构造方法的访问特点
问题1: 子类是否可以继承父类的构造方法??
- 不可以,因为构造方法要求方法名与类名相同.
子类和父类的类名不可能一致,所以构造方法不能被继承。
问题2: 创建子类对象的时候,为什么都会执行父类的空参数构造方法?
·- 因为子类在初始化的时候,很可能会使用到父类中的成员所以,在子类初始化之前, 一定要先完成父类的初始化而初始化的方式,就是调用父类的构造方法!
问题3: 子类是如何调用到父类构造方法的呢??
- 在所有的构造方法中,都默认隐藏着一句话
super();
问题4:父类构造方法中,也默认隐藏着super()吗?
- 是的,在Java中所有的类都默认继承了一个叫做object的类.
- 子类中所有的构造方法默认都会访问父类中无参的构造方法
- 子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据
- 子类初始化之前,一定要先完成父类初始化。
- 怎么初始化?
- 构造方法的第一条语默认都是: super()
- 注意: 如果我们编写的类,没有手动指定父类,系统也会自动继承Object(Java继承体系中的最顶层父类)
如果父类中没有空参构造方法,只有带参构造方法,会出现什么现象呢?
- 子类通过 super手动调用父类的带参的构造方法
- 子类通过 this 去调用本类的其他构造方法,本类其他构造方法再通过 super 去手动调用父类的带参的构造方法
- 注意:this(..)super(..)必须放在构造方法的第一行有效语句,并且二者不能共存。
this和 super
- this:代表本类对象的引用
- super:代表父类存储空间的标识(可以理解为父类对象引用)
final关键字
final 关键字是最终的意思,可以修饰 (方法,变量,类)
final 修饰的特点
- 修饰变量:表明该变量是常量,不能再次被赋值
- 修饰方法:表明该方法是最终方法,不能被重写
- 修饰类:表明该类是最终类,不能被继承
fina 关键字是最终的意思,可以修饰(方法,变量,类)
被final修饰变量就变成了常量(自定义常量),只能赋值一次,不可修改。
- 基本数据类型变量: 其值不可以更改
- 引用数据类型变量: 地址值不可更改,但是可以通过setXxx方法修改内部的属性值。
final修饰变量
- 变量是基本类型: final 修饰指的是基本类型的数据值不能发生改变
- 变量是引用类型: final 修饰指是引用类型的地址值不能发生改变但是地址里面的内容是可以发生改变的
final修饰成员变量,初始化时机。
- 在创建的时候,直接给值.
- 在构造方法结束之前,完成赋值.
抽象
public class TestAbstract {
/*
抽象类: 理解层面来说,就是把像的部分和相似的部分,抽取到一个父类中
(共性行为向上抽取)当行为被抽取到父类中之后, 发现这个行为
在父类中描述不清了.且该行为还是子类必须要做的事,就将其定
义为抽象方法抽象方法需要存活在抽象类当中。
简单记: 抽象类就是一个特殊的父类,该父类中可以定义抽象方法
*/
public static void main(String[] args) {
}
}
abstract class Employee{
public abstract void work();
}
class Manager extends Employee {
// 项目经理工作: 管理程序员……
@Override
public void work() {
System.out.println("管理程序员...");
}
}
抽象类介绍
- 抽象方法:将共性的行为 (方法) 抽取到父类之后,发现该方法的实现逻辑无法在父类中给出具体明确,该方法就可以定义为抽象方法。
- 抽象方法的定义格式
public abstract 返回值类型 方法名(参数列表) - 抽象类的定义格式:
public abstract class 类名
抽象类注意事项
- 抽象类不能实例化
- 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
- 可以有构造方法
- 抽象类的子类
- 要么重写抽象类中的所有抽象方法
- 要么是抽象类
问题1: 抽象类是否可以实例化(创建对象)
不允许实例化,一旦允许创建对象,就可以调用内部没有方法体的抽象方法了·T
问题2: 抽象类既然不能创建对象,那是否存在构造方法?
有构造方法,作用是交给子类去访问的。
问题3: 抽象类可以没有抽象方法吗?
可以没有抽象方法,但有抽象方法的类一定是抽象类.
问题4:作为抽象类的子类,需要注意什么?
1.必须重写所有的抽象方法。
2.将自己也变成一个抽象类 (不太推荐)
接口
接口介绍
接口:体现的思想是对规则的声明Java中的接口更多体现的是对行为的抽象。
接口的定义和特点
- 接口用关键字interface来定义
public interface 接口名 {} - 接口不能实例化
- 接口和类之间是实现关系,通过implements关键字表示
public class 类名 implements 接口名 {} - 接口的子类(实现类)
- 要么重写接口中的所有抽象方法
- 要么是抽象类
注意:接口和类的实现关系,可以单实现,也可以多实现。
public class 类名 implements 接口名1 , 接口名2 {}
public ctass InterImpl implements Inter (
@Override
public void study() {
System.out.println("我是实现类中的study方法");
}
}
//---------------------------------------------------
public class InterImpl implements Inter,InterA {
@Override
public void study() {
System.out.println("我是实现类中的study方法");
@Override
public void method1(){
}
@Override
public void method2(){
}
}
//---------------------------------------------------
public interface InterA {
public abstract void method1():
public abstract void method2():
public abstract void study();
}
接口的成员特点
- 成员变量
- 只能是常量
- 默认修饰符: public static final
- 构造方法
- 没有
- 成员方法
- 只能是抽象方法
- 默认修饰符:public abstract
- 关于接口中的方法,JDK8 和 JDK9 中有一些新特性
类和接口的关系
- 类和类的关系
- 继承关系,只能单继承,但是可以多层继承
- 类和接口的关系
- 实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
- 接口和接口的关系
- 继承关系,可以单继承,也可以多继承
多态
多态概述
同一个对象,在不同时刻表现出来的不同形态
举例:[程序员]
我们可以说 [程序员] 是 [程序员] :程序员 c = new 程序员();我们也可以说 [程序员] 是 [员工] :员工 e = new 程序员();
这里[程序员] 在不同的时刻表现出来了不同的形态,这就是多态
多态的前提和体现
有继承/实现关系有方法重写
有父类引用指向子类对象
public class Demo1Polymorphic {
/*
多态的前提和体现
1.有继承/实现关系
2.有方法重写
3.有父类引用指向子类对象
*/
public static void main(String[] args) {
// 当前事物,是一个员工
Employee e = new Coder();
// 当前事物,是一个程序员
Coder c = new Coder();
}
class Employee {
public void work(){
System.out.println("工作");
}
}
class Coder extends Employee {
@Override
public void work() {
System.out.println("程序员写代码");
}
}
多态的成员访问特点
- 构造方法:同继承一样,子类会通过 super 访问父类构造方法
- 成员变量:编译看左边(父类),执行看左边(父类)
- 成员方法:编译看左边(父类),执行看右边(子类)
多态的好处和弊端
- 多态的好处:提高了程序的扩展性
- 具体体现:定义方法的时候,使用父类型作为参数,该方法就可以接收这父类的任意子类对象
- 多态的弊端:不能使用子类的特有功能
public class Demo4Polymorphic {
public static void main(String[] args) {
Demo4Polymorphic d = new Demo4Polymorphic();
d.useAnimal(new Dog());
d.useAnima(new Cat(0));
}
public void useAnimal(Animal a){
a.eat();
}
}
abstract class Animal {
public abstract void eat();
}
class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗吃肉");
}
}
class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
事件
多态中的转型
- 向上转型
- 从子到父
- 父类引用指向子类对象
- 向下转型
- 从父到子
- 父类引用转为子类对象
概述:如果被转的引用类型变量,对应的实际类型和目标类型不是同一种类型,那么在转换的时候就会出现 ClassCastException===>转换类型不一样
关键字 instanceof
- 使用格式
- 对象名 instanceof 类型
- 判断一个对象是否是一个类的实例
- 通俗的理解:判断关键字左边的对象,是否是右边的类型,返回boolean类型结果
事件监听机制
事件源:按钮、图片、窗体..
事件:某些操作
如:鼠标单击,鼠标移动了,键盘按下了
绑定监听:当事件源上发生了某个事件,则触发执行某段代码
ActionListener MouseListener KeyListener
事件源对象.addActionListener(ActionListenter接口的实现类对象);
public class DemolActionListener {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize( width: 514, height: 538);// 设置宽高
frame.setLocationRelativeTo(null); // 设置居中
frame .setLayout(null); // 取消默认布局
frame.setDefaultcloseOperation(3); // 设置关闭模式
frame.setLocationRelativeTo(null); // 设置居中
frame .setLayout(null) ; // 取消默认布局
frame .setDefautcloseOperation(3); //设置关闭模式
JButton btn = new JButton( text: "按钮");
btn.setBounds( x: , y: , width: 100,height: 100);
frame .getcontentPane().add(btn) ;
// 1.确定事件源 --按钮
// 2.确定事件动作 -- ActionListener
// 3.绑定监听
// ActionListener 1 = new ActionListenerImpl();
btn.addActionListener(new ActionListenerImpl());
frame.setVisible(true)
}
}
class ActionListenerImpl implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("你不要过来啊~~rr");
}
}
鼠标事件
MouseListener
键盘事件
KeyListener
(九)贪吃蛇游戏
01.窗体绘制
02.图片与字体的绘制
03.直线与网格的绘制:
04.蛇体多节交替移动的实现:
05.键盘控制蛇头的四个方向显示和移动
06.蛇的消失后反向出现
07.食物的随机位置生成
08.蛇身的增长:
09.计分面板的实现
10.游戏的暂停功能
11.游戏的通关设置
12.蛇头与蛇身的碰撞判断
13.双缓存解决画面闪动问题
14.游戏失败后的重新开始;
15.游戏的多个关卡设置
二.JAVAWEB
(一)初始Web 开发
什么是 Web?
Web:全球广域网,也称为万维网(www World wide Web),能够通过浏览器访问的网站
web网站的开发模式
- 网页有哪些部分组成?
- 文字、图片、音频、视频、超链接
- 我们看到的网页,背后的本质是什么?
- 前端代码
- 前端的代码是如何转换成用户眼中的网页的?
- 通过浏览器转化(解析和渲染)成用户看到的网页
- 浏览器中对代码进行解析渲染的部分,称为浏览器内核
web标准
Web标准也称为网页标准,由一系列的标准组成,大部分由W3C( world Wide web onsortium,万维网联盟)负责制定
三个组成部分:
- HTML:负责网页的结构 (页面元素和内容)。
- CSS:负责网页的表现 (页面元素的外观、位置等页面样式,如: 颜色、大小等)。
- lavaScript:负责网页的行为 (交互效果)。
(二)HTML
什么是HTML、CSS?
- HTML (HyperText Markup Language):超文本标记语言
- 超文本:超越了文本的限制,比普通文本更强大。除文字信息,还可以定义图片、音频、视频等内容。
- 标记语言:由标签构成的语言
- HTML标签都是预定义好的。例如:使用<a>展示链接,使用<img>展示图片,<video>展示视频
- HTML代码直接在浏览器中运行,HTML标签由浏浏览器解析
CSS
- css(Cascading style sheet): 层叠样式表,用于控制页面的样式(表现)
HTML结构标签
<html>
<head>
<title>标题</title>
</head>
<body>
</body>
</html>
特点
- HTML标签不区分大小写
- HTML标签属性值单双引号都可以
- HTML语法松散(不太严格)