文章目录

  • 项目一、踏上Java开发之旅
    • 任务1、安装配置JDK并开发第一个Java程序
      • (一)安装JDK
      • (二)配置JDK
      • (三)开发Java程序
    • 任务2、搭建Java集成开发环境IntelliJ IDEA
      • (一)安装IntelliJ IDEA
      • (二) 配置IntelliJ IDEA
      • (三) 创建项目、包、类
  • 项目二、打好Java编程基础
    • 任务1、计算圆面积
      • (一)编程实现
        • 版本1、程序员指定半径,计算圆面积
        • 版本2、用户来输入半径,程序来计算圆面积
        • 版本3、设定结果的精度,满足用户的要求
        • 问题:如何接受键盘输入的包含空格的字符串?
      • (二) 讲解知识点
      • (三)拓展练习
        • 任务1、由卡号计算幸运数
        • 任务2、求解一元二次方程
    • 任务2、闰年判断
      • (一)编程实现
      • (二)讲解知识点
      • (三)拓展练习
        • 任务1、计算圆面积(选择结构版)
        • 任务2、求解一元二次方程(选择结构版)
    • 任务3、成绩等级评定
      • (一)编程实现
        • 方法一、采用并列式多分支结构评定成绩等级
        • 方法二、采用嵌套式多分支结构评定成绩等级
          • 思路1、从高分到低分来划分各个分数段
          • 思路2、从低分到高分来划分各个分数段
        • 方法三、采用延拓式多分支结构评定成绩等级
          • 思路1:从高分到低分来划分各个分数段
          • 思路2、从低分到高分来划分各个分数段
        • 方法四、采用开关式多分支结构评定成绩等级
      • (二)讲解知识点
        • 1、并列式多分支结构
        • 2、嵌套式多分支结构
        • 3、延拓式多分支结构
        • 4、开关式多分支结构
      • (三)拓展练习
        • 任务1、确定给定日期是一年的第几天
        • 任务 2、构建可进不可退的多级菜单系统
        • 任务3、根据收入计算个人所得税
    • 任务4、等差数列求和
      • (一)编程实现
      • (二)讲解知识点
        • 1、for循环
          • (1)语法格式
          • (2)执行流程
        • 2、自增自减运算
          • (1)自增运算
          • (2)自减运算
      • (三)拓展练习
        • 任务1、打印水仙花数
        • 任务2、输出指定范围内的闰年
        • 任务3、判断一个整数是不是素数
    • 任务5、打印乘法九九表
      • (一)编程实现
      • (二)讲解知识点
        • 1、语法格式
        • 2、执行规则
      • (三)拓展练习
        • 任务1、解决百钱买百鸡问题
        • 任务2、蓝桥杯竞赛题:验证四平方和定理
        • 任务3、打印字符等腰三角形
    • 任务6、猜数小游戏(单次版)
      • (一)编程实现
      • (二)讲解知识点
        • 1、前测试条件循环 - while循环
          • (1)语法格式
          • (2)执行情况
        • 2、后测试条件循环 - do...while循环
          • (1)语法格式
          • (2)执行情况
        • 3、随机类 - Random
      • (三)拓展练习
        • 任务1、猜数小游戏(多次版)
        • 任务2、构建可进可退的多级菜单系统
        • 任务3、模拟微信拼手气红包程序产生指定个数的随机红包
    • 任务7、统计一组学生成绩
      • (一)编程实现
        • 课堂练习
      • (二)讲解知识点
        • 1、一维数组定义
          • (1)语法格式
          • (2 )数组定义示例
          • (3)数组定义的内存变化图
        • 2、不同类型数组元素默认初始值
        • 3、避免数组下标越界异常
        • 4、避免数组空指针异常
      • (三)拓展练习
        • 任务1、蓝桥杯竞赛题:回文日期问题
        • 任务2、数组排序(升序和降序排列)
          • 1、选择法排序
            • (1)选择法排序含义
            • (2)选择法排序实现步骤
          • 2、冒泡法排序
            • (1)冒泡法排序含义
            • (2)冒泡法排序实现步骤
        • 补充:利用Arrays工具提供的sort()方法实现数组排序
    • 任务8、打印杨辉三角形
    • (一)编程实现
    • (二)讲解知识点
      • 1、指定二维数组行数与列数
      • 2、指定二维数组行数,不指定列数
      • 3、直接使用嵌套大括号“{}”静态初始化二维数组
    • (三)拓展练习
      • 任务1、求二维数组最值及位置
      • 任务2、查询元素是否在二维数组里
  • 项目三、探索面向对象编程
    • 任务1、采用面向对象方式求三角形面积
    • (一)编程实现
    • (二)讲解知识点
    • (三)拓展练习
      • 1、任务1、创建学生类并测试
      • 2、任务2、采用面向对象求解一元二次方程

项目一、踏上Java开发之旅

  • 工欲善其事必先利其器,要做Java开发,首先得搭建好Java开发环境,为了提高开发效率,还得搭建Java集成开发环境,我们推荐功能强大的IntelliJ IDEA。

任务1、安装配置JDK并开发第一个Java程序

(一)安装JDK

  • 安装JDK11

(二)配置JDK

变量
JAVA_HOME D:\Program Files\Java\jdk-11.0.7
Path %JAVA_HOME%\bin;…

(三)开发Java程序

  1. 编写源程序
  2. 编译成字节码
  3. 解释执行类

任务2、搭建Java集成开发环境IntelliJ IDEA

(一)安装IntelliJ IDEA

(二) 配置IntelliJ IDEA

(三) 创建项目、包、类

  • 项目:Java课程案例
  • 包:net.huawei.p01.t02
  • 类:HelloWorld
  • 不接收命令行参数
package net.huawei.p01.t02;/*** 功能:输出一条信息* 作者:华卫* 日期:2022年03月24日*/
public class HelloWorld {public static void main(String[] args) { // argumentsSystem.out.println("Hello Java World~");}
}
  • 运行程序,查看结果
  • 接收多个命令行参数(字符串数组args,用for循环遍历)
  • 修改程序,再运行,查看结果

项目二、打好Java编程基础

  • 眼观百遍代码,不如手敲一遍~
  • 修炼编程功力,重在日积月累~
  • Java数据类型、常量与变量、运算符与表达式、选择结构、循环结构、数组

任务1、计算圆面积

  • 输入圆半径,计算圆面积,输出结果

(一)编程实现

版本1、程序员指定半径,计算圆面积

  • 缺点是跟用户之间没互动

版本2、用户来输入半径,程序来计算圆面积

  • 用户可以输入整数,也可以输入实数
  • 输入整数,用sc.nextInt()

版本3、设定结果的精度,满足用户的要求

  • 要求结果保留两位小数
  • 回想一下你们在Python里怎么实现这个用户要求的,利用round()函数可以搞定
  • 采用遮尾法,数据没变,只是显示两位小数
  • 采用剪尾法来处理

问题:如何接受键盘输入的包含空格的字符串?

  • 输入字符串,用sc.next(),如果字符串里有空格,空格之后的字符不接收
  • 如何才能接收包含空格的字符串呢?那就要用到Java的缓冲字符输入流(BufferedReader)
  • 如何进行异常处理,可以自己写,也可以利用菜单来生成异常处理框架

(二) 讲解知识点

(三)拓展练习

任务1、由卡号计算幸运数

  • 员工卡号是四位整数[1000,9999][1000,9999][1000,9999],各位数字的和就是参加抽奖活动的幸运数字,比如451245124512,4+5+1+2=124 + 5 + 1 + 2 = 124+5+1+2=12,幸运数字就是121212
  • 输入员工卡号,编程计算该员工的幸运数字
  • 方法一:直接拆分整数
  • 方法二:转换成字符串来处理
  • 计算机科学家Wirth在上个世纪70年代提出一个经典公式:程序 = 数据结构 + 算法,数据结构是程序的基础,算法是程序的灵魂。

任务2、求解一元二次方程

  • ax2+bx+c=0,a≠0ax^2+bx+c=0, a\neq0ax2+bx+c=0,a​=0
  • 输入系数a,b,ca, b, ca,b,c,要求Δ≥0\Delta\ge0Δ≥0,编程计算其实根
  • x1=−b+b2−4ac2a,x2=−b−b2−4ac2a\displaystyle x_1=\frac{-b+\sqrt{b^2-4ac}}{2a},x_2=\frac{-b-\sqrt{b^2-4ac}}{2a}x1​=2a−b+b2−4ac​​,x2​=2a−b−b2−4ac​​

任务2、闰年判断

  • 什么是闰年?有两种情况:能被4整除但是不能被100整除;能被400整除
  • 解决闰年判断问题,涉及三种运算:算术运算、关系运算、逻辑运算
  • 第一种闰年情况:year % 4 == 0 && year % 100 != 0
  • 第二种闰年情况:year % 400 == 0

(一)编程实现

  • net.huawei.p02.t02包里创建Task02
package net.huawei.p02.t02;import java.util.Scanner;/*** 功能:闰年判断* 作者:华卫* 日期:2022年03月24日*/
public class Task02 {public static void main(String[] args) {// 声明部分int year;String result;Scanner sc = new Scanner(System.in);// 输入部分System.out.print("year = ");year = sc.nextInt();// 处理部分if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {result = year + "是闰年。";} else {result = year + "是平年。";}// 输出部分System.out.println(result);}
}
  • 运行程序,查看结果

  • 闰年条件涉及到两种逻辑运算符,逻辑与&&和逻辑或||,但是没有用逻辑非!,请你修改闰年条件,能够将三种逻辑运算符都派上用场。(在Python里:not、and、or)

(二)讲解知识点

  • 演示求余运算
  • 演示关系运算
  • 演示逻辑运算
  • 双分支结构,分支只有一条语句时,可以省掉花括号

(三)拓展练习

任务1、计算圆面积(选择结构版)

  • 利用选择结构防范用户输入负的半径
  • 单分支结构一般用于把关或过滤。当然,大家可以用双分支结构来处理这个问题。
  • 要求每行只输出5个数,那么就需要一个计数变量count

任务2、求解一元二次方程(选择结构版)

  • Δ≥0\Delta\ge0Δ≥0,输出两个实数解,否则提示用户“此方程没有实根!”
  • 提示:计算平方根 - Math.sqrt(b * b - 4 * a * c)

任务3、成绩等级评定

  • 对百分制成绩评定等级
(100, +∞):超出范围
[90, 100]:优秀
[80, 90):良好
[70, 80):中等
[60, 70):及格
[0, 60):不及格
(-∞, 0):超出范围

(一)编程实现

方法一、采用并列式多分支结构评定成绩等级

  • 思路:有多少种情况,就并列写多少个单分支,分支之间相互独立

  • 第1个分数段:score>100,score∈(100,+∞)score \gt 100, score \in (100, +\infty)score>100,score∈(100,+∞) - 超出范围

  • 第2个分数段:90≤score≤100,score∈[90,100]90 \le score \le 100, score \in [90, 100]90≤score≤100,score∈[90,100] - 优秀

  • 第3个分数段:80≤score<90,score∈[80,90)80 \le score \lt 90, score \in [80, 90)80≤score<90,score∈[80,90) - 良好

  • 第4个分数段:70≤score<80,score∈[70,80)70 \le score \lt 80, score \in [70, 80)70≤score<80,score∈[70,80) - 中等

  • 第5个分数段:60≤score<70,score∈[60,70)60 \le score \lt 70, score \in [60, 70)60≤score<70,score∈[60,70) - 及格

  • 第6个分数段:0≤score<60,score∈[0,60)0 \le score \lt 60, score \in [0, 60)0≤score<60,score∈[0,60) - 不及格

  • 第7个分数段:score<0,score∈(−∞,0)score \lt 0, score \in (-\infty, 0)score<0,score∈(−∞,0) - 超出范围

  • net.huawei.p02.t03创建Task03_1

  • 怎么解决这个问题呢?很简单,在处理部分之前将level初始化为空字符串

package net.huawei.p02.t03;import java.util.Scanner;/*** 功能:采用并列式多分支结构评定成绩等级* 作者:华卫* 日期:2022年03月31日*/
public class Task03_1 {public static void main(String[] args) {// 声明部分int score;String level;Scanner sc = new Scanner(System.in);// 输入部分System.out.print("score = ");score = sc.nextInt();// 处理部分level = "";if (score > 100) level = "超出范围";if (score >= 90 && score <= 100) level = "优秀";if (score >= 80 && score < 90) level = "良好";if (score >= 70 && score < 80) level = "中等";if (score >= 60 && score < 70) level = "及格";if (score >= 0 && score < 60) level = "不及格";if (score < 0) level = "超出范围";// 输出部分System.out.println(level);}
}
  • 运行程序,查看结果(测试七种情况)






  • 总结:并列式多分支结构,优点是易于理解,但缺点是效率低(思考一下,为什么效率低)。
  • 其实,这个程序可以作点优化,因为成绩大于100分或小于0分都是超出范围,所以可以将这两个并列的分之合而为一。

方法二、采用嵌套式多分支结构评定成绩等级

思路1、从高分到低分来划分各个分数段

  • net.huawei.p02.t03包里创建Task03_2
package net.huawei.p02.t03;import java.util.Scanner;/*** 功能:采用嵌套式多分支结构评定成绩等级* 作者:华卫* 日期:2022年03月31日*/
public class Task03_2 {public static void main(String[] args) {// 声明部分int score;String level;Scanner sc = new Scanner(System.in);// 输入部分System.out.print("score = ");score = sc.nextInt();// 处理部分level = "";if (score > 100) {level = "超出范围";} else {if (score >= 90) {level = "优秀";} else {if (score >= 80) {level = "良好";} else {if (score >= 70) {level = "中等";} else {if (score >= 60) {level = "及格";} else {if (score >= 0) {level = "不及格";} else {level = "超出范围";}}}}}}// 输出部分System.out.println(level);}
}
  • 运行程序,查看结果(测试七种情况)






思路2、从低分到高分来划分各个分数段

  • net.huawei.p02.t03包里创建Task03_2_
  • 运行程序,查看结果(测试七种情况)






  • 总结:嵌套式多分支结构,优点是层次分明、效率高,但缺点是嵌套层次太多时显得很繁。

方法三、采用延拓式多分支结构评定成绩等级

思路1:从高分到低分来划分各个分数段

  • net.huawei.p02.t03包里创建Task03_3
package net.huawei.p02.t03;import java.util.Scanner;/*** 功能:采用延拓式多分支结构评定成绩等级* 作者:华卫* 日期:2022年04月07日*/
public class Task03_3 {public static void main(String[] args) {// 声明部分int score;String level;Scanner sc = new Scanner(System.in);// 输入部分System.out.print("score = ");score = sc.nextInt();// 处理部分level = "";if (score > 100) {level = "超出范围";} else if (score >= 90) {level = "优秀";} else if (score >= 80) {level = "良好";} else if (score >= 70) {level = "中等";} else if (score >= 60) {level = "及格";} else if (score >= 0) {level = "不及格";} else {level = "超出范围";}// 输出部分System.out.println(level);}
}
  • 运行程序,查看结果






思路2、从低分到高分来划分各个分数段

  • net.huawei.p02.t03包里创建Task03_3_
package net.huawei.p02.t03;import java.util.Scanner;/*** 功能:采用延拓式多分支结构评定成绩等级* 作者:华卫* 日期:2022年04月07日*/
public class Task03_3_ {public static void main(String[] args) {// 声明部分int score;String level;Scanner sc = new Scanner(System.in);// 输入部分System.out.print("score = ");score = sc.nextInt();// 处理部分level = "";if (score < 0) {level = "超出范围";} else if (score < 60) {level = "不及格";} else if (score < 70) {level = "及格";} else if (score < 80) {level = "中等";} else if (score < 90) {level = "良好";} else if (score <= 100) {level = "优秀";} else {level = "超出范围";}// 输出部分System.out.println(level);}
}
  • 运行程序,查看结果






  • 总结:延拓式多分支结构,优点是只有一层,并且效率高。希望同学们务必掌握这一种多分支处理方式。

方法四、采用开关式多分支结构评定成绩等级

  • 关键点在于将成绩变量整除10,以便将各个分数段转换成离散的整数值,这样才能用开关式多分支结构来进行处理。
  • net.huawei.p02.t03包里创建Task03_4
package net.huawei.p02.t03;import java.util.Scanner;/*** 功能:采用开关式多分支结构评定成绩等级* 作者:华卫* 日期:2022年04月07日*/
public class Task03_4 {public static void main(String[] args) {// 声明部分int score;String level;Scanner sc = new Scanner(System.in);// 输入部分System.out.print("score = ");score = sc.nextInt();// 处理部分level = "";if (score < 0 || score > 100) {level = "超出范围";} else {switch (score / 10) {case 10:case 9:level = "优秀";break;case 8:level = "良好";break;case 7:level = "中等";break;case 6:level= "及格";break;default:level = "不及格";                    }}// 输出部分System.out.println(level);}
}
  • 运行程序,查看结果






  • 总结:开关式多分支结构,优点是书写简洁,并且效率高,但缺点是只能针对离散型的情况进行处理。开关式多分支结构里的测试表达式,类型可以是整数、字符、甚至可以是字符串。

(二)讲解知识点

  • 多分支结构可有四种处理方式:并列式、嵌套式、延拓式、开关式

1、并列式多分支结构

if (条件1) {语句组1
}
if (条件2) {语句组2
}
……
if (条件n) {语句组n
}

2、嵌套式多分支结构

if (条件) {if (条件1) {语句组1} else {……}
} else {if (条件2) {语句组2} else {……}
}

3、延拓式多分支结构

if (条件1) {语句组1
} else if (条件2) {语句组2
}
……
} else if (条件n) {语句组n
} else {语句组n+1
}

4、开关式多分支结构

switch (测试表达式) {case 值1:语句组1break;case 值2:语句组2break;……case 值n:语句组nbreak;default:语句组n+1
}

(三)拓展练习

任务1、确定给定日期是一年的第几天

  • 要求输入年、月、日,最好能判断用户输入的是否是合法日期
  • 比如2022年3月31日, 那是今年的第90天(31 + 28 + 31 = 90)
  • 比如2000年3月31日,那是2000年的第91天(31 + 29 + 31 = 91)

任务 2、构建可进不可退的多级菜单系统

名片管理系统{登录{添加名片修改名片查询名片删除名片退出名片管理系统\begin{cases} 登录\begin{cases} 添加名片\\ 修改名片\\ 查询名片\\ 删除名片\\ \end{cases} \\ 退出\\ \end{cases}名片管理系统⎩⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎧​登录⎩⎪⎪⎪⎨⎪⎪⎪⎧​添加名片修改名片查询名片删除名片​退出​

  • 采用开关式多分支结构来实现菜单系统
  • net.huawei.p02.t03包里创建XExercise02
  • 先完成一级菜单
package net.huawei.p02.t03;import java.util.Scanner;/*** 功能:构建可进不可退的多级菜单系统* 作者:华卫* 日期:2022年04月07日*/
public class XExercise02 {public static void main(String[] args) {// 声明部分int mc1;Scanner sc = new Scanner(System.in);// 绘制一级菜单System.out.println("   名片管理系统");System.out.println("==================");System.out.println("     1. 登录");System.out.println("     0. 退出");System.out.println("==================");System.out.print("输入菜单编号[1,0]:");// 根据用户选择执行相应操作mc1 = sc.nextInt();switch (mc1) {case 1:System.out.println("用户登录尚未完成");break;case 0:System.out.println("谢谢使用~再见~");break;default:System.out.println("输入的菜单编号有误!");}}
}
  • 运行程序,查看结果


  • 采用模块化思想,创建一个登录方法 - login(),然后再用户选择1菜单项时调用它
  • 编写login()方法
  • 运行程序,测试登录方法

  • 登录成功之后,定义名片管理方法 - cardManagment()
  • 编写cardManagement()方法代码
  • 运行程序,测试名片管理方法
  • 现在这个菜单系统是可进但是不可退,有一个入口,但有多个入口,等我们学了循环结构之后,我们可以改进这个菜单系统,使之成为可进可退的多级菜单系统,保证系统只有唯一的入口和唯一的出口。

任务3、根据收入计算个人所得税

  • 个人所得税税率表一(综合所得适用)

任务4、等差数列求和

  • 任务:计算1 + 2 + 3 + …… + 100的值

(一)编程实现

  • 创建net.huawei.p02.t04包,然后在包里创建Task04
package net.huawei.p02.t04;/*** 功能:计算1 + 2 + 3 + …… + 100的值* 作者:华卫* 日期:2022年04月07日*/
public class Task04 {public static void main(String[] args) {// 声明部分int sum;// 初始化sum = 0;// 处理部分(for循环也叫计数循环,用于事先知道要循环多少次的情况)for (int i = 1; i <= 100; i++) { // 循环头:初始条件;循环条件;迭代条件sum = sum + i; // 累加语句            }// 输出部分System.out.println("1 + 2 + 3 + …… + 100 = " + sum);}
}
  • i++: 后自增,先用后增

  • 运行程序,查看结果

  • 其实1 + 2 + 3 + …… + 100跟100 + 99 + …… + 3 + 2 + 1是等值的,因此for循环可以从100递减循环到1来计算

  • 大家不妨编程计算1 + 3 + 5 + … + 99的值


  • 第1种和第2种方法都循环100次,但是第3种方法只循环了50次,效率高一些。

(二)讲解知识点

1、for循环

(1)语法格式
for(初始化表达式; 循环条件; 操作表达式){执行语句...break | continue...
}
(2)执行流程

  • 当循环条件成立时,执行循环,直到循环条件不成立时,终止循环。

2、自增自减运算

(1)自增运算
  • 后自增:先用后增
  • 签字增:先增后用
(2)自减运算
  • 后自减:先用后减
  • 前自减:先减后用

(三)拓展练习

任务1、打印水仙花数

  • 所谓水仙花数,是指等于其各位数字立方和的三位数。

\qquad153=13+53+33153=1^3+5^3+3^3153=13+53+33
\qquad370=33+73+03370=3^3+7^3+0^3370=33+73+03
\qquad371=33+73+13371=3^3+7^3+1^3371=33+73+13
\qquad407=43+03+73407=4^3+0^3+7^3407=43+03+73

  • 分析问题,首先水仙花数是三位数,那么我们可以确定范围:[100, 999],这个我们可以通过循环结构来搞定:
for (int n = 100; n <= 999; n++) {...
}
  • 然后对于这个范围的每个数n,我们要去判断它是否等于其各位数字的立方和,这里的难点或关键在于如何分解一个三位数,得到它的每位数字。

  • 假设我们已经把三位数n分解成百位数p3,十位数p2,个位数p1,这样我们的筛选条件就可以写出来:n == p3 * p3 * p3 + p2 * p2 * p2 + p1 * p1 * p1。

  • 如何拆分一个三位数n(375)呢?

  • 首先求n的个位数:n % 10 = 375 % 10 = 5
    然后要将三位数变成两位数:n = n / 10 = 375 / 10 = 37;
    对于新的两位数n,又求它的个位数:n % 10 = 37 % 10 = 7
    然后要将两位数变成一位数:n = n / 10 = 37 / 10 = 3;

  • 我们可以交替使用求余和整除运算将一个三位数拆分,得到它的个位数、十位数和百位数。当然这个分解方法可以推广到任何多位数的拆分。

任务2、输出指定范围内的闰年

  • 输出[2000, 2500]内的全部闰年,要求每行输出5个年份

任务3、判断一个整数是不是素数

  • 输入一个整数,判断它是不是素数

  • 概念:什么叫素数(Prime Number)?一个整数除了1和它本身之外没有其它因子,这个整数就叫素数,否则就叫合数,但是有一个特殊情况,1既不是素数,也不是合数。比如:2、3、5、7都是素数,它们除了1和本身都没有其它因子,但是6就是合数,除了1和6之外,还有2和3都是其因子(6 = 2 * 3)。

  • 方法:判断一个整数是不是素数的方法 - 比如我们考虑一个整数n(n≥2)n(n\ge2)n(n≥2),就要看从222到n−1n-1n−1的每个数能否整除nnn,如果能整除,那么nnn就不是素数;如果从头到尾都不能整除,那么nnn就是素数。

  • 编程思路:我们采用一个布尔型的标志变量isPrimeNumber来表示待判断的整数n是不是素数,如果isPrimeNumber = true表明是素数,如果isPrimeNumber = false表明不是素数。先假定待判断的整数n是素数,设置isPrimeNumber = true,一旦在循环里找到能整除n的真因子,说明n不是素数,立马设置isPrimeNumber = false,并跳出循环结果。循环之后就根据isPrimeNumber的真假来输出n是素数还是合数。(这个编程思路,有点类似于法院断案,先假定你是好人,只有找到犯罪证据,才能断定你是罪犯。)

任务5、打印乘法九九表

(一)编程实现

  • net.huawei.t05包里创建Task05
package net.huawei.p02.t05;/*** 功能:打印九九表* 作者:华卫* 日期:2022年04月07日*/
public class Task05 {public static void main(String[] args) {for (int i = 1; i <= 9; i++) {for (int j = 1; j <= i; j++) {System.out.print(i + "×" + j + "=" + (i * j) + "\t");}System.out.println();}}
}
  • 运行程序,查看结果

(二)讲解知识点

1、语法格式

for(初始化表达式; 循环条件; 操作表达式) {...for(初始化表达式; 循环条件; 操作表达式) {执行语句...}...
}

2、执行规则

  • 在双层for循环嵌套中,外层循环每执行一轮,都要执行完内层循环中的整个for循环,然后执行外层循环第二轮,接着再执行完内层循环中的整个for循环,以此类推,直至外层循环的循环条件不成立,才会跳出整个嵌套for循环。如果外循环有mmm次,内循环有nnn次,那么内循环里的操作会执行m×nm\times nm×n次。

(三)拓展练习

任务1、解决百钱买百鸡问题

  • 我国古代数学家张丘建在《算经》一书中曾提出过著名的“百钱买百鸡”问题,该问题叙述如下:鸡翁一,值钱五;鸡母一,值钱三;鸡雏三,值钱一;百钱买百鸡,则翁、母、雏各几何?

  • 翻译过来,意思是公鸡一个五块钱,母鸡一个三块钱,小鸡三个一块钱,现在要用一百块钱买一百只鸡,问公鸡、母鸡、小鸡各多少只?

  • 需要定义三个整型变量cock, hen, chick,分别代表公鸡、母鸡和小鸡的购买数量。

  • 有两方面的条件:关于钱的条件与关于鸡的条件
    – 钱的条件:cock×5+hen×3+chick3=100cock \times5+hen\times3+\displaystyle\frac{chick}{3}=100cock×5+hen×3+3chick​=100
    – 鸡的条件:cock+hen+chick=100cock+hen+chick=100cock+hen+chick=100

任务2、蓝桥杯竞赛题:验证四平方和定理

  • 四平方和定理,又称为拉格朗日定理:每个正整数都可以表示为至多4个正整数的平方和。如果把0包括进去,就正好可以表示为4个数的平方和。比如:5=02+02+12+225 = 0^2 + 0^2 + 1^2 + 2^25=02+02+12+22,7=12+12+12+227 = 1^2 + 1^2 + 1^2 + 2^27=12+12+12+22
  • 对于一个给定的正整数,可能存在多种平方和的表示法。要求你对4个数排序:0≤a≤b≤c≤d0\le a \le b \le c \le d0≤a≤b≤c≤d,并对所有的可能表示法按a,b,c,da,b,c,da,b,c,d 为联合主键升序排列,最后输出第一个表示法。程序输入为一个正整数N(N<5000000)N (N<5000000)N(N<5000000),要求输出444个非负整数,按从小到大排序,中间用空格分开。
  • 例如,输入:555,则程序应该输出:00120\ 0\ 1\ 20 0 1 2

任务3、打印字符等腰三角形

  • 用户输入行数, 比如10, 就打印10行等腰三角形

任务6、猜数小游戏(单次版)

  • 游戏规则:程序产生一个[1, 100]之间的随机整数,用户输入整数进行猜测,如果猜对了,就结束游戏;如果猜错了,程序会提示你是猜高了还是猜低了,然后让你继续输入整数进行猜测。

(一)编程实现

  • net.huawei.p02.t06包里创建Task06
package net.huawei.p02.t06;import java.util.Random;
import java.util.Scanner;/*** 功能:猜数小游戏* 作者:华卫* 日期:2022年04月07日*/
public class Task06 {public static void main(String[] args) {// 声明部分int x, target;Scanner sc = new Scanner(System.in);Random random = new Random();// 产生猜测目标target = random.nextInt(100);// 输入猜测的整数System.out.print("输入一个[1, 100]的整数:");x = sc.nextInt();while (x != target) {// 判断是猜高了还是猜低了if (x > target) {System.out.println("朋友,你猜高了~继续猜吧");} else {System.out.println("朋友,你猜低了~继续猜吧");}// 继续输入猜测的整数System.out.print("输入一个[1, 100]的整数:");x = sc.nextInt();}System.out.println("恭喜你猜对了,游戏结束~");}
}
  • 运行程序,查看结果
  • 如果采用二分法来猜测,猜测次数最多不会超过log2100≈7\mathrm{log}_2100\approx 7log2​100≈7
  • net.huawei.p02.t06包里创建Task06_
package net.huawei.p02.t06;import java.util.Random;
import java.util.Scanner;/*** 功能:猜数小游戏* 作者:华卫* 日期:2022年04月14日*/
public class Task06_ {public static void main(String[] args) {// 声明部分int target, x;Scanner sc = new Scanner(System.in);// 产生猜测目标Random random = new Random();target = random.nextInt(100);while (true) {// 用户输入猜测的数System.out.print("输入一个[1, 100]的整数:");x = sc.nextInt();// 判断用户是否猜测正确if (x > target) {System.out.println("朋友,你猜高了~继续猜吧");} else if (x < target){System.out.println("朋友,你猜低了~继续猜吧");} else {break; // 猜中了,跳出循环}}System.out.println("恭喜你猜对了,游戏结束!");}
}
  • 运行程序,查看结果

(二)讲解知识点

1、前测试条件循环 - while循环

(1)语法格式
初始条件
while (循环条件) {语句块break|continue;更新条件
}
(2)执行情况

  • 首先判断循环条件是真还是假,如果是真的,执行循环体,然后再次判断循环条件。如果是真的,继续循环,直到循环条件变成假的。有一种特殊情况:如果第一次判断循环条件就不成立,那么一次循环也不执行。

2、后测试条件循环 - do…while循环

(1)语法格式
初始条件
do {语句块break|continue;更新条件
} while (循环条件);
(2)执行情况

  • 首先执行一次循环,然后判断循环条件,如果为真,继续循环,直到条件为假时结束循环。后测试当型循环,属于先上车后买票,无论如何都会执行一次循环。

3、随机类 - Random

  • 查看Random的方法
  • 产生指定范围的随机整数[a, b]
Random random = new Random();
int x = a + random.nextInt(b - a);

(三)拓展练习

任务1、猜数小游戏(多次版)

  • 如果用户猜对了,会询问用户是否继续玩。

任务2、构建可进可退的多级菜单系统

  • net.huawei.p02.t06包里创建XExercise02
  • 给一级菜单添加循环
  • 运行程序,测试效果
  • 编写登录方法 - login()
  • 运行程序,测试效果
  • 编写名片管理方法 - cardManagement()
  • 运行程序,查看效果
  • 查看完整源代码
package net.huawei.p02.t06;import java.util.Scanner;/*** 功能:构建可进可退的多级菜单系统* 作者:华卫* 日期:2022年04月07日*/
public class XExercise02 {public static void main(String[] args) {// 声明部分int mc1;Scanner sc = new Scanner(System.in);boolean isRunning = true; // 循环控制变量while (isRunning) {// 绘制一级菜单System.out.println("  名片管理系统");System.out.println("================");System.out.println("   1. 登录");System.out.println("   0. 退出");System.out.println("================");System.out.print("输入菜单编号[1,0]:");mc1 = sc.nextInt();// 根据用户选择进行相应的操作switch (mc1) {case 1:// 调用登录方法login();break;case 0:System.out.println("谢谢使用~再见~");isRunning = false; // 结束循环break;default:System.out.println("输入的菜单编号有误!");}}}/*** 登录方法*/private static void login() {String username, password;Scanner sc = new Scanner(System.in);System.out.print("用户名:");username = sc.next();System.out.print("密  码:");password = sc.next();if (username.equals("howard") && password.equals("903213")) {System.out.println("登录成功~");// 调用名片管理方法cardManagement();} else {System.out.println("用户名或密码有误,登录失败~");}}/*** 名片管理方法*/private static void cardManagement() {int mc2;Scanner sc = new Scanner(System.in);boolean isRunning = true; // 循环控制变量while (isRunning) {// 绘制二级菜单System.out.println("=====名片管理======");System.out.println("  1. 添加名片");System.out.println("  2. 修改名片");System.out.println("  3. 查询名片");System.out.println("  4. 删除名片");System.out.println("  5. 返回上级");System.out.println("===================");System.out.print("输入菜单编号[1,2,3,4,5]:");mc2 = sc.nextInt();switch (mc2) {case 1:System.out.println("执行添加名片功能~");break;case 2:System.out.println("执行修改名片功能~");break;case 3:System.out.println("执行查询名片功能~");break;case 4:System.out.println("执行删除名片功能~");break;case 5:isRunning = false; // 结束二级菜单循环break;default:System.out.println("输入的菜单编号有误!");}}}
}

任务3、模拟微信拼手气红包程序产生指定个数的随机红包

  • 输入总金额与红包数,随机给每个红包分配金额

任务7、统计一组学生成绩

  • 统计一组学生成绩的总分、平均分、最高分和最低分
  • 假如一组学生100个人,利用前面所学的知识,程序就需要声明10个变量score1,score2,...,score100\mathrm{score1, score2, ..., score100}score1,score2,...,score100,来分别记住每位学生的成绩,计算平均分
  • average=score1+score2+...+score100100\mathrm{average}=\displaystyle\frac{\mathrm{score1+score2+...+score100}}{100}average=100score1+score2+...+score100​会显得特别麻烦,此时我们用一个数组来保存100个成绩,通过数组的索引或下标来访问每一个成绩,可以使用循环来处理。

(一)编程实现

  • net.huawei.p02.t07包里创建Task07
package net.huawei.p02.t07;import java.util.Scanner;/*** 功能:统计一组学生成绩* 作者:华卫* 日期:2022年04月07日*/
public class Task07 {public static void main(String[] args) {// 声明部分double[] scores = new double[10]; // 双精度一维数组,10个元素,scores[0], scores[1],..., scores[9]double sum, average, max, min;Scanner sc = new Scanner(System.in);// 输入部分for (int i = 0; i < scores.length; i++) {System.out.print("scores[" + i + "] = ");scores[i] = sc.nextDouble();}// 处理部分sum = 0;for (int i = 0; i < scores.length; i++) {sum = sum + scores[i];}average = sum / scores.length;max = Double.MIN_VALUE;for (int i = 0; i < scores.length; i++) {if (scores[i] > max) {max = scores[i];}}min = Double.MAX_VALUE;for (int i = 0; i < scores.length; i++) {if (scores[i] < min) {min = scores[i];}}// 输出部分System.out.println("sum = " + sum);System.out.println("average = " + average);System.out.println("max = " + max);System.out.println("min = " + min);}
}
  • 运行程序,查看结果
  • 可以利用增强for循环来遍历数组

课堂练习

  • 任务1、确保输入成绩在[0, 100]范围内
  • 任务2、确定最高分或最低分的位置

(二)讲解知识点

1、一维数组定义

(1)语法格式
数组类型[] 数组名 = new 数组类型[数组长度];
数组类型[] 数组名 = new 数组类型[]{数组元素0, 数组元素1, ...};
数组类型[] 数组名 = {数组元素0, 数组元素1, ...};
(2 )数组定义示例
int[] ids = new int[100];
String[] names = new String[] {"洪艳林", "陈燕文", "郑晓琳", "唐竹龙"};
Object[] student = {1, "张三丰", "男", 20, "15892924560", "maths007@163.com"};
(3)数组定义的内存变化图
  • 声明数组变量,此时数组变量还是null,赋值实例化数组之后,才会给它分配内存空间

2、不同类型数组元素默认初始值

数据类型 默认初始值
byte, short, int, long 0
float, double 0.0
char 一个空字符,即’\u0000’
boolean false
引用数据类型 null,表示变量不引用任何对象

3、避免数组下标越界异常

  • 每个数组的索引(下标)都有一个范围,即[0, length - 1]。在访问数组的元素时,索引不能超出这个范围,否则程序会报错(ArrayIndexOutOfBoundsException,即数组角标越界异常)。

4、避免数组空指针异常

  • 在使用变量引用一个数组时,变量必须指向一个有效的数组对象,如果该变量的值为null,则意味着没有指向任何数组,此时通过该变量访问数组的元素会出现错误(NullPointerException,即空指针异常)。

(三)拓展练习

任务1、蓝桥杯竞赛题:回文日期问题

  • 2020 年春节期间,有一个特殊的日期引起了大家的注意:2020 年 2 月 2 日。因为如果将这个日期按“yyyymmdd”的格式写成一个 8 位数是 20200202,恰好是一个回文数。我们称这样的日期是回文日期。有人表示 20200202 是“千年一遇”的特殊日子。对此小明很不认同,因为不到 2 年之后就是下一个回文日期:20211202 即 2021年 12月2日。也有人表示 20200202 并不仅仅是一个回文日期,还是一个 ABABBABA 型的回文日期。对此小明也不认同,因为大约 100 年后就能遇到下一个 ABABBABA 型的回文日期:21211212即2121 年 12 月 12 日。算不上“千年一遇”,顶多算“千年两遇”。
  • 给定一个 8 位数的日期,请你计算该日期之后下一个回文日期和下一个 ABABBABA 型的回文日期各是哪一天。
  • 输入描述:输入包含一个八位整数 N,表示日期。
    对于所有评测用例,10000101 ≤ N ≤ 89991231,保证 N 是一个合法日期的 8 位数
  • 输出描述:输出两行,每行 1 个八位数。第一行表示下一个回文日期,第二行表示下一个 ABABBABA 型
    的回文日期。

任务2、数组排序(升序和降序排列)

1、选择法排序
(1)选择法排序含义
  • 选择排序(Selection Sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。
(2)选择法排序实现步骤
  • 选择法排序(降序):nnn个数排序,经过n−1n-1n−1轮比较。
    – 第111轮是第111个数跟剩下的(n−1)(n-1)(n−1)个数比较,让第111个数成为本轮最大者,要比较(n−1)(n-1)(n−1)次;
    – 第222轮是第222个数跟剩下的(n−2)(n-2)(n−2)个数比较,让第222个数成为本轮最大者,要比较(n−2)(n-2)(n−2)次;
    – ……
    – 第(n−1)(n-1)(n−1)轮是第(n−1)(n-1)(n−1)个数与剩下的111个数比较,让第(n−1)(n-1)(n−1)个数成为本轮最大者,要比较111次。
    – 总比较次数:(n−1)+(n−2)+...+2+1=n(n−1)2=O(n2)(n-1)+(n-2)+...+2+1 = \displaystyle \frac{n(n-1)}{2}=O(n^2)(n−1)+(n−2)+...+2+1=2n(n−1)​=O(n2)

2、冒泡法排序
(1)冒泡法排序含义
  • 冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端。
(2)冒泡法排序实现步骤
  • 冒泡法排序(降序):nnn个数排序,经过n−1n-1n−1轮比较。
    – 第111轮是nnn个数里相邻两个数比较,如果后者比前者大就交换,要比较(n−1)(n-1)(n−1)次,本轮最小者“浮”到第nnn个位置;
    – 第222轮是前(n−1)(n-1)(n−1)个数里相邻两个数比较,如果后者比前者大就交换,要比较(n−2)(n-2)(n−2)次,本轮最小者“浮”到第(n−1)(n-1)(n−1)个位置;
    – ……
    – 第(n−1)(n-1)(n−1)轮是前222个数里相邻两个数比较,如果后者比前者大就交换,要比较111次,本轮最小者“浮”到第222个位置;
    – 总比较次数:(n−1)+(n−2)+...+2+1=n(n−1)2(n-1)+(n-2)+...+2+1 = \displaystyle \frac{n(n-1)}{2}(n−1)+(n−2)+...+2+1=2n(n−1)​

补充:利用Arrays工具提供的sort()方法实现数组排序

  • net.huawei.p02.t07包里创建XExercise02_3
  • 运行程序,查看结果
  • 怎么才能实现降序排列呢?此时,我们还得传一个参数给sort()方法,这个参数是Collections.reverseOrder()
  • 运行程序,查看结果
  • 要访问一个班的全部同学,有两种方式:一种方式是通过学号(id),相当于采用一维数组来访问;一种方式是通过座位号(row, col),相当于采用二维数组来访问。

任务8、打印杨辉三角形

  • 杨辉三角,是二项式系数在三角形中的一种几何排列,中国南宋数学家杨辉1261年所著的《详解九章算法》一书中出现。在欧洲,帕斯卡(1623 ~ 1662)在1654年发现这一规律,所以这个表又叫做帕斯卡三角形。帕斯卡的发现比杨辉要迟393年,比贾宪迟600年。

(a+b)1=a+b(a+b)^1=a+b(a+b)1=a+b
(a+b)2=a2+2ab+b2(a+b)^2=a^2+2ab+b^2(a+b)2=a2+2ab+b2
(a+b)3=a3+3a2b+3ab2+b3(a+b)^3=a^3+3a^2b+3ab^2+b^3(a+b)3=a3+3a2b+3ab2+b3
(a+b)4=a4+4a3b+6a2b2+4ab3+b4(a+b)^4=a^4+4a^3b+6a^2b^2+4ab^3+b^4(a+b)4=a4+4a3b+6a2b2+4ab3+b4
……

  • 二项式定理,又称牛顿二项式定理,由艾萨克牛顿于1664-1665年提出。

(a+b)n=Cn0an+Cn1an−1b+Cn2an−2b2+……+Cnian−ibi+……+Cnn−1abn−1+Cnnbn=∑i=0nCnian−ibi,Cni=n!(n−i)!⋅i!(a+b)^n=C_n^0a^n+C_n^1a^{n-1}b+C_n^2a^{n-2}b^2+……+C_n^ia^{n-i}b^i+……+C_n^{n-1}ab^{n-1}+C_n^nb^n=\displaystyle \sum_{i=0}^nC_n^ia^{n-i}b^i,C_n^i=\frac{n!}{(n-i)!\cdot i!}(a+b)n=Cn0​an+Cn1​an−1b+Cn2​an−2b2+……+Cni​an−ibi+……+Cnn−1​abn−1+Cnn​bn=i=0∑n​Cni​an−ibi,Cni​=(n−i)!⋅i!n!​

(一)编程实现

  • 思路:用二维数组来保存杨辉三角形的元素
    111121133114641……\begin{matrix} 1&\\ 1&1\\ 1 &2 &1\\ 1 &3 &3 &1\\ 1 &4 &6 &4 &1\\ …… \end{matrix}11111……​1234​136​14​1​
  • 边界:a[i][0]=1,a[i][i]=1,i∈[0,n−1]a[i][0] = 1, a[i][i] =1, i\in[0, n-1]a[i][0]=1,a[i][i]=1,i∈[0,n−1]
  • 内部:a[i][j]=a[i−1][j−1]+a[i−1][j],i∈[2,n],j∈[1,i−1]a[i][j]=a[i-1][j-1]+a[i-1][j],i \in[2,n],j\in[1,i-1]a[i][j]=a[i−1][j−1]+a[i−1][j],i∈[2,n],j∈[1,i−1]
  • net.huawei.p02.t08包里创建Task08

package net.huawei.p02.t08;/*** 功能:打印杨辉三角形* 作者:华卫* 日期:2022年04月14日*/
public class Task08 {public static void main(String[] args) {// 声明部分(三角形二维数组)int[][] a = new int[15][];// 每行元素个数跟行数一致for (int i = 0; i < a.length; i++) {a[i] = new int[i + 1];}// 边界赋值for (int i = 0; i < a.length; i++) {a[i][0] = 1; // 左边界a[i][i] = 1; // 右边界(对角线)}// 内部元素采用递推公式计算for (int i = 2; i < a.length; i++) {for (int j = 1; j < i; j++) {a[i][j] = a[i - 1][j - 1] + a[i - 1][j];}}// 输出杨辉三角形for (int i = 0; i < a.length; i++) {for (int j = 0; j <= i; j++) {System.out.print(a[i][j] + "\t");}System.out.println();}}
}
  • 运行程序,查看结果

  • 杨辉三角形的数据没有问题,但是格式不好看,需要处理一下,使之显示为三角形。

  • 再运行程序,查看结果

  • 将杨辉三角形显示为等腰三角形

  • 利用循环耗时来实现打字机效果

  • 这种实现动画效果的方式不好,浪费资源,应该采用多线程来实现动画效果。

(二)讲解知识点

1、指定二维数组行数与列数

int[][] xx = new int[3][4];

  • 上面的代码相当于定义了一个3*4的二维数组,这个二维数组的长度为3,可以将它看成3个int[]类型的一维数组,每个一维数组中的元素又是一个长度为4的一维数组。

2、指定二维数组行数,不指定列数

int[][] xx = new int[3][];

  • 第二种方式和第一种类似,只是数组中每个元素的长度不确定。

3、直接使用嵌套大括号“{}”静态初始化二维数组

int[][] xx = {{1, 2}, {3, 4, 5, 6}, {7, 8, 9}};

  • 上面的二维数组中定义了三个元素,这三个元素都是数组,分别为{1, 2}、{3, 4, 5, 6}、{7, 8, 9} 。

(三)拓展练习

任务1、求二维数组最值及位置

  • 产生一个3行4列的随机二维数组

任务2、查询元素是否在二维数组里

  • 可以静态初始化一个二维数组

  • 面向过程 (POP - Procedure-Oriented Programming):操作和数据是分开。比如要进行一个开窗操作。采用面向过程的思路:定义一个window数据,再定义一个open()函数,此时,要打开窗户,调用open()函数,传入窗口数据window,即open(window),相当于是一个动宾结构
  • 面向对象(OOP - Object-Oriented Programming):操作和数据是封装到类里的。比如要进行一个开窗操作。采用面向对象的思路:定义一个Window类,在类里定义一个open()方法,此时,要打开窗户,首先基于Window类创建窗口对象window,调用window对象的open()方法, 即window.open(),相当于是一个主谓结构。

项目三、探索面向对象编程

  • 面向对象程序设计(Object Oriented Programming)作为一种新方法,其本质是以建立模型体现出来的抽象思维过程和面向对象的方法。模型是用来反映现实世界中事物特征的。任何一个模型都不可能反映客观事物的一切具体特征,只能对事物特征和变化规律的一种抽象,且在它所涉及的范围内更普遍、更集中、更深刻地描述客体的特征。通过建立模型而达到的抽象是人们对客体认识的深化。

任务1、采用面向对象方式求三角形面积

  • 采用面向过程的思路:定义一个计算三角形面积的函数calcuateTriangleArea(double a, double b, double c),输入a、b、c,把输入的a、b、c作为参数传入calcuateTriangleArea()函数,得到计算结果。
  • 创建Triangle类,包含a、b、c私有属性,提供无参与有参构造方法,提供getters和setters,重写toString()方法,提供getArea()方法
  • 创建TestTriangle类,创建Triangle对象,设置对象属性a、b、c,调用对象方法,计算出三角形面积

(一)编程实现

  • 创建net.huawei.p03.t01包,然后在包里创建Triangle
  • 定义三个缺省权限的双精度属性a、b、c,定义计算三角形面积的方法getArea(),返回值是双精度

(1)利用三边关系定理判断能否构成三角形

  • 三边关系定理:任意两边之和大于第三边

(2)如果能构成三角形,利用海伦公式来计算

  • 三边为a,b,ca, b, ca,b,c,半周长 p=a+b+c2p=\displaystyle \frac{a+b+c}{2}p=2a+b+c​
  • 面积area=p(p−a)(p−b)(p−c)area=\displaystyle \sqrt{p(p-a)(p-b)(p-c)}area=p(p−a)(p−b)(p−c)​
package net.huawei.p03.t01;/*** 功能:三角形类* 作者:华卫* 日期:2022年04月21日*/
public class Triangle {// 缺省权限属性double a, b, c;/*** @return 三角形面积*/public double getArea() {double s = 0, p;// 判断a、b、c能否构成三角形if (a + b > c && b + c > a && c + a > b) {p = (a + b + c) / 2;s = Math.sqrt(p * (p - a) * (p - b) * (p -c));            } else {s = -1;}return s;}
}
  • 类Triangle封装了数据(a、b、c)和操作(getArea()),封装(Encapsulation)是面向对象三大特性之一。

  • 利用IDEA的工具,可以显示Triangle类的类图

  • 创建一个测试类TestTriangle类,在其主方法里,创建Triangle对象,设置其属性,调用其方法,计算得到三角形面积

package net.huawei.p03.t01;import java.util.Scanner;/*** 功能:测试三角形类* 作者:华卫* 日期:2022年04月21日*/
public class TestTriangle {public static void main(String[] args) {double a, b, c, s;Scanner sc = new Scanner(System.in);// 利用无参构造方法创建三角形对象Triangle triangle = new Triangle();System.out.print("a = ");a = sc.nextDouble();System.out.print("b = ");b = sc.nextDouble();System.out.print("c = ");c = sc.nextDouble();// 设置三角形对象属性triangle.a = a;triangle.b = b;triangle.c = c;// 调用三角形对象方法s = triangle.getArea();// 判断是否构成三角形if (s != -1) {System.out.println("s = " + s);} else {System.out.println("提示:构不成三角形!");}}
}
  • 运行程序,查看结果

  • 缺省权限属性的不足:由于a、b、c是缺省权限属性,可以通过对象.属性名直接访问,比如triangle.a = -10;,边长不能为负,这样直接访问属性显然不合理,因此,我们应该将属性私有化,外界不能直接访问,而必须通过公共方法来设置和获取属性,于是私有属性得到有效的保护。

  • 如何实现类的封装:在定义一个类时,将类中的属性私有化,即使用private关键字来修饰,私有属性只能在它所在类中被访问,如果外界想要访问私有属性,需要提供一些使用public修饰的公有方法,其中包括用于获取属性值的getXXX()方法(简称getter)和设置属性值的setXXX()方法(简称setter)。

  • 修改Triangle类,将a、b、c属性设置为私有属性

  • 查看TestTriangle类,就会发现程序报错,不能通过triangle对象直接去访问私有属性a、b、c

  • 为了让triangle对象能设置私有属性a、b、c,我们就要提供setXXX()方法(setter方法)

  • 参数名与成员变量名相同时,给成员变量名加个this前缀,this这个特殊变量代表的当前类的实例,相当于Python类当中的self

  • 此时,triangle对象可以设置私有属性a、b、c,但是无法获取私有属性值,我们还需定义getXXX()方法 - getter方法

  • 修改TestTriangle类,通过setter方法来设置对象属性

  • 运行程序,查看结果

  • 演示对象调用getXXX()方法

  • 操作技巧:利用IDEA自动生成类的getters和setters

  • 删除掉刚才我们创建getters和setters

  • 演示如何自动生成getters和setters

  • 单击[Code]菜单下[Generate…]或按组合键<Alt>+<Insert>,弹出[Generate]快捷菜单,选择[Getter and Setter],然后选中三个属性a、b、c,单击[OK]按钮即可生成getters和setters。

  • 在TestTriangle类主方法里打印三角形对象,会不会显示三角形的数据信息呢?

  • 显示的是对象的路径.类名@地址,其实地址就是对象的哈希码。

  • 如何才能打印对象时显示对象的数据信息呢,我们需要去重写(Override)Triangle类的toString()方法,类似于Python类__str__()方法的功能。

  • 采用IDEA自动生成toString()方法

  • 再次运行TestTriangle,看看直接打印对象的效果

  • 其实,打印对象时,默认就会调用对象的toString()方法

  • 课堂练习:让三角形面积输出结果保留两位有效数字

  • 刚才我们创建三角形对象时,基于默认的无参构造方法来进行对象初始化的。

  • 如果我们创建类时没有写构造方法,系统会自动添加一个无参构造方法。

  • 大家可以构造方法有什么特点:(1)public权限;(2)没有返回值类型;(3)构造方法名跟类名一样

  • 下面我们来给三角形类定义一个有参构造方法

  • 此时,切换到TestTriangle类,会发现创建对象出错

  • 为什么会报错呢?当我们创建了有参构造方法时,系统就不会自动添加无参构造方法,除非手动添加无参构造方法

  • 把蓝色光条一道类名上,表明不初始化任何成员变量

  • 我们给构造方法写点代码

  • 此时,再去看看TestTriangle类,你会发现错误消失了

  • 运行TestTriangle类,查看结果

  • 创建TestTriangle2类来测试有参构造方法

package net.huawei.p03.t01;import java.util.Scanner;/*** 功能:测试三角形类* 作者:华卫* 日期:2022年04月21日*/
public class TestTriangle2 {public static void main(String[] args) {double a, b, c, s;Scanner sc = new Scanner(System.in);System.out.print("a = ");a = sc.nextDouble();System.out.print("b = ");b = sc.nextDouble();System.out.print("c = ");c = sc.nextDouble();// 基于有参构造方法来创建三角形对象Triangle triangle = new Triangle(a, b, c);// 调用三角形对象方法s = triangle.getArea();// 打印三角形对象System.out.println(triangle.toString());// 判断是否构成三角形if (s != -1) {System.out.println("s = " + String.format("%.2f", s));} else {System.out.println("提示:构不成三角形!");}}
}
  • 运行程序,查看结果
  • 课堂练习:如何防范给三角形a、b、c成员变量赋负的值
  • 修改Triangle类的setA()、setB()、setC()方法
  • 运行TestTriangle类,查看结果
  • 其实这样处理并不是很好,如果边长不是正数,那么就抛出异常,不再去调用三角形对象的方法计算面积
  • 修改TestTriangle,处理异常
  • 运行TestTriangle类,进行测试

(二)讲解知识点

(三)拓展练习

1、任务1、创建学生类并测试

  • 创建Student类,包含id、name、gender、age、major、clazz、phone私有属性,提供无参与有参构造方法,提供getters和setters,提供toString()方法,提供learn()方法

2、任务2、采用面向对象求解一元二次方程

  • 创建一元二次方程类Equation,包含a、b、c三个私有属性,提供getters和setters,提供无参和三参构造方法,一个公共方法solve()。然后创建一个测试类TestEquation,在其主方法里创建Equation对象,设置对象属性,调用对象方法求解方程。

2022年Java程序设计讲课笔记相关推荐

  1. 2019年Java程序设计讲课笔记目录

    2019年Java程序设计讲课笔记目录 1.Java讲课笔记01:Java快速入门 2.Java讲课笔记02:初识集成开发环境Intellij IDEA 3.Java讲课笔记03:Java语法基础 4 ...

  2. 2022年Java学习笔记目录

    一.2022年Java任务驱动课程 任务驱动,统摄知识点:2022年Java程序设计讲课笔记 二.2022年Java学习笔记 (一)踏上Java开发之旅 Java学习笔记1.1.1 搭建Java开发环 ...

  3. 2022年Java项目课程目录

    一.2022Java项目课程目录 Java项目课程01:课程概述 Java项目课程02:系统概述 Java项目课程03:涉及知识点 Java项目课程04:需求分析 Java项目课程05:系统设计 Ja ...

  4. 《Java程序设计》课程学习资源集合

    文章目录 1.<Java程序设计>在线课程(福建省精品在线课程) 2. 在线编程练习题集 3. 郑老师教学博客 4.<Java程序设计>在线课程使用说明-2022版 5. 大学 ...

  5. 关于2022年java学习的期中总结

    朱自清先生用<匆匆>来形容时间匆匆流逝,我用Java学习来形容时间匆匆流逝,转眼都到了2022年的五月了,很感谢本学期刘振东老师教我<java程序设计与应用开发>.我在这学期的 ...

  6. 2021-2022学年度第二学期21级Java程序设计理论模拟考试

    说明:由于看pdf太难受了,重新编辑好放到博客上,方便自己复习,正确答案加粗标红 考试试卷 页码, 1/4 试卷名称:2021-2022学年度第二学期21级Java程序设计理论模拟考试(3.4.6班) ...

  7. 2022 最新 Java 基础 面试题(一)

    2022 最新 Java 基础 面试题(一) 1.面向对象的特征有哪些方面? 3.String 是最基本的数据类型吗? 4.float f=3.4;是否正确? 5.short s1 = 1; s1 = ...

  8. 《Java程序设计》第十一周学习总结

    20175334 <Java程序设计>第十一周学习总结 教材学习内容总结 第十三章 URL类 一个URL对象通常包含最基本的三部分信息:协议.地址.资源. URL对象调用 InputStr ...

  9. 20175320 2018-2019-2 《Java程序设计》第2周学习总结

    20175320 2018-2019-2 <Java程序设计>第2周学习总结 教材学习内容总结 本周学习了教材的第二章及第三章的内容.在这两章中介绍了Java编程中的基本数据类型与数组以及 ...

最新文章

  1. emmap erlang_erlang的map基本使用
  2. android 应用状态,保持应用程序状态在Android上
  3. 中石油训练赛 - Get Strong(dfs双向搜索+二分)
  4. oracle 存储同步,Oracle数据库知识——存储过程篇
  5. bzoj 1024 [SCOI2009]生日快乐
  6. WMS仓储系统在管理中产生的盈利
  7. 双系统ubuntu 删除后重装
  8. NeatUpload IIS6.0注册问题
  9. 阿里巴巴日志处理系统
  10. 一个屌丝程序猿的人生(五十)
  11. 鼠标右键失灵java_全百科鼠标助手
  12. 大华摄像头使用外网进行访问管理
  13. 原创经典-为什么Spring中的IOC(控制反转)能够降低耦合性(解耦)?
  14. 为什么0x100是256个字节、0x400是1KB、0x800是2KB、0x1000是4KB?
  15. RSD面向对象分类的图像分割
  16. 全国快递物流查询-快递单号查询接口api
  17. CSDN文章如何导出pdf
  18. 分布式存储系统(一) - 概念
  19. 发布个人项目jar包到maven中央仓库详解
  20. Unity Android 路径下的斜杆和反斜杠

热门文章

  1. 软件教练说:性能优化与性能设计,“相亲相爱”的一对
  2. ModelArts黑科技揭秘|模型智能评估、诊断,让模型来个“体检
  3. 从前世今生聊一聊,大厂为啥亲睐时序数据库
  4. 面对10ms的延迟,这群人就是一个字“改”
  5. matlab excel 进程,Matlab使用xlsread, xlswrite函数导致excel进程无法终止的问题
  6. 450g带盖吐司配方_食谱 | 直接法北海道吐司,一起get柔软的秘密!
  7. 在虚拟机中是无法运行CarlaUE.sh文件的
  8. LaTeX常用Debug方法汇总
  9. LSTM公式详解推导
  10. WORD如何创建三线表样式?