关于本周的内容,Java的基本内容差不多已经学,开始学习面向对象
文章目录
1.流程控制语句
1.1选择结构语句之switch
//格式
switch(表达式或者某个变量的值){
case 值1:
语句1;
break;
case 值2:
语句2;
break;
...
default:
语句n;
break;
}
执行流程
switch接收结果
1)接收的结果与case1进行比较,如果相等,执行语句1,break结束
2)如果不相等,与case2进行比较,如果相等,执行语句2,break结束
3)如果接收的结果和case值都不相等,则执行default中的语句n,break结束
**来看一个问题**
switch后面跟的值可以有哪些类型?
可以跟基本数据类型的byte,short,int,char类型
jdk5以后可以跟枚举类型enmu
jdk7以后可以跟String字符串
**switch语句的注意事项**
1):switch中的case后只能跟**常量**,**不能是变量**
2)在switch语句中,不要忘了break,否则可能会出现**case穿透现象**
3)关于switch语句的结束条件:
①要么遇见break
②要么执行的程序末尾
4):default语句可以在switch语句中的任何位置,不影响语句的执行流程
①如果default在语句中,不要省略break
②如果default在语句末,则可以省略break
2.循环语句
2.1循环语句之for循环
/*
看个需求
需要在控制台打印10句"我爱Java"
原始方法:输出10句话
System.out.println("我爱Java");
System.out.println("我爱Java");
System.out.println("我爱Java");
System.out.println("我爱Java");
System.out.println("我爱Java");
System.out.println("我爱Java");
System.out.println("我爱Java");
System.out.println("我爱Java");
System.out.println("我爱Java");
System.out.println("我爱Java");
这样的代码阅读性差,且代码冗余度高
并且,如果需要输入更多的语句,我们也不可能一句一句的去输出
所以,由此我们引入循环
for循环的格式
for(初始化语句;条件表达式;控制体语句或者步长语句){
循环体语句;
}
*/
for(int i = 1; i <+ 10 ; i++){
System.out.println("我爱Java");
}
/*
执行流程:
1)初始化语句(只执行一次)
2)然后执行条件表达式,如果成立,则执行循环体语句
3)回到控制体语句或者步长语句,变量自增或者自减
4)再次执行条件表达式,如果成立,执行循环体语句,如果不成立,则循环结束
*/
循环的求和思想
/*
在控制台输入1-10并且求出1-10之间所有数据之和
1)定义一个结果变量sum,从0开始
2)用sum和当前数据相加,再赋值给结果变量sum
3)拿上一次求和结果sum与当前数据相加,再将结果赋值给结果变量sum
4)...
5)输出结果
*/
public class GetSum{
public static void main(String[] args){
//定义一个结果变量sum,从0开始
int sum = 0;
for(int i = 1; i <= 10; i++){
//输出1-10
System.out.println(i);
//用sum和当前数据相加,再赋值给结果变量sum
sum += i;
}
//输出1-10之间所有数据之和
System.out.println("1-10之间所有数据之和为" + sum);
}
}
获取水仙花数
/*
在控制台打印水仙花数
水仙花指的是三位数,而且这个三位数的每一个位上的立方相加就是
当期数据本身;
举例:153 = 1 * 1 * 1 + 5*5*5 + 3*3*3
分析:
1)三位数,确定了范围100-999之间,所以我们使用for循环
2)获取每个位上的数
3)逻辑判断,如果当前数各个位上数字立方和等于这个数,则输出
*/
public class Demo{
public static void main(String[] args){
//三位数,确定了范围100-999之间,所以我们使用for循环
for(int i = 100; i < 1000; i++){
//获取每个位上的数
int geWei = i % 10;
int shiWei = i / 10 % 10;
int baiWei = i / 100;
//加入逻辑判断
if(i == geWei*geWei*geWei+shiWei*shiWei*shiWei+baiWei*baiWei*baiWei){
//输出当前数据
System.out.println(i + "是水仙花数");
}
}
}
}
2.2循环语句之while循环
/*
while循环的格式
初始化语句;
while(条件表达式){
循环体语句;
控制体语句或者步长语句
}
执行流程:
先初始化语句,对变量赋值;
执行条件表达式,是否成立;成立,执行循环体语句,控制体语句进行变量控制
再次判断条件表达式是否成立,成立,执行循环体语句,控制体语句进行变量控制
...
当条件表达式不成立,while循环结束
注意事项:控制体语句不能忘,否则会变成死循环
*/
while循环和for循环的区别
共同点:能够描述一种循环思想,可以将重复性冗余代码进行优化,提供程序阅读性
不同点:
1)格式不同
2)场景不同
for:明确循环次数,优先使用for循环(开发中优先使用for)
while:不明确循环次数
3)是否节省内存资源
for循环结束之和,变量被释放,能节省内存
while循环结束,变量依然可以使用,相对于for循环格式来说,比较耗费内存资源
2.3循环语句之do-while循环
/*
循环语句之do-while循环实际开发中用的非常少;
和for,while循环最大的区别:
当条件不成立时,循环体至少执行一次格式
格式:
初始化语句;
do{
循环体语句;
控制体语句;
} while (条件表达式);
2.4死循环
/*
死循环的两种格式
for(;;) {
循环体语句;
}
while使用居多
while(true) {
循环体语句;
}
当满足某个条件,结束循环---关键字break
*/
死循环的应用
/*
Math.random()
需求:猜数字游戏
while(true) {
1)产生一个1~100之间的随机数
2)创建一个键盘录入对象
3)录入的数据和产生的随机数进行对比
如果大了,提示"您要猜的数据大了"
如果小了,提示"您要猜的数据小了"
如果一致,提示"恭喜您,猜对了"
结束死循环,break;
}
*/
import java.util.Scanner;
public class MathDemo{
public static void main(String[] args){
//需要产生一个随机数:java.lang.Math 里面的功能random()产生一个1-100之间的随机数
int number = (int)(Math.random() * 100 + 1);
//定义一个统计变量
int count = 0;
while(true){
//只要进一次循环,count++
count ++;
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
//提示用户输入一个整数并录入
System.out.println("请您输入要猜的数字:");
int guessNumber = sc.nextInt();
//使用guessNumber上面的随机数获取到的number进行对比
if (guessNumber > 100 || guessNumber <= 0) {
System.out.println("您输入的数据有误,请输入1~100之间的数");
} else if (guessNumber > number){
System.out.println("您猜的数大了");
} else if (guessNumber < number){
System.out.println("您猜的数小了");
} else {
System.out.println("恭喜您,第"+ count +"次猜对了");
break;
}
}
}
}
2.5for循环的嵌套
/*
在控制台打印99乘法表
*/
public class PrintMulTables{
public static void main(String[] args){
//为了保证有数据从1开始
for(int i = 1; i <= 9; i++){//外层控制行数
for(int j = 1; j <= i; j++){//内层循环控制列数,列数随着行数的变化 第一行,1列,第二行,2列....
System.out.print(j + "*" + i + "=" + (j * i) + "\t");//不换行
}
System.out.println();//换行
}
}
}
2.6break,continue和return关键字
- break:结束中断,结束循环语句也可以结束switch语句
- continue:仅仅在循环中使用,表示"结束当期循环,立即进入下一次循环"
- return:就是结束方法的,一般很少在方法中单独使用,结合有具体返回值类型的方法的使用(有具体返回值类型,必须有结果,否则报错),结束之前必须有一个结果
3.方法
3.1Java中的方法
什么是方法
就是将一个功能抽取出来,把代码单独定义在一个大括号内,形成一个单独的功能。 当我们需要这个功能的时候,就可以去调用。这样即实现了代码的复用性,也解决了代码冗余的现象。
方法就是完成特定功能的代码块
如何定义,定义格式
定义方法的格式
1)有具体返回值的方法定义
格式:
public static 返回值类型 方法名(形参类型1 参数名1,形参类型1 参数名2...) {
//业务逻辑实现:举例:完成两个数的比较,获取最大值
return 具体的结果;
}
调用方法:
1.1)单独调用,不适用于有具体返回值的方法
1.2)输出调用,不建议,直接输出,没有意义
1.3)赋值调用,推荐;可以用返回的结果值进行其他操作
接收的结果类型 变量名 = 方法名(实际参数1,实际参数2...);
2)没有具体返回值的方法定义
没有具体的结果,是直接输出在控制台上,Java提供了一个关键字void 代替返回值类型
格式:
public static void 方法名(形参类型1 参数名1, 形参类型2 参数名2, ...) {
//完成逻辑判断
System.out.println("xxx");
}
调用方法:
单独调用
方法的形参如果是基本数据类型,形参的改变不会影响实际参数
*/
//用户输入一个整数n,调用方法打印nn乘法表
class PrintMulTables{
public static void main(String[] args){
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
//提示用户输入并录入数据
System.out.println("请输入一个整数");
int num = sc.nextInt();
//调用方法
printMethod(num);
}
//定义一个打印乘法表的方法
public void printMethod(int num){
//为了保证有数据从1开始
for(int i = 1; i <= num; i++){//外层控制行数
for(int j = 1; j <= i; j++){//内层循环控制列数,列数随着行数的变化 第一行,1列,第二行,2列....
System.out.print(j + "*" + i + "=" + (j * i) + "\t");//不换行
}
System.out.println();//换行
}
}
}
3.2方法重载(overload)
方法重载:为了某个功能的扩展性,多个方法方法名可以相同(完全一样),参数列表不同,与返回值无关
参数列表不同:
1)参数个数
2)参数数据类型
3)参数顺序
public class OverLoadDemo {
public static void main(String[] args) {
//直接调用
System.out.println(getSum(10, 20 ));
System.out.println(getSum(20, 30, 40));
System.out.println(getSum(70, 80, 90, 100));
}
//定义一个求两个数据之和的方法
public static int getSum(int a, int b) {
int result = a + b;
return result;
}
//定义一个求三个数据之和的方法
public static int getSum(int a, int b, int c) {
int result = a + b + c;
return result;
}
//定义一个求四个数据之和的方法
public static int getSum(int a, int b, int c, int d) {
int result = a + b + c + d;
return result;
}
}
4.数组
4.1数组基本内容
什么是数组?
Java中数组可以看成是一个容器,一个可以储存多个类型相同元素的容器
/*
数组的定义格式有两种
1)动态初始化
自己定义数组的长度,数组的元素由系统(jvm)默认分配
数据类型[] 数组名 = new 数据类型[数组长度];
举例:
int[] arr = new int[3];
2)静态初始化
初始化时指定数组中每个元素的内容,数组的长度由系统默认分配
数据类型[] 数组名 = new 数据类型[]{元素1, 元素2, ...};
举例:
int[] arr = new int[]{1, 2, 3};
简写格式:
数据类型[] 数组名 = {元素1, 元素2,...};
int[] arr = {1, 2, 3};
数组定义时候的注意事项:不能动静结合!
int[] arr = new int[3]{1, 2, 3};//错误!!!
在数组中由一个特有的属性:length
数组名称.length:获取数组长度
数组中最大索引值: 数组名称.length - 1
所有的数组有一个特点:数组名称[角标或者索引值]:访问数组的元素 ,角标值/索引值从0开始计算
*/
int[] arr = new int[2] ; 完成了哪些事情?
1)在栈内存中 给int[] arr变量开辟栈内存空间
2)new int[2] ; 在堆内存中申请空间
3)系统对数组的内容进行默认初始化,int类型元素的默认值0
4)系统默认初始化完毕,产生一个堆内存空间地址值
5)将堆内存空间地址值赋值给栈内存变量arr
6)栈内存变量arr指向堆内存空间地址
4.2数组的应用
4.2.1.数组的遍历
/*
静态初始化一个数组,定义方法遍历输出数组的各个元素
输出格式:
[元素1, 元素2, ..., 元素n]
*/
public class Demo1{
public static void main(String[] args){
//静态初始化数组
int[] arr = {12, 23, 34, 45, 56};
//直接调用方法
traverse(arr);
}
//定义遍历数组的方法
public void traverse(int[] arr){
//首先输出"["
System.out.print("[");
//for循环进行数组的遍历
for(int i = 0; i < arr.length; i++){
//判断当前元素是不是数组最后一个元素
if(i == arr.length - 1){
System.out.println(arr[i] + "]");
}else{
System.out.print(arr[i] + ", ");
}
}
}
}
4.2.2.求数组最大值
import java.util.Scanner;
/*
键盘录入5个不同的数据,组成数组,然后获取数组中的最大值(使用方法完成,明显有返回值----int)
*/
public class HomeWork03 {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
//创建一个数组
int[] arr = new int[5];
//使用循环提示用户输入数据并将数据赋给数组元素
for (int i = 0; i < 5; i++) {
System.out.println("请输入第" + (i + 1) + "个元素");
arr[i] = sc.nextInt();
}
//调用方法
int maxNum = getMax(arr);
System.out.println("\n五个数中最大值是:" + maxNum);
}
//定义方法完成获取数组中最大值
public static int getMax(int[] arr) {
//定义结果变量
int max = arr[0];
//遍历数组
for (int i = 1; i < arr.length; i++){
if (max < arr[i]) {
max = arr[i];
}
}
return max;
}
}
4.2.3.冒泡排序算法
/*
需求:
键盘输入数组的长度,以及数组的各个元素,对数组进行冒泡排序
一般数组需要排序(数组长度-1)轮,但是有可能会提前完成排序
所以在算法中加入了判断,如果元素没有发生交换,就认为已经完成排序
*/
import java.util.Scanner;
class BubbleSort{
public static void main(String[] args){
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
//提示用户输入数组长度并记录
System.out.print("请输入数组长度:");
int length = sc.nextInt();
//动态初始化一个int类型的数组
int[] array = new int[length];
//使用for循环录入数组各个元素
for(int i = 0; i < length; i++){
System.out.print("请输入数组索引值为" + i + "的元素值:");
array[i] = sc.nextInt();
}
System.out.println("排序前的数组");
//调用方法对排序前的数组进行遍历
printArray(array);
//调用冒泡排序方法
bubbleSort(array);
}
//定义一个遍历数组的方法
//输出格式为[元素1, 元素2, 元素3, ..., 元素n]
public static void printArray(int[] arr){
//首先输出[
System.out.print("[");
//使用for循环对数组进行遍历
for(int i = 0; i < arr.length; i++){
//判断当前元素是否为数组最后一个元素
if(i == arr.length - 1){
System.out.print(arr[i] + "]");
}else{
System.out.print(arr[i] + ", ");
}
}
}
//冒泡排序算法的代码
public static void bubbleSort(int[] arr){
for(int i = 0; i < arr.length - 1; i++){
//定义一个boolean类型的变量记录元素是否发生交换
boolean isExchange = true;
for(int j = 0; j < arr.length - 1 - i; j++){
//判断相邻两个元素的大小
if(arr[j] > arr[j + 1]){
//如果发生变量交换,则将isExchange变为false
isExchange = false;
//定义一个中间变量,辅助交换
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
//如果循环中没有元素发生交换,则表示数组已经排好序,可以跳出循环
if (isExchange){
System.out.println("\n排序提前完成。");
break;
}
//每一轮排序完后对数组进行遍历输出
System.out.println("\n第" + (i + 1) + "轮排序后数组情况");
printArray(arr);
}
}
}
5.面向对象
5.1什么是面向对象
面向对象基于面向过程
首先我们先来看一下面向过程
我们来回想一下,目前我们完成一个需求的步骤:首先是搞清楚我们要做什么,然后在分析怎么做,最后我们再代码体现。一步一步去实现,而具体的每一步都需要我们去实现和操作。这些步骤相互调用和协作,完成我们的需求。
在上面的每一个具体步骤中我们都是参与者,并且需要面对具体的每一个步骤和过程,这就是面向过程最直接的体现。
那么什么是面向过程开发呢? 面向过程开发,其实就是面向着具体的每一个步骤和过程,把每一个步骤和过程完成,然后由这些功能方法相互调用,完成需求。
面向过程的代表语言:C语言
面向对象语言被设计出来的理念
不断的去创建对象,使用对象,指挥对象做事情
面向对象思想举例
面向对象基于面向过程,面向过程的代表C语言
举例:现实生活的例子
买电脑
面向过程:
1)了解电脑配置
2)自己去电脑城了解
3)砍价,还价
4)买完电脑,发现被坑
面向对象:
1)了解电脑配置–告诉懂行的朋友
2)你的朋友买回来
面向对象的思想特点
1)更符合生活中的思想行为习惯
2)让复杂的事情简单化
3)从执行者变成指挥者
面向对象的三大特征(重点!!!)
封装,继承,多态
5.2类
什么是类?
类,是能够描述现实世界事物一组属性和行为的集合;
类和事物的关系:一一对应的关系
事物:一定现实真实存在的
学生事物
属性: 姓名,身高, 年龄 等等…
行为: 学习,玩游戏…
Java中用class描述事物 成员变量 就是事物的属性 成员方法 就是事物的行为 Java中最基本单元就是类,定义类其实就是定义类的成员(成员变量和成员方法)
代码体现:
class 类名{ //类名:满足标识符的规范: 见名知意
//成员变量
//成员方法
}
/**
* 手机有品牌(brand),价格,颜色,内存等属性,
* 手机可以打电话,发短信,打游戏等行为,
* 请使用面向对象的方式描述手机并且进行定义一个PhoneTest类,在主方法中测试手机类
*/
public class Phone {
//成员变量
String brand;
double price;
String color;
String memory;
//成员方法
//打电话
public void call(String name){
System.out.println("正在给" + name + "打电话...");
}
//发短信
public void sendMessage(String name){
System.out.println("给" + name + "发送短信成功\n内容为:你好!" + name);
}
//打游戏
public void playGame(String gameName){
System.out.println("正在启动" + gameName + "\n请合理安排游戏时间");
}
//显示信息
public void showInfo(){
System.out.println("品牌\t价格\t\t颜色\t\t\t内存\n" + brand + "\t" + price + "\t" + color + "\t" + memory);
}
}
//测试类
public class PhoneTest {
public static void main(String[] args) {
Phone phone = new Phone();
phone.brand = "华为";
phone.price = 5999;
phone.color = "黑";
phone.memory = "6GB + 12GB";
phone.showInfo();
System.out.println("----------------------------");
phone.call("jack");
System.out.println("----------------------------");
phone.sendMessage("tom");
System.out.println("----------------------------");
phone.playGame("王者荣耀");
System.out.println("----------------------------");
Phone phone1 = new Phone("小米", 3999, "白", "6GB + 12GB");
phone1.showInfo();
}
}
如果手机价格,赋值的时候可以随便赋值,可能出现非法数据"负数"
通过上面的代码,思考问题,如何才能保证我们数据的安全性—>封装(关键字 权限修饰符—>private)
5.3封装
封装: 是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
好处: 隐藏实现细节,提供公共的访问方式,提高了代码的复用性,提高安全性。
封装原则:
将不需要对外提供的内容都隐藏起来。
把属性隐藏,提供公共方法对其访问。
private关键字
是一个权限修饰符。 可以修饰成员(成员变量和成员方法) 被private修饰的成员只在本类中才能访问。
private最常见的应用:
把成员变量用private修饰 提供对应的getXxx()/setXxx()方法 一个标准的案例的使用
6.面试题
6.1成员变量和局部变量的区别
- 在类中的位置不同
成员变量 类中方法外
局部变量 方法内或者方法声明上
- 在内存中的位置不同
成员变量 堆内存
局部变量 栈内存
- 生命周期不同
成员变量 随着对象的存在而存在,随着对象的消失而消失
局部变量 随着方法的调用而存在,随着方法的调用完毕而消失
- 初始化值不同
成员变量 有默认的初始化值
局部变量 没有默认的初始化值,必须先定义,赋值,才能使用。
6.2方法中基本类型作为参数传递和引用类型作为参数传递的区别
- 基本类型作为形式参数,形式参数改变不影响实际参数;
- 引用类型作为形式参数,形式参数的改变直接影响实际参数;