300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Java初学者零基础分章学习后续

Java初学者零基础分章学习后续

时间:2023-11-19 13:04:58

相关推荐

Java初学者零基础分章学习后续

第5章 程序控制结构

5.1 五种控制结构

if-else

if(age>18){System.out.println(" ");} else {System.out.println(" ");}

switch

switch(c1) {case 'a' :System.out.println("A");break;case 'b' :System.out.println("B");break;case 'c' :case 'd' :case 'e' :System.out.println("C,D,E");break;default :System.out.println("你的输入有误~")

for

for(int i= 0 , j = 0; i<100; i++,j++;){System.out.println("i=" + i +"j="+ j);}

while

while 循环也有四要素只是四要素放的位置和for比一样

while(i<=10){System.out.println(" ");i++;}

do…while

循环变量初始化;

do{

​ 循环体(语句);

​ 循环变量迭代;

}while(循环条件);

do{System.out.println( );i++;}while(i<=10);

5.2 switch 注意事项

例题

对学生成绩大于 60 分的,输出"合格"。低于 60 分的,输出"不合格"。(注:输入的成绩不能大于 100), 提示 成绩/60*

提示

这里我们需要进行一个转换, 编程思路 :

如果成绩在 [60,100] , (int)(成绩/60) = 1

如果成绩在 [0,60) , (int)(成绩/60) = 0

if( score >= 0 && score <= 100) {switch ((int)(score / 60)) {case 0 :System.out.println("不合格");break;case 1 :System.out.println("合格");break;// default :// System.out.println("输入有误");}} else {System.out.println("输入的成绩在 0-100");}

switch 和 if 的比较

如果判断的具体数值不多,而且符合 byte、 short 、int、 char, enum[枚举], String 这 6 种类型。虽然两个语句都可 以使用,建议使用 swtich 语句。其他情况:对区间判断,对结果为 boolean 类型判断,使用 if,if 的使用范围更广

5.3 for 注意事项

循环条件是返回一个布尔值的表达式for(;循环判断条件;) 中的初始化和变量迭代可以写到其它地方,但是两边的分号不能省略。循环初始值可以有多条初始化语句,但要求类型一样,并且中间用逗号隔开,循环变量迭代也可以有多条变量迭代 语句,中间用逗号隔开。

###5.83 while 注意事项

循环条件是返回一个布尔值的表达式while 循环是先判断再执行语句

5.4 do…while

先执行,再判断,也就是说,一定会至少执行一次最后 有一个 分号 ;while 和 do…while 区别举例: 要账

5.5 多重循环控制

设外层循环次数为 m 次,内层为 n 次,则内层循环体实际上需要执行 m*n 次。

九九乘法表

public class Test {/*** java实现九九乘法*/public static void main(String[] args) {//九九乘法for(int i = 1;i <= 9;i++){for(int j = 1;j <= i;j++){System.out.print(j+"*"+ i +"="+i*j+" ");//此处用的print}System.out.println();}}

5.6经典的打印的金字塔

矩形

*************************for(int i = 1;i <=5;i++){System.out.println("*****");}

打印半个金字塔

* //第 1 层 有 1 个*** //第 2 层 有 2 个**** //第 3 层 有 3 个***** //第 4 层 有 4 个****** //第 5 层 有5个*public class Switch{//编写一个main方法public static void main(String[] args) {for(int i = 1;i <= 5;i++){//i表示层数//控制打印每层的*的个数for(int j = 1;j<=i;j++){System.out.print("*");}//每打印完一层的*后,就换行System.out.println("");//println本身会换行,//或者用System.out.print("\n");}}}

打印整个金字塔

* //第 1 层 有 1 个* 2 * 1 -1 有 4=(总层数-1)个空格*** //第 2 层 有 3 个* 2 * 2 -1 有 3=(总层数-2)个空格***** //第 3 层 有 5 个* 2 * 3 -1 有 2=(总层数-3)个空格******* //第 4 层 有 7 个* 2 * 4 -1 有 1=(总层数-4)个空格********* //第 5 层 有 9 个* 2 * 5 -1 有 0=(总层数-5)个空格public class Switch{//编写一个main方法public static void main(String[] args) {for(int i = 1;i <= 5;i++){//i表示层数//在输出*之前,还要输出 对应空格 = 总层数-当层数for(int k = 1;k <= 5-i;k++){System.out.print(" ");}//控制打印每层的*的个数for(int j = 1;j<=2*i-1;j++){System.out.print("*");}//每打印完一层的*后,就换行System.out.println("");//println本身会换行,//或者用System.out.print("\n");}}}

打印空心的金字塔 [最难的]

* //第 1 层 有 1 个* 当前行的第一个位置是*,最后一个位置也是** * 第 2 层 有 2 个* 当前行的第一个位置是*,最后一个位置也是** * 第 3 层 有 2 个* 当前行的第一个位置是*,最后一个位置也是*** 第 4 层 有 2 个* 当前行的第一个位置是*,最后一个位置也是********** //第 5 层 有 9 个* 全部输出*import java.util.Scanner;public class Switch{public static void main(String[] args){Scanner myScanner = new Scanner(System.in);System.out.println("输出几行星星:");int line = myScanner.nextInt();for(int i=1; i<=line;i++){for(int k=1;k<=line-i;k++){System.out.print(" ");//前边的空格数}for(int j=1;j<=2*i-1;j++){if(j==1||j==2*i-1||i==line){//每行第一个和最后一个和最后一行输出*System.out.print("*");}else{System.out.print(" ");}}System.out.println(" ");//换行}}}

自己写的空心菱形

import java.util.Scanner;public class Switch{public static void main(String[] args){Scanner myScanner = new Scanner(System.in);System.out.println("输出上半部分为几行星星:");int line = myScanner.nextInt();//上半部分for(int i=1; i<=line;i++){for(int k=1;k<=line-i;k++){System.out.print(" ");//前边的空格数}for(int j=1;j<=2*i-1;j++){if(j==1||j==2*i-1){//每行第一个和最后一个和最后一行输出*System.out.print("*");}else{System.out.print(" ");}}System.out.println(" ");//换行}//下半部分for(int a =line-1; a>=1;a--){for(int c = line-a;c>=1;c--){System.out.print(" ");}for (int b=1;b<=2*a-1;b++){if(b==1||b==2*a-1){//每行第一个和最后一个和最后一行输出*System.out.print("*");}else{System.out.print(" ");}}System.out.println(" ");//换行}}}

5.7 跳转控制语句break注意事项

(1)break 语句可以指定退出那层

(2)label1 是标签,名字由程序员指定。

(3)break 后指定到那个label 就退出到哪里。

(4)在实际的开发中,尽量不要使用标签。

(5)如果没有指定 break ,默认退出最近的循环体

随机数 random

Math.random()//public static double random()返回带正号的 double 值,该值大于等于 0.0 且小于 1.0。返回值是一个伪随机选择的数,在该范围内(近似)均匀分布。 //0.47499987617404070.412386966275462560.084959148528738430.0342776451405425450.36542069380683640.451686957568369740.67270952269476640.45505129024644540.8100140526769770.044614912679679320.12219404584351146 (int)(Match.random()*100)+1//加一是因为,前边乘以100范围是0~99,加1之后范围就到了0~100了。

字符串比较 equals

if("丁真".equals(name) && "666".equals(passwd)) {System.out.println("恭喜你,登录成功~");break;}

判断“丁真”和name这两个字符串是否相等。

5.8 跳转控制语句continue

continue 语句用于结束本次循环,继续执行下一次循环。continue 语句出现在多层嵌套的循环语句体中时,可以通过标签指明要跳过的是哪一层循环 , 这个和前面的标签的 使用的规则一样.

###5.13 跳转控制语句retuen

return 使用在方法,表示跳出所在的方法,如果 return 写在 main 方法,退出程序。

5.9本章作业

求出1-1/2+1/3-1/4…1/100的和

注意1.0/j中的数字1.0不能写成1

//自己写的public class Switch{public static void main(String[] args){double sum=0;int a=1;for(int j=1;j<=100;j++){if(j%2==0){a=-1;}else{a=1;}sum=sum+(1.0/j)*a;//这的1.0不能写成1//写成1的话这个除法1/j得到的就是0了!}System.out.println("sum="+sum);}}//老师的public class Homework08 {//编写一个main方法public static void main(String[] args) {/*求出1-1/2+1/3-1/4…..1/100的和思路分析1. 1-1/2+1/3-1/4…..1/100 = (1/1)-(1/2)+(1/3)-(1/4)...1/1002. 从上面的分析我们可以看到 (1) 一共有100数 , 分子为1 , 分母从1-100(2) 还发现 当分母为奇数时,前面是 +, 当分母是偶数时,前面是-3. 我们可以使用 for + 判断即可完成4. 把结果存放到 double sum 5. 这里有一个隐藏的陷阱,要把 公式分子 1 写出1.0 才能得到精确的小数*/double sum = 0;for(int i = 1; i <= 100; i++) {//判断是奇数还是偶数,然后做不同的处理if( i % 2 != 0) {//分母为奇数sum += 1.0/i;} else {//分母我偶数sum -= 1.0/i;}}System.out.println("sum=" + sum);}}

求1+(1+2)+(1+2+3)+(1+2+3+4)+…+(1+2+3+…+100)的结果

public class Switch{public static void main(String[] args){int sum=0;for(int i=1;i<=100;i++){for(int j=1;j<=i;j++){sum+=j;}}System.out.println("sum="+ sum);}}

第 6 章 数组、排序和查找

6.1 冒泡序列

这样一层循环只是把最大的一个数排到了最后

public class BubbleSort{public static void main(String[] args){int[] arr={24,68,-2,1,6};int max=0;for(int i=0;i<arr.length-1;i++){if(arr[i]>arr[i+1]){max=arr[i];arr[i]=arr[i+1];arr[i+1]=max;}System.out.println("第"+(i+1)+"轮");for(int j=0;j<arr.length;j++){System.out.print(arr[j]+"\t");}System.out.println();}}}

双重循环最后一下把所有的数从小排到大

public class BubbleSort{public static void main(String[] args){int[] arr={24,68,-2,1,6};int max=0;for(int i=0;i<arr.length-1;i++){for(int j=0;j<arr.length-i-1;j++)if(arr[j]>arr[j+1]){max=arr[j];arr[j]=arr[j+1];arr[j+1]=max;}System.out.println("第"+(i+1)+"轮");for(int j=0;j<arr.length;j++){System.out.print(arr[j]+"\t");}System.out.println();}}}

6.2 数组的使用

使用方式1-动态初始化

数组的定义: 数组类型 数组名[] = new 数据类型[大小]

int a[] = new int[5];

使用方式2-动态初始化

数据类型 数组名[]; 也可以 数据类型[] 数组名;

int a[]; 或者 int[] a;//声明数组,这时 a 是 null

数组名 = new 数据类型[大小];

a = new int[10]//分配内存空间,可以存放数据

使用方式3-静态初始化

数据类型 数组名[] = {元素值,元素值…}

int a[]={2,5,6,90,65,33}

注意:

数组创建后,如果没有赋值,有默认值

int 0,short 0, byte 0, long 0, float 0.0,double 0.0,char \u0000,boolean false,String null

数组属引用类型,数组型数据是对象(object)

6.3 数组赋值机制

基本数据类型赋值,这个值就是具体的数据,而且相互不影响。

​ int n1 = 2; int n2 = n1;

int a=10;int b=a;b=80;System.out.println(a);// 10System.out.println(b);// 80

数组在默认情况下是引用传递,赋的值是地址。

public class ArrayDetail{public static void main(String[] args){int[] a={1,2,3};int[] b=a;b[1]=9;for (int i=0;i<a.length;i++){System.out.print(a[i]+" ");//1 9 3}System.out.println();for(int i=0;i<b.length;i++){System.out.print(b[i]+ " ");//1 9 3}}}

这样数组a和数组b就互不干扰了

重新定义一个数组b

public class ArrayDetail{public static void main(String[] args){int[] a={1,2,3};int[] b=new int[a.length];for(int i = 0; i < a.length; i++) {b[i] = a[i];}b[1]=9;for (int i=0;i<a.length;i++){System.out.print(a[i]+" ");//1 2 3}System.out.println();for(int i=0;i<b.length;i++){System.out.print(b[i]+ " ");//1 9 3}}}

6.4 数组的增加

用户可以通过如下方法来决定是否继续添加,添加成功,是否继续?y/n

官方答案

import java.util.Scanner;public class ArrayDetail{public static void main(String[] args){Scanner myScanner=new Scanner(System.in);int[] arr={1,2,3};do{int[] arr2=new int[arr.length +1];for(int i=0;i<arr.length;i++){arr2[i]=arr[i];}System.out.println("请输入你要增加的元素:");int num=myScanner.nextInt();arr2[arr2.length - 1]=num;arr=arr2;// 让 arr 指向 arr2; arr = arr2; 那么 原来 arr 数组就被销毁System.out.println("===arr扩容后元素的情况====");for(int i=0;i<arr.length;i++){System.out.print(arr[i]+" ");}//问用户是否继续System.out.println();System.out.println("是否继续添加 y/n");char key = myScanner.next().charAt(0);if(key=='n'){//如果输入n,就结束break;}}while(true);System.out.println("你退出了增加...");}}

自己写的,在数组int[] arr={1,2,3}的基础上定义增加几个数值,然后录入,输入。(结束后内存里是两个数组,改进是一个)

import java.util.Scanner;public class ArrayDetail{public static void main(String[] args){Scanner myScanner=new Scanner(System.in);int[] arr={1,2,3};System.out.println("请输入要加入的个数:");int n = myScanner.nextInt();int[] arr2=new int[arr.length+n];for(int i=0;i<arr.length;i++){arr2[i]=arr[i];}System.out.println("请输入:");for(int i=0;i<n;i++){int m=myScanner.nextInt();arr2[arr.length+i]=m;}//1. arr=arr2; 用这个销毁原来的数组arrfor(int i=0;i<arr2.length;i++){//2. 再把这的arr2换成arr就行了System.out.print(arr2[i]+" "); //这种方法比自己的好,能减少一个数组。}}}

6.5 二维数组

使用方式 1: 动态初始化

语法: 类型[][] 数组名=new 类型【大小】【大小】

比如: int a[][]=new int[2] [3];

使用方式 2: 动态初始化

先声明:类型 数组名[][];

再定义(开辟空间) 数组名 = new 类型[大小] [大小]

赋值(有默认值,比如 int 类型的就是 0)

使用方式 3: 动态初始化-列数不确定

int[][] arr = new int[3] [];

使用方式 4: 静态初始化

定义 类型 数组名[][] = {{值 1,值 2…},{值 1,值 2…},{值 1,值 2…}}

int[] [] arr = {{1,1,1}, {8,8,9}, {100}};

6.6 杨辉三角形

规律1.第一行有 1 个元素, 第 n 行有 n 个元素2. 每一行的第一个元素和最后一个元素都是 13. 从第三行开始, 对于非第一个元素和最后一个元素的元素的值. arr[i][j]arr[i][j] = arr[i-1][j] + arr[i-1][j-1]; //必须找到这个规律public class ArrayDetail{public static void main(String[] args){int[][] yangHui = new int[12][];for(int i=0;i<yangHui.length;i++){yangHui[i]=new int[i+1];//给每个一维数组(行)开空间for(int j= 0;j<yangHui[i].length;j++){if(j==0 || j==yangHui[i].length-1){yangHui[i][j]=1;}else{yangHui[i][j] = yangHui[i-1][j]+yangHui[i-1][j-1];}}}//输出杨辉三角形for(int i=0;i<yangHui.length;i++){for(int j =0;j<yangHui[i].length;j++){System.out.print(yangHui[i][j]+"\t");}System.out.println();}}}

6.7 二维数组使用细节和注意事项

一维数组的声明方式有:

int[] x 或者 int x[]

二维数组的声明方式有:

int[] [] y 或者 int[] y[] 或者 int y[] []

二维数组实际上是由多个一维数组组成的,它的各个一维数组的长度可以相同,也可以不相同。

6.8 本章作业

下面数组定义正确的有B,D

String foo = "blue";boolean[] bar = new booolean[2];//数组bar[]默认的都是falseif(bar[0]){//bar[0]为false,所以不进入foo="green";}System.out.println(foo);// 仍然为blue

3.

public class Homework04 {//编写一个main方法public static void main(String[] args) {/*已知有个升序的数组,要求插入一个元素,该数组顺序依然是升序, 比如: [10, 12, 45, 90], 添加23 后, 数组为 [10, 12,23, 45, 90]思路 本质数组扩容 + 定位1. 我们先确定 添加数应该插入到哪个索引2. 然后扩容*///先定义原数组int[] arr = {10, 12, 45, 90};int insertNum = 111;int index = -1; //index就是要插入的位置//遍历 arr数组, 如果发现 insertNum<=arr[i], 说明 i 就是要插入的位置//使用 index 保留 index = i;//如果遍历完后,没有发现 insertNum<=arr[i], 说明 index = arr.length//即:添加到arr的最后for(int i = 0; i < arr.length; i++) {if(insertNum <= arr[i]) {index = i;break; //找到位置后,就退出}}//判断index 的值if(index == -1) {//说明没有还没有找到位置index = arr.length;}//扩容//先创建一个新的数组,大小 arr.length + 1int[] arrNew = new int[arr.length + 1];//下面老师准备将arr的元素拷贝到 arrNew ,并且要跳过 index位置/*分析:int[] arr = {10, 12, 45, 90};arrNew = { }*///i 控制arrNew的下标 , j用来控制arr数组的下标for(int i = 0, j = 0; i < arrNew.length; i++) {if( i != index ) {//说明可以把 arr的元素拷贝到 arrNewarrNew[i] = arr[j];j++;} else {//i这个位置就是要插入的数arrNew[i] = insertNum;}}//让arr 指向 arrNew , 原来的数组,就成为垃圾,被销毁arr = arrNew;System.out.println("======插入后,arr数组的元素情况======");for(int i = 0; i < arr.length; i++) {System.out.print(arr[i] + "\t");}}}

随机生成10个整数(1-100)保存到数组; 在数组中找是否有8

for(int i = 0; i < arr.length; i++) {arr[i] = (int)(Math.random() * 100) + 1;}int findNum = 8;int index = -1; //如果找到,就把下标记录到 indexfor(int i = 0; i < arr.length; i++) {if(findNum == arr[i]) {System.out.println("找到数" + findNum + " 下标=" + i);index = i;break;}}if(index == -1) {System.out.println("没有找到数" + findNum );}

第 7 章 面向对象编程(基础部分)

7.1 类与对象

类和对象的区别 类是抽象的,概念的,代表一类事物,比如人类,猫类…, 即它是数据类型.对象是具体的,实际的,代表一个具体事物, 即 是实例.类是对象的模板,对象是类的一个个体,对应一个实例

7.2对象在内存中存在形式(重要的)必须搞清楚。

7.3 如何创建对象

先声明再创建

Cat cat ; //声明对象 cat

cat = new Cat(); //创建

直接创建 Cat cat = new Cat();

public class Object{public static void main(String[] args){Cat cat1 = new Cat();cat1.name="小白";cat1.age=3;cat1.color="白色";System.out.println("第一只猫的信息"+cat1.name+" "+cat1.age+" "+cat1.color);}}class Cat{int age;String name;String color;}

7.4 类和对象的内存分配机制

Java 内存的结构分析

栈: 一般存放基本数据类型(局部变量)堆: 存放对象(Cat cat , 数组等)方法区:常量池(常量,比如字符串), 类加载信息

Java 创建对象的流程简单分析

先加载 Person 类信息(属性和方法信息, 只会加载一次)在堆中分配空间, 进行默认初始化(看规则)把地址赋给 p , p 就指向对象进行指定初始化, 比如 p.name =”jack” p.age = 10

Person a=new Person();a.age=10;a.name="小明";Person b;b=a;System.out.println(b.name); //小明b.age=200;b=null; //把b的地址null,b现在谁也不指向了System.out.println(a.age); //200System.out.println(b.age); //异常

7.5 基本数据类型的传参机制

public class MethodParameter01 {//编写一个 main 方法public static void main(String[] args) {int a = 10;int b = 20;//创建 AA 对象 名字 objAA obj = new AA();obj.swap(a, b); //调用 swapSystem.out.println("main 方法 a=" + a + " b=" + b);//a=10 b=20}}class AA {public void swap(int a,int b){System.out.println("\na 和 b 交换前的值\na=" + a + "\tb=" + b);//a=10 b=20//完成了 a 和 b 的交换int tmp = a;a = b;b = tmp;System.out.println("\na 和 b 交换后的值\na=" + a + "\tb=" + b);//a=20 b=10}}

7.6 引用数据类型的传参机制

看一个案例 MethodParameter02.java

B 类中编写一个方法 test100,可以接收一个数组,在方法中修改该数组,看看原来的数组是否变化?会变化

B 类中编写一个方法 test200,可以接收一个 Person(age,sal)对象,在方法中修改该对象属性,看看原来的对象是否变化?会变化.(注意看一个类中怎样调用另一个类。跨类中的方法A类调用B类方法:需要通过对象调用。比如 对象名.方法名(参数) )

public class Object{public static void main(String[] args){B b=new B();int arr[]={1,2,3};b.test100(arr);System.out.println("主方法中的");for(int i=0;i<arr.length;i++){System.out.print(arr[i]+"\t");}Ren mo = new Ren();mo.name="jack";mo.age=20;b.test200(mo); //注意看这一点System.out.println(mo.age);}}class Ren{String name;int age;}class B{public void test200(Ren mo){//注意看mo.age=10000;}public void test100(int arr[]){arr[0]=123;System.out.println("类中的");for(int i=0;i<arr.length;i++){System.out.print(arr[i]+"\t");}}}

7.7成员方法返回类型是引用类型应用实例

编写一个方法 copyPerson,可以复制一个 Person 对象,返回复制的对象。克隆对象, 注意要求得到新对象和原来的 对象是两个独立的对象,只是他们的属性相同。

public class MethodExercise02 {//编写一个main方法public static void main(String[] args) {Person p = new Person();p.name = "milan";p.age = 100;//创建toolsMyTools tools = new MyTools();Person p2 = tools.copyPerson(p);//到此 p 和 p2是Person对象,但是是两个独立的对象,属性相同System.out.println("p的属性 age=" + p.age + " 名字=" + p.name);System.out.println("p2的属性 age=" + p2.age + " 名字=" + p2.name);//这里老师提示: 可以同 对象比较看看是否为同一个对象System.out.println(p == p2);//false}}class Person {String name;int age;}class MyTools {//编写一个方法copyPerson,可以复制一个Person对象,返回复制的对象。克隆对象, //注意要求得到新对象和原来的对象是两个独立的对象,只是他们的属性相同////编写方法的思路//1. 方法的返回类型 Person//2. 方法的名字 copyPerson//3. 方法的形参 (Person p)//4. 方法体, 创建一个新对象,并复制属性,返回即可public Person copyPerson(Person p) {//创建一个新的对象Person p2 = new Person();p2.name = p.name; //把原来对象的名字赋给p2.namep2.age = p.age; //把原来对象的年龄赋给p2.agereturn p2;}}

7.8 递归举例

距离问题

阶乘问题

public class Recursion01 {//编写一个 main 方法public static void main(String[] args) {T t1 = new T();t1.test(4);//输出什么? n=2 n=3 n=4int res = t1.factorial(5);System.out.println("5 的阶乘 res =" + res);}}class T {//分析public void test(int n) {if (n > 2) {test(n - 1);}System.out.println("n=" + n);}}//factorial 阶乘public int factorial(int n) {if (n == 1) {return 1;} else {return factorial(n - 1) * n;}}}

(老鼠迷宫,汉诺塔,八皇后例子没有写,有空注意一下,很有意思)

7.9 方法重载

java 中允许同一个类中,多个同名方法的存在,但要求 形参列表不一致!方法名必须相同,形参列表必须相同(形参类型或个数或顺序,至少有一样不同,参数名无要求),返回类型无要求。

7.10 可变参数

java 允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法。 就可以通过可变参数实现。

基本语法:访问修饰符 返回类型 方法名(数据类型… 形参名) {

}

public int sum(int... nums) {//可以任意多个数相加int res = 0;for(int i = 0; i < nums.length; i++) {res += nums[i];}return res;}}

可变参数的实参可以为0个活任意多个。

可变参数色实参可以为数组。

可变参数的本质就是数组

可变参数可以和普通类型的参数一起放在有形参列表,但必须保证可变参数在最后

一个形参列表中只能出现一个可变参数

里边有一个publicStringshowScore(String name ,double… scores)

注意string.

public class VarParameterExercise {//编写一个 main 方法public static void main(String[] args) {HspMethod hm = new HspMethod();System.out.println(hm.showScore("milan" , 90.1, 80.0 ));System.out.println(hm.showScore("terry" , 90.1, 80.0,10,30.5,70 ));}}class HspMethod {/*有三个方法,分别实现返回姓名和两门课成绩(总分),返回姓名和三门课成绩(总分),返回姓名和五门课成绩(总分)。封装成一个可变参数的方法*///分析 1. 方法名 showScore 2. 形参(String ,double... ) 3. 返回 Stringpublic String showScore(String name ,double... scores){double totalScore = 0;for(int i = 0; i < scores.length; i++) {totalScore += scores[i];}return name + " 有 " +scores.length + "门课的成绩总分为=" + totalScore;}}

7.11 作用域

public class VarScopeDetail{//编写一个 main 方法public static void main(String[] args) {Person p1 = new Person();/*属性生命周期较长,伴随着对象的创建而创建,伴随着对象的销毁而销毁。局部变量,生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁。即在一次方法调用过程中*///p1.say();//当执行 say 方法时,say 方法的局部变量比如 name,会创建,当 say 执行完毕后//name 局部变量就销毁,但是属性(全局变量)仍然可以使用//T t1 = new T();t1.test(); //第 1 种跨类访问对象属性的方式t1.test2(p1);//第 2 种跨类访问对象属性的方式}}class T {//全局变量/属性:可以被本类使用,或其他类使用(通过对象调用)public void test() {Person p1 = new Person();System.out.println(p1.name);//jack}public void test2(Person p) {System.out.println(p.name);//jack}}class Person {//细节: 属性可以加修饰符(public protected private..)// 局部变量不能加修饰符public int age = 20;String name = "jack";public void say() {//细节 属性和局部变量可以重名,访问时遵循就近原则String name = "king";System.out.println("say() name=" + name);}public void hi() {String address = "北京";//String address = "上海";//错误,重复定义变量String name = "hsp";//可以}}

7.12 构造器

基本语法

[修饰符] 方法名(形参列表){

​ 方法体;

}

构造器的修饰符可以默认, 也可以是 public protected private构造器没有返回值方法名 和类名字必须一样参数列表 和 成员方法一样的规则构造器的调用, 由系统完成 基本介绍 构造方法又叫构造器(constructor),是类的一种特殊的方法,它的主要作用是完成对新对象的初始化。它有几个特点: 方法名和类名相同没有返回值在创建对象时,系统会自动的调用该类的构造器完成对象的初始化 注意事项

7.13 this关键字

案例

this 的注意事项和使用细节

this 关键字可以用来访问本类的属性、方法、构造器this 用于区分当前类的属性和局部变量访问成员方法的语法:this.方法名(参数列表);访问构造器语法:this(参数列表); 注意只能在构造器中使用(即只能在构造器中访问另外一个构造器, 必须放在第一 条语句)this 不能在类定义的外部使用,只能在类定义的方法中使用。

this案例

定义 Person 类,里面有 name、age 属性,并提供 compareTo 比较方法,用于判断是否和另一个人相等,提供测试类 TestPerson 用于测试, 名字和年龄完全一样,就返回 true, 否则返回 false

public class TestPerson {//编写一个 main 方法public static void main(String[] args) {Person p1 = new Person("mary", 20);Person p2 = new Person("mary", 20);System.out.println("p1 和 p2 比较的结果=" + pareTo(p2));}}/*定义 Person 类,里面有 name、age 属性,并提供 compareTo 比较方法,用于判断是否和另一个人相等,提供测试类 TestPerson 用于测试, 名字和年龄完全一样,就返回 true, 否则返回 false*/class Person {String name;int age;//构造器public Person(String name, int age) {this.name = name;this.age = age;}//compareTo 比较方法public boolean compareTo(Person p) {//名字和年龄完全一样// if(this.name.equals(p.name) && this.age == p.age) {// return true;// } else {// return false;// }return this.name.equals(p.name) && this.age == p.age;}}

7.14 课后作业

编程创建一个Cale计算类,在其中定义2个变量表示2个操作数,定义4个方法实现求和、差、乘、商(要求除数为0的话,要提示)并创建2个对象,分别测试。(注意除数中Double的大小写,有点搞不懂

public class Homework06 {//编写一个main方法public static void main(String[] args) {Cale cale = new Cale(2, 10);System.out.println("和=" + cale.sum());System.out.println("差=" + cale.minus());System.out.println("乘=" + cale.mul());Double divRes = cale.div();if(divRes != null) {System.out.println("除=" + divRes);} }}/*编程创建一个Cale计算类,在其中定义2个变量表示两个操作数,定义四个方法实现求和、差、乘、商(要求除数为0的话,要提示) 并创建两个对象,分别测试 */class Cale {double num1;double num2;public Cale(double num1, double num2) {this.num1 = num1;this.num2 = num2;}//和public double sum() {return num1 + num2;}//差public double minus() {return num1 - num2;}//乘积public double mul() {return num1 * num2;}//除法//public Double div() {//判断if(num2 == 0) {System.out.println("num2 不能为0");return null;} else {return num1 / num2;}}}

7.

public class Test {//公有类int count = 9; //属性public void count1() {//Test类的成员方法count=10;//这个count就是属性 改成 10System.out.println("count1=" + count); //10 }public void count2() {//Test类的成员方法System.out.println("count1=" + count++);} //这是Test类的main方法, 任何一个类,都可有mainpublic static void main(String args[]) {//老韩解读//1. new Test()是匿名对象, 匿名对象使用后,就不能使用//2. new Test().count1() 创建好匿名对象后, 就调用count1()new Test().count1(); Test t1= new Test();t1.count2();//9t1.count2();//10}}

10.

第8章 面向对象编程(中级部分)

8.1 IDEA 常用快捷键

删除当前行, 默认是 ctrl + Y

复制当前行,默认是crtl + D

补全代码 alt + /

添加注释和取消注释 ctrl + / 【第一次是添加注释,第二次是取消注释】

导入该行需要的类 先配置 auto import , 然后使用 alt+enter 即可

快速格式化代码 ctrl + alt + L

快速运行程序 自己定义 alt + R

生成构造器等 alt + insert [提高开发效率]

查看一个类的层级关系 ctrl + H [学习继承后,非常有用]

将光标放在一个方法上,输入 ctrl + B , 可以定位到方法 [学继承后,非常有用]

自动的分配变量名 , 通过 在后面假 .var [老师最喜欢的]

8.2 包

8.2.1 包的三大作用
区分相同名字的类当类很多时,可以很好的管理类【看Java API文档】控制访问范围
8.2.2 包的基本语法

.student;

package 关键字,表示打包。com.student 表示包名。

8.2.3 包的基本分析
8.2.4 包的命名

命名规则:

只能包含数字、字母、下划线、小圆点,但不能用数字开头,不能是关键字或者保留字。

命名规范:

一般是小写字母+小圆点

一般是com.公司名.项目名.业务板块名

8.2.5 常用的包

一个包下,包含很多的类,java中常用的包有:

java.lang.* //lang包是基本包,默认引入,不需要再引入。java.util.* //util 包,系统提供的工具包,工具类,使用 .* //网络包,网络开发java.awt* //是做java的界面开发,GUI

8.2.6 如何引入包

在java中,为了装载已编译好的包,通常可使用以下三种方法。

在要引用的类名前带上包名作为修饰符。

Animals.Cat cat = new Animals Cat();

其中,Animals是包名,Cat是包中的类,cat是类的对象。

在文件开头使用 import 引用包中的类。

import Animals.Cat;

class Check{

​ Cat cat = new Cat( );

}

同样,Animals是包名,Cat是包中的类,cat是创建的Cat类对象。

在文件前使用 import 引入整个包。

import Animals. *;

Animals整个包被引入。(在引入包时,可以用点“ . ”表示出包所在的层次结构,如经常使用的:

import java.io.*;

import java.applet.* ;

实际是引入了/java/io/或/java/applet/这样的目录结构下的所有内容。)

8.2.7 注意事项和使用细节
package 的作用是声明当前类所在的包,需要放在类的最上面,一个类中最多只有一句package。import 指令位置放在package的下面,在类定义前面,可以有多句且没有顺序要求。

8.3 访问修饰符

8.3.1基本介绍

java 提供四种访问控制修饰符号,用于控制方法和属性(成员变量)的访问权限(范围):

公开级别:用 public 修饰,对外公开受保护级别:用 protected 修饰,对子类和同一个包中的类公开默认级别:没有修饰符号,向同一个包的类公开私有级别:用 private 修饰,只有类本身可以访问,不对外公开

8.3.2 4种访问修饰符的访问范围
8.3.3使用的注意事项
修饰符可以用来修饰类中的属性,成员方法以及类只有默认的和public才能修饰类!并且遵循上述访问权限的特点。成员方法的访问规则和属性一样

8.4 面向对象编程三大特征

8.4.1基本介绍

面向对象编程有三大特征:封装、继承和多态。

8.4.2封装介绍
8.4.3封装的理解和好处
8.4.4 封装的实现步骤 (三步)

8.5 面向对象编程-继承

8.5.1 继承基本介绍和示意图

继承可以解决代码复用,让我们的编程更加靠近人类思维.当多个类存在相同的属性(变量)和方法时,可以从这些类中 抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过 extends 来 声明继承父类即可。画出继承的示意图

8.5.2 继承的基本语法
8.5.3 继承给编程带来的便利
代码的复用性提高了代码的扩展性和维护性提高了
8.5.4继承的深入讨论/细节问题
子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问, 但是私有属性和方法不能在子类直接访 问,要通过父类提供公共的方法去访问子类必须调用父类的构造器, 完成父类的初始化当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无 参构造器,则必须在子类的构造器中用 super 去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过如果希望指定去调用父类的某个构造器,则显式的调用一下 : super(参数列表)super 在使用时,必须放在构造器第一行(super 只能在构造器中使用)super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器java 所有类都是 Object 类的子类, Object 是所有类的基类父类构造器的调用不限于直接父类!将一直往上追溯直到 Object 类(顶级父类)子类最多只能继承一个父类(指直接继承),即 java 中是单继承机制。不能滥用继承,子类和父类之间必须满足 is-a 的逻辑关
8.5.5 继承的本质分析(重要)
我们看一个案例来分析当子类继承父类,创建子类对象时,内存中到底发生了什么?提示:当子类对象创建好后,建立查找的关系

package com.whwedu.extend_;/*** 讲解继承的本质*/public class ExtendsTheory {public static void main(String[] args) {Son son = new Son();//内存的布局//?-> 这时请大家注意,要按照查找关系来返回信息//(1) 首先看子类是否有该属性//(2) 如果子类有这个属性,并且可以访问,则返回信息//(3) 如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息..)//(4) 如果父类没有就按照(3)的规则,继续找上级父类,直到 Object... System.out.println(son.name);//返回就是大头儿子//System.out.println(son.age);//返回的就是 39//System.out.println(son.getAge());//返回的就是 39System.out.println(son.hobby);//返回的就是旅游}}class GrandPa {//爷类String name = "大头爷爷";String hobby = "旅游";}class Father extends GrandPa {//父类String name = "大头爸爸";private int age = 39;public int getAge() {return age;}}class Son extends Father {//子类String name = "大头儿子";}

子类创建的内存布局

8.5.6 案例分析

8.6 super 关键字

8.6.1基本介绍

super 代表父类的引用,用于访问父类的属性、方法、构造器

8.6.2基本语法
8.6.3 super 给编程带来的便利/细节
8.6.4 super 和 this 的比较

8.7 方法重写/覆盖(override)

8.7.1基本介绍
8.7.2 注意事项和使用细节

方法重写也叫方法覆盖,需要满足下面的条件

8.7.3 对方法的重写和重载做一个比较

8.8 面向对象编程-多态

8.8.1 多[多种]态[状态]基本介绍

方法或对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承基础之上的。

8.8.2 多态的具体体

方法的多态

重写和重载就体现多态

对象的多态 (核心,困难,重点)

多态的前提是:两个对象(类)存在继承关系

8.8.3 多态的向上转型和向下转型
向上转型 向上转型

package com.whwedu.poly_.detail_;public class Animal {String name = "动物";int age = 10;public void sleep(){System.out.println("睡");}public void run(){System.out.println("跑");}public void eat(){System.out.println("吃");}public void show(){System.out.println("hello,你好");}}package com.whwedu.poly_.detail_;public class Cat extends Animal {public void eat(){//方法重写System.out.println("猫吃鱼");}public void catchMouse(){//Cat 特有方法System.out.println("猫抓老鼠");}}package com.whwedu.poly_.detail_;public class Dog extends Animal {//Dog 是 Animal 的子类}package com.whwedu.poly_.detail_;public class PolyDetail {public static void main(String[] args) {//向上转型: 父类的引用指向了子类的对象//语法:父类类型引用名 = new 子类类型();Animal animal = new Cat();Object obj = new Cat();//可以吗? 可以 Object 也是 Cat 的父类//向上转型调用方法的规则如下://(1)可以调用父类中的所有成员(需遵守访问权限)//(2)但是不能调用子类的特有的成员//(#)因为在编译阶段,能调用哪些成员,是由编译类型来决定的//animal.catchMouse();错误//(4)最终运行效果看子类(运行类型)的具体实现, 即调用方法时,按照从子类(运行类型)开始查找方法//,然后调用,规则我前面我们讲的方法调用规则一致。animal.eat();//猫吃鱼.. animal.run();//跑animal.show();//hello,你好animal.sleep();//睡//我希望,可以调用 Cat 的 catchMouse 方法//多态的向下转型//(1)语法:子类类型 引用名 =(子类类型)父类引用;//问一个问题? cat 的编译类型 Cat,运行类型是 CatCat cat = (Cat) animal;cat.catchMouse();//猫抓老鼠//(2)要求父类的引用必须指向的是当前目标类型的对象Dog dog = (Dog) animal; //可以吗? 不可以System.out.println("ok~~");}}

8.8.4 属性没有重写之说!属性的值看编译类型

public class PolyDetail02 {public static void main(String[] args) {//属性没有重写之说!属性的值看编译类型Base base = new Sub();//向上转型System.out.println(base.count);// ? 看编译类型 10Sub sub = new Sub();System.out.println(sub.count);//? 20}}class Base {//父类int count = 10;//属性}class Sub extends Base {//子类int count = 20;//属性}

8.8.5 instanceOf 比较操作符

instanceOf 比较操作符,用于判断对象的运行类型是否为 XX 类型或 XX 类型的子类型。

public class PolyDetail03 {public static void main(String[] args) {BB bb = new BB();System.out.println(bb instanceof BB);// trueSystem.out.println(bb instanceof AA);// true//aa 编译类型 AA, 运行类型是 BB//BB 是 AA 子类AA aa = new BB();System.out.println(aa instanceof AA);// trueSystem.out.println(aa instanceof BB);// trueObject obj = new Object();System.out.println(obj instanceof AA);//falseString str = "hello";//System.out.println(str instanceof AA);//直接报错,字符串和AA没有任何关系System.out.println(str instanceof Object);//true}}class AA {} //父类class BB extends AA{} //子类

8.8.6 java 的动态绑定机制(非常非常重要.)

Java 重要特性: 动态绑定机制

再看一种情况:

public class DynamicBinding {public static void main(String[] args) {//a 的编译类型 A, 运行类型 BA a = new B();//向上转型System.out.println(a.sum());// 30System.out.println(a.sum1());// 20}}class A {//父类public int i = 10;//动态绑定机制:public int sum() {//父类 sum()return getI() + 10;//20 +10}public int sum1() {//父类 sum1()return i + 10;//10 + 10}public int getI() {//父类 getIreturn i;}}class B extends A {//子类public int i = 20;public int getI() {//子类 getI()return i;}}

8.8.7 多态的应用

多态数组

数组的定义类型为父类类型,里面保存的实际元素类型为子类类型

应用实例:现有一个继承结构如下:要求创建 1 个 Person 对象、2 个 Student 对象和 2 个 Teacher 对象, 统一放在数组 中,并调用每个对象 say 方法.

应用实例升级:如何调用子类特有的方法,比如 Teacher 有一个 teach , Student 有一个 study 怎么调用?

代码:

package com.whwedu.houserent.view;class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String say() {//返回名字和年龄return name + "\t" + age;}}class Student extends Person {private double score;public Student(String name, int age, double score) {super(name, age);this.score = score;}public double getScore() {return score;}public void setScore(double score) {this.score = score;}//重写父类 say@Overridepublic String say() {return "学生 " + super.say() + " score=" + score;}//特有的方法public void study() {System.out.println("学生 " + getName() + " 正在学 java...");}}class Teacher extends Person {private double salary;public Teacher(String name, int age, double salary) {super(name, age);this.salary = salary;}public double getSalary() {return salary;}public void setSalary(double salary) {this.salary = salary;}//写重写父类的 say 方法@Overridepublic String say() {return "老师 " + super.say() + " salary=" + salary;}//特有方法public void teach() {System.out.println("老师 " + getName() + " 正在讲 java 课程...");}}public class PloyArray {public static void main(String[] args) {//应用实例:现有一个继承结构如下:要求创建 1 个 Person 对象、// 2 个 Student 对象和 2 个 Teacher 对象, 统一放在数组中,并调用每个对象 say 方法Person[] persons = new Person[5];persons[0] = new Person("jack", 20);persons[1] = new Student("mary", 18, 100);persons[2] = new Student("smith", 19, 30.1);persons[3] = new Teacher("scott", 30, 20000);persons[4] = new Teacher("king", 50, 25000);for (int i = 0; i < persons.length; i++) {//老师提示: person[i] 编译类型是 Person ,运行类型是是根据实际情况有 JVM 来判断System.out.println(persons[i].say());//动态绑定机制//这里大家聪明. 使用 类型判断 + 向下转型.if (persons[i] instanceof Student) {//判断 person[i] 的运行类型是不是 StudentStudent student = (Student) persons[i];//向下转型student.study();//小伙伴也可以使用一条语句 ((Student)persons[i]).study();} else if (persons[i] instanceof Teacher) {Teacher teacher = (Teacher) persons[i];teacher.teach();} else if (persons[i] instanceof Person) {//System.out.println("你的类型有误, 请自己检查...");} else {System.out.println("你的类型有误, 请自己检查...");}}}}

多态参数

方法定义的形参类型为父类类型,实参类型允许为子类类型

package com.whwedu.houserent.view;public class Employee {private String name;private double salary;public Employee(String name, double salary) {this.name = name;this.salary = salary;}//得到年工资的方法public double getAnnual() {return 12 * salary;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getSalary() {return salary;}public void setSalary(double salary) {this.salary = salary;}}package com.whwedu.houserent.view;public class Manager extends Employee {private double bonus;public Manager(String name, double salary, double bonus) {super(name, salary);this.bonus = bonus;}public double getBonus() {return bonus;}public void setBonus(double bonus) {this.bonus = bonus;}public void manage() {System.out.println("经理 " + getName() + " is managing");}//重写获取年薪方法@Overridepublic double getAnnual() {return super.getAnnual() + bonus;}}package com.whwedu.houserent.view;public class Worker extends Employee {public Worker(String name, double salary) {super(name, salary);}public void work() {System.out.println("普通员工 " + getName() + " is working");}@Overridepublic double getAnnual() {//因为普通员工没有其它收入,则直接调用父类方法return super.getAnnual();}}package com.whwedu.houserent.view;public class PloyParameter {public static void main(String[] args) {Worker tom = new Worker("tom", 2500);Manager milan = new Manager("milan", 5000, 200000);PloyParameter ployParameter = new PloyParameter();ployParameter.showEmpAnnual(tom);ployParameter.showEmpAnnual(milan);ployParameter.testWork(tom);ployParameter.testWork(milan);}//showEmpAnnual(Employee e)//实现获取任何员工对象的年工资,并在 main 方法中调用该方法 [e.getAnnual()]public void showEmpAnnual(Employee e) {System.out.println(e.getAnnual());//动态绑定机制.}//添加一个方法,testWork,如果是普通员工,则调用 work 方法,如果是经理,则调用 manage 方法public void testWork (Employee e){if (e instanceof Worker) {((Worker) e).work();//有向下转型操作} else if (e instanceof Manager) {((Manager) e).manage();//有向下转型操作} else {System.out.println("不做处理...");}}}

8.9 Object 类详解

8.9.1 equals方法

==和 equals 的对比 [面试题]

== 是一个比较运算符

== :既可以判断基本类型,又可以判断引用类型== :如果判断基本类型,判断的是值是否相等。实例: int i = 10; doublt d = 10.0;== :如果判断引用类型,判断的是地址是否相等,即判定是不是同一对象。equals :是Object类中的方法,只能判断引用类型。(可以查看Jdk源码)默认判断的是地址是否相等,子类中往往重写该方法,用于判断内容是否相等。比如:Integer,String【看看String 和 Integer的 equals 源代码】

8.9.2 hashCode 方法

几个小结:

提高具有哈希结构的容器的效率!两个引用,如果指向的是同一个对象,则哈希值肯定是一样的!两个引用,如果指向的是不同对象,则哈希值是不一样的哈希值主要根据地址号来的!, 不能完全将哈希值等价于地址

8.9.3 toString 方法

基本介绍

默认返回:全类名+@+哈希值的十六进制,【查看 Object 的 toString 方法】

子类往往重写 toString 方法,用于返回对象的属性信息

重写 toString 方法,打印对象或拼接对象时,都会自动调用该对象的 toString 形式

当直接输出一个对象时,toString 方法会被默认的调用, 比如 System.out.println(monster); 就会默认调用 monster.toString()

8.9.4 finalize 方法
当对象被回收时,系统自动调用该对象的 finalize 方法。子类可以重写该方法,做一些释放资源的操作什么时候被回收:当某个对象没有任何引用时,则 jvm 就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来 销毁该对象,在销毁该对象前,会先调用 finalize方法垃圾回收机制的调用,是由系统来决定(即有自己的 GC 算法), 也可以通过 System.gc() 主动触发垃圾回收机制

8.10 断点调试(debug)

8.10.1 一个实际需求
8.10.2 断点调试介绍
8.10.3 断点调试的快捷键

F7(跳入) F8(跳过) shift+F8(跳出) F9(resume,执行到下一个断点)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。