Java教程笔记
第一章:Java概述及运算符
/*
对第一个java程序进行总结
1. java程序编写-编译-运行的过程
编写:我们将编写的java代码保存在以".java"结尾的源文件中
编译:使用javac.exe命令编译我们的java源文件。格式:javac 源文件名.java
运行:使用java.exe命令解释运行我们的字节码文件。 格式:java 类名
2.
在一个java源文件中可以声明多个class。但是,只能最多有一个类声明为public的。
而且要求声明为public的类的类名必须与源文件名相同。
3. 程序的入口是main()方法。格式是固定的。
4. 输出语句:
System.out.println():先输出数据,然后换行
System.out.print():只输出数据
5.每一行执行语句都以";"结束。
6.编译的过程:编译以后,会生成一个或多个字节码文件。字节码文件的文件名与java源文件中的类名相同。
*/
public class Hello {
public static void main(String[] args) {//public static void main(String a[]) {//arguments:参数
System.out.print("Hello World!");
System.out.println();//换行
System.out.println("Hello World!");
}
}
class Person{
}
class Animal{
}
class ReviewTest{
public static void main(String[] args){
char c1 = 'a';
char c2 = 97;//开发中非常少见
System.out.println(c2);
char c3 = 5;
char c4 = '5';
int i1 = (int)c4;
System.out.println(i1);//53
}
}
/*
运算符之一:算术运算符
-
-
-
-
- / % (前)++ (后)++ (前)-- (后)-- +
-
-
-
*/
class AriTest {
public static void main(String[] args) {
//除号:/
int num1 = 12;
int num2 = 5;
int result1 = num1 / num2;
System.out.println(result1);//2
int result2 = num1 / num2 * num2;
System.out.println(result2);//10
double result3 = num1 / num2;
System.out.println(result3);//2.0
double result4 = num1 / num2 + 0.0;//2.0
double result5 = num1 / (num2 + 0.0);//2.4
double result6 = (double)num1 / num2;//2.4
double result7 = (double)(num1 / num2);//2.0
System.out.println(result5);
System.out.println(result6);
// %:取余运算
//结果的符号与被模数的符号相同
//开发中,经常使用%来判断能否被除尽的情况。
int m1 = 12;
int n1 = 5;
System.out.println("m1 % n1 = " + m1 % n1);
int m2 = -12;
int n2 = 5;
System.out.println("m2 % n2 = " + m2 % n2);
int m3 = 12;
int n3 = -5;
System.out.println("m3 % n3 = " + m3 % n3);
int m4 = -12;
int n4 = -5;
System.out.println("m4 % n4 = " + m4 % n4);
//(前)++ :先自增1,后运算
//(后)++ :先运算,后自增1
int a1 = 10;
int b1 = ++a1;
System.out.println("a1 = " + a1 + ",b1 = " + b1);
int a2 = 10;
int b2 = a2++;
System.out.println("a2 = " + a2 + ",b2 = " + b2);
int a3 = 10;
++a3;//a3++;
int b3 = a3;
//注意点:
short s1 = 10;
//s1 = s1 + 1;//编译失败
//s1 = (short)(s1 + 1);//正确的
s1++;//自增1不会改变本身变量的数据类型
System.out.println(s1);
//问题:
byte bb1 =127;
bb1++;
System.out.println("bb1 = " + bb1);
//(前)-- :先自减1,后运算
//(后)-- :先运算,后自减1
int a4 = 10;
int b4 = a4--;//int b4 = --a4;
System.out.println("a4 = " + a4 + ",b4 = " + b4);
}
/*
运算符之三:比较运算符
== != > < >= <= instanceof
结论:
1.比较运算符的结果是boolean类型
2.区分 == 和 =
*/
class CompareTest {
public static void main(String[] args) {
int i = 10;
int j = 20;
System.out.println(i == j);//false
System.out.println(i = j);//20
boolean b1 = true;
boolean b2 = false;
System.out.println(b2 == b1);//false
System.out.println(b2 = b1);//true
}
}}
/*
运算符之四:逻辑运算符
& && | || ! ^
说明:
1.逻辑运算符操作的都是boolean类型的变量
*/
class LogicTest {
public static void main(String[] args) {
//区分& 与 &&
//相同点1:& 与 && 的运算结果相同
//相同点2:当符号左边是true时,二者都会执行符号右边的运算
//不同点:当符号左边是false时,&继续执行符号右边的运算。&&不再执行符号右边的运算。
//开发中,推荐使用&&
boolean b1 = true;
b1 = false;
int num1 = 10;
if(b1 & (num1++ > 0)){
System.out.println("我现在在北京");
}else{
System.out.println("我现在在南京");
}
System.out.println("num1 = " + num1);
boolean b2 = true;
b2 = false;
int num2 = 10;
if(b2 && (num2++ > 0)){
System.out.println("我现在在北京");
}else{
System.out.println("我现在在南京");
}
System.out.println("num2 = " + num2);
// 区分:| 与 ||
//相同点1:| 与 || 的运算结果相同
//相同点2:当符号左边是false时,二者都会执行符号右边的运算
//不同点3:当符号左边是true时,|继续执行符号右边的运算,而||不再执行符号右边的运算
//开发中,推荐使用||
boolean b3 = false;
b3 = true;
int num3 = 10;
if(b3 | (num3++ > 0)){
System.out.println("我现在在北京");
}else{
System.out.println("我现在在南京");
}
System.out.println("num3 = " + num3);
boolean b4 = false;
b4 = true;
int num4 = 10;
if(b4 || (num4++ > 0)){
System.out.println("我现在在北京");
}else{
System.out.println("我现在在南京");
}
System.out.println("num4 = " + num4);
}
}
/*
运算符之六:三元运算符
1.结构:(条件表达式)? 表达式1 : 表达式2
2. 说明
① 条件表达式的结果为boolean类型
② 根据条件表达式真或假,决定执行表达式1,还是表达式2.
如果表达式为true,则执行表达式1。
如果表达式为false,则执行表达式2。
③ 表达式1 和表达式2要求是一致的。
④ 三元运算符可以嵌套使用
凡是可以使用三元运算符的地方,都可以改写为if-else
反之,不成立。
-
如果程序既可以使用三元运算符,又可以使用if-else结构,那么优先选择三元运算符。原因:简洁、执行效率高。
*/
class SanYuanTest {
public static void main(String[] args) {//获取两个整数的较大值
int m = 12;
int n = 5;int max = (m > n)? m : n;
System.out.println(max);double num = (m > n)? 2 : 1.0;
//(m > n)? 2 : “n大”;//编译错误
//**************************
n = 12;
String maxStr = (m > n)? “m大” : ((m == n)? “m和n相等” : “n大”);
System.out.println(maxStr);//*****************************
//获取三个数的最大值
int n1 = 12;
int n2 = 30;
int n3 = -43;int max1 = (n1 > n2)? n1 : n2;
int max2 = (max1 > n3)? max1 : n3;
System.out.println(“三个数中的最大值为:” + max2);//不建议
//int max3 = (((n1 > n2)? n1 : n2) > n3)? ((n1 > n2)? n1 : n2) : n3;
System.out.println(“三个数中的最大值为:” + max3);//该写成if-else:
if(m > n){
System.out.println(m);
}else{
System.out.println(n);
}
}
}
/*
运算符之五:位运算符 (了解)
结论:
- 位运算符操作的都是整型的数据
- << :在一定范围内,每向左移1位,相当于 * 2
:在一定范围内,每向右移1位,相当于 / 2
面试题:最高效方式的计算2 * 8 ? 2 << 3 或 8 << 1
*/
class BitTest {
public static void main(String[] args) {
int i = 21;
i = -21;
System.out.println(“i << 2 :” + (i << 2));
System.out.println(“i << 3 :” + (i << 3));
System.out.println(“i << 27 :” + (i << 27));
int m = 12;
int n = 5;
System.out.println("m & n :" + (m & n));
System.out.println("m | n :" + (m | n));
System.out.println("m ^ n :" + (m ^ n));
//练习:交换两个变量的值
int num1 = 10;
int num2 = 20;
System.out.println("num1 = " + num1 + ",num2 = " + num2);
//方式一:定义临时变量的方式
//推荐的方式
int temp = num1;
num1 = num2;
num2 = temp;
//方式二:好处:不用定义临时变量
//弊端:① 相加操作可能超出存储范围 ② 有局限性:只能适用于数值类型
//num1 = num1 + num2;
//num2 = num1 - num2;
//num1 = num1 - num2;
//方式三:使用位运算符
//有局限性:只能适用于数值类型
//num1 = num1 ^ num2;
//num2 = num1 ^ num2;
//num1 = num1 ^ num2;
System.out.println("num1 = " + num1 + ",num2 = " + num2);
}
}
第二章:条件语句流程控制语句
/*
分支结构中的if-else(条件判断结构)
一、三种结构
第一种:
if(条件表达式){
执行表达式
}
第二种:二选一
if(条件表达式){
执行表达式1
}else{
执行表达式2
}
第三种:n选一
if(条件表达式){
执行表达式1
}else if(条件表达式){
执行表达式2
}else if(条件表达式){
执行表达式3
}
…
else{
执行表达式n
}
*/
class IfTest {
public static void main(String[] args) {
//举例1
int heartBeats = 79;
if(heartBeats < 60 || heartBeats > 100){
System.out.println("需要做进一步检查");
}
System.out.println("检查结束");
//举例2
int age = 23;
if(age < 18){
System.out.println("你还可以看动画片");
}else{
System.out.println("你可以看成人电影了");
}
//举例3
if(age < 0){
System.out.println("您输入的数据非法");
}else if(age < 18){
System.out.println("青少年时期");
}else if(age < 35){
System.out.println("青壮年时期");
}else if(age < 60){
System.out.println("中年时期");
}else if(age < 120){
System.out.println("老年时期");
}else{
System.out.println("你是要成仙啊~~");
}
}
}
/*
运算符之二:赋值运算符
= += -= *= /= %=
*/
class SetValueTest {
public static void main(String[] args) {
//赋值符号:=
int i1 = 10;
int j1 = 10;
int i2,j2;
//连续赋值
i2 = j2 = 10;
int i3 = 10,j3 = 20;
//*********************
int num1 = 10;
num1 += 2;//num1 = num1 + 2;
System.out.println(num1);//12
int num2 = 12;
num2 %= 5;//num2 = num2 % 5;
System.out.println(num2);
short s1 = 10;
//s1 = s1 + 2;//编译失败
s1 += 2;//结论:不会改变变量本身的数据类型
System.out.println(s1);
//开发中,如果希望变量实现+2的操作,有几种方法?(前提:int num = 10;)
//方式一:num = num + 2;
//方式二:num += 2; (推荐)
//开发中,如果希望变量实现+1的操作,有几种方法?(前提:int num = 10;)
//方式一:num = num + 1;
//方式二:num += 1;
//方式三:num++; (推荐)
//练习1
int i = 1;
i *= 0.1;
System.out.println(i);//0
i++;
System.out.println(i);//1
//练习2
int m = 2;
int n = 3;
n *= m++; //n = n * m++;
System.out.println("m=" + m);//3
System.out.println("n=" + n);//6
//练习3
int n1 = 10;
n1 += (n1++) + (++n1);//n1 = n1 + (n1++) + (++n1);
System.out.println(n1);//32
}
}
/*
练习:随意给出一个三位数的整数,打印显示它的个位数,十位数,百位数的值。
格式如下:
数字xxx的情况如下:
个位数:
十位数:
百位数:
例如:
数字153的情况如下:
个位数:3
十位数:5
百位数:1
*/
class AriExer {
public static void main(String[] args) {
int num = 187;
int bai = num / 100;
int shi = num % 100 / 10;//int shi = num / 10 % 10;
int ge = num % 10;
System.out.println("百位为:" + bai);
System.out.println("十位为:" + shi);
System.out.println("个位为:" + ge);
}
}
第三章:输入输出语句
/*
如何从键盘获取不同类型的变量:需要使用Scanner类
具体实现步骤:
1.导包:import java.util.Scanner;
2.Scanner的实例化:Scanner scan = new Scanner(System.in);
3.调用Scanner类的相关方法(next() / nextXxx()),来获取指定类型的变量
注意:
需要根据相应的方法,来输入指定类型的值。如果输入的数据类型与要求的类型不匹配时,会报异常:InputMisMatchException
导致程序终止。
*/
//1.导包:import java.util.Scanner;
import java.util.Scanner;
class ScannerTest{
public static void main(String[] args){
//2.Scanner的实例化
Scanner scan = new Scanner(System.in);
//3.调用Scanner类的相关方法
System.out.println("请输入你的姓名:");
String name = scan.next();
System.out.println(name);
System.out.println("请输入你的芳龄:");
int age = scan.nextInt();
System.out.println(age);
System.out.println("请输入你的体重:");
double weight = scan.nextDouble();
System.out.println(weight);
System.out.println("你是否相中我了呢?(true/false)");
boolean isLove = scan.nextBoolean();
System.out.println(isLove);
//对于char型的获取,Scanner没有提供相关的方法。只能获取一个字符串
System.out.println("请输入你的性别:(男/女)");
String gender = scan.next();//"男"
char genderChar = gender.charAt(0);//获取索引为0位置上的字符
System.out.println(genderChar);
}
}
/*
岳小鹏参加Java考试,他和父亲岳不群达成承诺:
如果:
成绩为100分时,奖励一辆BMW;
成绩为(80,99]时,奖励一台iphone xs max;
当成绩为[60,80]时,奖励一个 iPad;
其它时,什么奖励也没有。
请从键盘输入岳小鹏的期末成绩,并加以判断
说明:
- else 结构是可选的。
- 针对于条件表达式:
如果多个条件表达式之间是“互斥”关系(或没有交集的关系),哪个判断和执行语句声明在上面还是下面,无所谓。
如果多个条件表达式之间有交集的关系,需要根据实际情况,考虑清楚应该将哪个结构声明在上面。
如果多个条件表达式之间有包含的关系,通常情况下,需要将范围小的声明在范围大的上面。否则,范围小的就没机会执行了。
*/
import java.util.Scanner;
class IfTest {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("请输入岳小鹏期末成绩:(0-100)");
int score = scan.nextInt();
if(score == 100){
System.out.println("奖励一辆BMW");//be my wife! BMW <---> MSN
}else if(score > 80 && score <= 99){
System.out.println("奖励一台iphone xs max");
}else if(score >= 60 && score <= 80){
System.out.println("奖励一个 iPad");
}else{
System.out.println("什么奖励也没有");
}
}
}
/*
编写程序:由键盘输入三个整数分别存入变量num1、num2、num3,
对它们进行排序(使用 if-else if-else),并且从小到大输出。
说明:
-
if-else结构是可以相互嵌套的。
-
如果if-else结构中的执行语句只有一行时,对应的一对{}可以省略的。但是,不建议大家省略。
*/
import java.util.Scanner;
class IfTest2 {
public static void main(String[] args) {Scanner scanner = new Scanner(System.in);
System.out.println(“请输入第一个整数:”);
int num1 = scanner.nextInt();
System.out.println(“请输入第二个整数:”);
int num2 = scanner.nextInt();
System.out.println(“请输入第三个整数:”);
int num3 = scanner.nextInt();if(num1 >= num2){
if(num3 >= num1)
System.out.println(num2 + “,” + num1 + “,” + num3);
else if(num3 <= num2)
System.out.println(num3 + “,” + num2 + “,” + num1);
else
System.out.println(num2 + “,” + num3 + “,” + num1);
}else{
if(num3 >= num2)
System.out.println(num1 + “,” + num2 + “,” + num3);
else if(num3 <= num1)
System.out.println(num3 + “,” + num1 + “,” + num2);
else
System.out.println(num1 + “,” + num3 + “,” + num2);
}
}
}
class IfExer {
public static void main(String[] args) {
int x = 4;
int y = 1;
if (x > 2)
if (y > 2)
System.out.println(x + y);
//System.out.println(“atguigu”);
else //就近原则
System.out.println("x is " + x);
//课后练习3:测算狗的年龄
int dogAge = 6;
if(dogAge >= 0 && dogAge <= 2){
System.out.println("相当于人的年龄:" + dogAge * 10.5);
}else if( dogAge > 2){
System.out.println("相当于人的年龄:" + (2 * 10.5 + (dogAge - 2) * 4));
}else{
System.out.println("狗狗还没出生呢!");
}
//课后练习4:如何获取一个随机数:10 - 99
int value = (int)(Math.random() * 90 + 10);// [0.0,1.0) --> [0.0,90.0) --->[10.0, 100.0) -->[10,99]
System.out.println(value);
//公式:[a,b] : (int)(Math.random() * (b - a + 1) )+ a
}
}
/*
大家都知道,男大当婚,女大当嫁。那么女方家长要嫁女儿,当然要提出一定的条件:
高:180cm以上;富:财富1千万以上;帅:是。
如果这三个条件同时满足,则:“我一定要嫁给他!!!”
如果三个条件有为真的情况,则:“嫁吧,比上不足,比下有余。”
如果三个条件都不满足,则:“不嫁!”
*/
import java.util.Scanner;
class IfExer1 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("请输入你的身高:(cm)");
int height = scan.nextInt();
System.out.println("请输入你的财富:(千万)");
double wealth = scan.nextDouble();
/*
方式一:
System.out.println("请输入你是否帅:(true/false)");
boolean isHandsome = scan.nextBoolean();
if(height >= 180 && wealth >= 1 && isHandsome){
System.out.println("我一定要嫁给他!!!");
}else if(height >= 180 || wealth >= 1 || isHandsome){
System.out.println("嫁吧,比上不足,比下有余。");
}else{
System.out.println("不嫁!");
}
*/
//方式二:
System.out.println("请输入你是否帅:(是/否)");
String isHandsome = scan.next();
if(height >= 180 && wealth >= 1 && isHandsome.equals(“是”)){
System.out.println(“我一定要嫁给他!!!”);
}else if(height >= 180 || wealth >= 1 || isHandsome.equals(“是”)){
System.out.println(“嫁吧,比上不足,比下有余。”);
}else{
System.out.println(“不嫁!”);
}
}
}
/*
大家都知道,男大当婚,女大当嫁。那么女方家长要嫁女儿,当然要提出一定的条件:
高:180cm以上;富:财富1千万以上;帅:是。
如果这三个条件同时满足,则:“我一定要嫁给他!!!”
如果三个条件有为真的情况,则:“嫁吧,比上不足,比下有余。”
如果三个条件都不满足,则:“不嫁!”
*/
import java.util.Scanner;
class IfExer1 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("请输入你的身高:(cm)");
int height = scan.nextInt();
System.out.println("请输入你的财富:(千万)");
double wealth = scan.nextDouble();
/*
方式一:
System.out.println("请输入你是否帅:(true/false)");
boolean isHandsome = scan.nextBoolean();
if(height >= 180 && wealth >= 1 && isHandsome){
System.out.println("我一定要嫁给他!!!");
}else if(height >= 180 || wealth >= 1 || isHandsome){
System.out.println("嫁吧,比上不足,比下有余。");
}else{
System.out.println("不嫁!");
}
*/
//方式二:
System.out.println("请输入你是否帅:(是/否)");
String isHandsome = scan.next();
if(height >= 180 && wealth >= 1 && isHandsome.equals(“是”)){
System.out.println(“我一定要嫁给他!!!”);
}else if(height >= 180 || wealth >= 1 || isHandsome.equals(“是”)){
System.out.println(“嫁吧,比上不足,比下有余。”);
}else{
System.out.println(“不嫁!”);
}
}
}
/*
编写程序:从键盘上输入2019年的“month”和“day”,要求通过程序输出输入的日期为2019年的第几天。
2 15: 31 + 15
5 7: 31 + 28 + 31 + 30 + 7
…
说明:break在switch-case中是可选的
*/
import java.util.Scanner;
class SwitchCaseTest2 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("请输入2019年的month:");
int month = scan.nextInt();
System.out.println("请输入2019年的day:");
int day = scan.nextInt();
//定义一个变量来保存总天数
int sumDays = 0;
//方式一:冗余
/*
if(month == 1){
sumDays = day;
}else if(month == 2){
sumDays = 31 + day;
}else if(month == 3){
sumDays = 31 + 28 + day;
}else if(month == 4){
sumDays = 31 + 28 + 31 + day;
}
//...
else{//month == 12
//sumDays = ..... + day;
}
*/
//方式二:冗余
/*
switch(month){
case 1:
sumDays = day;
break;
case 2:
sumDays = 31 + day;
break;
case 3:
sumDays = 31 + 28 + day;
break;
...
}
*/
switch(month){
case 12:
sumDays += 30;
case 11:
sumDays += 31;
case 10:
sumDays += 30;
case 9:
sumDays += 31;
case 8:
sumDays += 31;
case 7:
sumDays += 30;
case 6:
sumDays += 31;
case 5:
sumDays += 30;
case 4:
sumDays += 31;
case 3:
sumDays += 28;
case 2:
sumDays += 31;
case 1:
sumDays += day;
}
System.out.println("2019年" + month + "月" + day + "日是当年的第" + sumDays + "天");
}
}
/*
从键盘分别输入年、月、日,判断这一天是当年的第几天
注:判断一年是否是闰年的标准:
1)可以被4整除,但不可被100整除
或
2)可以被400整除
说明:
- 凡是可以使用switch-case的结构,都可以转换为if-else。反之,不成立。
- 我们写分支结构时,当发现既可以使用switch-case,(同时,switch中表达式的取值情况不太多),
又可以使用if-else时,我们优先选择使用switch-case。原因:switch-case执行效率稍高。
*/
import java.util.Scanner;
class SwitchCaseExer {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("请输入year:");
int year = scan.nextInt();
System.out.println("请输入month:");
int month = scan.nextInt();
System.out.println("请输入day:");
int day = scan.nextInt();
//定义一个变量来保存总天数
int sumDays = 0;
switch(month){
case 12:
sumDays += 30;
case 11:
sumDays += 31;
case 10:
sumDays += 30;
case 9:
sumDays += 31;
case 8:
sumDays += 31;
case 7:
sumDays += 30;
case 6:
sumDays += 31;
case 5:
sumDays += 30;
case 4:
sumDays += 31;
case 3:
//sumDays += 28;
//判断year是否是闰年
if((year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0){
sumDays += 29;
}else{
sumDays += 28;
}
case 2:
sumDays += 31;
case 1:
sumDays += day;
}
System.out.println(year + "年" + month + "月" + day + "日是当年的第" + sumDays + "天");
}
}
第四章:循环
/*
For循环结构的使用
一、循环结构的4个要素
① 初始化条件
② 循环条件 —>是boolean类型
③ 循环体
④ 迭代条件
二、for循环的结构
for(①;②;④){
③
}
执行过程:① - ② - ③ - ④ - ② - ③ - ④ - … - ②
*/
class ForTest {
public static void main(String[] args) {
/*
System.out.println("Hello World!");
System.out.println("Hello World!");
System.out.println("Hello World!");
System.out.println("Hello World!");
System.out.println("Hello World!");
*/
for(int i = 1;i <= 5;i++){//i:1,2,3,4,5
System.out.println("Hello World!");
}
//i:在for循环内有效。出了for循环就失效了。
//System.out.println(i);
//练习:
int num = 1;
for(System.out.print('a');num <= 3;System.out.print('c'),num++){
System.out.print('b');
}
//输出结果:abcbcbc
System.out.println();
//例题:遍历100以内的偶数,输出所有偶数的和,输出偶数的个数
int sum = 0;//记录所有偶数的和
int count = 0;//记录偶数的个数
for(int i = 1;i <= 100;i++){
if(i % 2 == 0){
System.out.println(i);
sum += i;
count++;
}
//System.out.println("总和为:" + sum);
}
System.out.println("总和为:" + sum);
System.out.println("个数为:" + count);
}
}
/*
编写程序从1循环到150,并在每行打印一个值,
另外在每个3的倍数行上打印出“foo”,
在每个5的倍数行上打印“biz”,
在每个7的倍数行上打印输出“baz”。
*/
class ForTest1 {
public static void main(String[] args) {
for(int i = 1;i <= 150;i++){
System.out.print(i + " ");
if(i % 3 == 0){
System.out.print("foo ");
}
if(i % 5 == 0){
System.out.print("biz ");
}
if(i % 7 == 0){
System.out.print("baz ");
}
//换行
System.out.println();
}
}
}
/*
例题:对学生成绩大于60分的,输出“合格”。低于60分的,输出“不合格”。
说明:如果switch-case结构中的多个case的执行语句相同,则可以考虑进行合并。
*/
class SwitchCaseTest1 {
public static void main(String[] args) {
/*
int score = 78;
switch(score){
case 0:
case 1:
case 2:
...
case 100:
}
*/
/*
int score = 78;
if(score >= 60){
}else{
}
*/
int score = 78;
switch(score / 10){
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
System.out.println("不及格");
break;
case 6:
case 7:
case 8:
case 9:
case 10:
System.out.println("及格");
break;
}
//更优的解决方案:
switch(score / 60){
case 0:
System.out.println("不及格");
break;
case 1:
System.out.println("及格");
break;
}
}
}
第五天
class ReviewTest{
public static void main(String[] args){
int sum ;
//for(int i = 1;i <= 100;i++){
if(4 % 2 != 0){
//System.out.println(i);
sum = 1;
}else{
sum = 2;
}
//}
System.out.println(sum);
}
}
/*
题目:输入两个正整数m和n,求其最大公约数和最小公倍数。
比如:12和20的最大公约数是4,最小公倍数是60。
说明:break关键字的使用:一旦在循环中执行到break,就跳出循环
*/
import java.util.Scanner;
class ForTest{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
System.out.println("请输入第一个正整数:");
int m = scan.nextInt();
System.out.println("请输入第二个正整数:");
int n = scan.nextInt();
//获取最大公约数
//1.获取两个数中的较小值
int min = (m <= n)? m : n;
//2.遍历
for(int i = min;i >= 1 ;i--){
if(m % i == 0 && n % i == 0){
System.out.println("最大公约数为:" + i);
break;//一旦在循环中执行到break,就跳出循环
}
}
//获取最小公倍数
//1.获取两个数中的较大值
int max = (m >= n)? m : n;
//2.遍历
for(int i = max;i <= m * n;i++){
if(i % m == 0 && i % n == 0){
System.out.println("最小公倍数:" + i);
break;
}
}
}
}
/*
While 循环的使用
一、循环结构的4个要素
① 初始化条件
② 循环条件 —>是boolean类型
③ 循环体
④ 迭代条件
二、while循环的结构
①
while(②){
③;
④;
}
执行过程:① - ② - ③ - ④ - ② - ③ - ④ - … - ②
说明:
1.写while循环千万小心不要丢了迭代条件。一旦丢了,就可能导致死循环!
2.我们写程序,要避免出现死循环。
3.for循环和while循环是可以相互转换的!
区别:for循环和while循环的初始化条件部分的作用范围不同。
算法:有限性。
*/
class WhileTest{
public static void main(String[] args) {
//遍历100以内的所有偶数
int i = 1;
while(i <= 100){
if(i % 2 == 0){
System.out.println(i);
}
i++;
}
//出了while循环以后,仍可以调用。
System.out.println(i);//101
}
}
/*
do-while循环的使用
一、循环结构的4个要素
① 初始化条件
② 循环条件 —>是boolean类型
③ 循环体
④ 迭代条件
二、do-while循环结构:
①
do{
③;
④;
}while(②);
执行过程:① - ③ - ④ - ② - ③ - ④ - … - ②
说明:
1.do-while循环至少会执行一次循环体!
2.开发中,使用for和while更多一些。较少使用do-while
*/
class DoWhileTest {
public static void main(String[] args) {
//遍历100以内的偶数,并计算所有偶数的和及偶数的个数
int num = 1;
int sum = 0;//记录总和
int count = 0;//记录个数
do{
if(num % 2 == 0){
System.out.println(num);
sum += num;
count++;
}
num++;
}while(num <= 100);
System.out.println("总和为:" + sum);
System.out.println("个数为:" + count);
//*************体会do-while至少执行一次循环体***************
int number1 = 10;
while(number1 > 10){
System.out.println("hello:while");
number1--;
}
int number2 = 10;
do{
System.out.println("hello:do-while");
number2--;
}while(number2 > 10);
}
}
/*
题目:
从键盘读入个数不确定的整数,并判断读入的正数和负数的个数,输入为0时结束程序。
说明:
- 不在循环条件部分限制次数的结构:for(;😉 或 while(true)
- 结束循环有几种方式?
方式一:循环条件部分返回false
方式二:在循环体中,执行break
*/
import java.util.Scanner;
class ForWhileTest {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int positiveNumber = 0;//记录正数的个数
int negativeNumber = 0;//记录负数的个数
for(;;){//while(true){
int number = scan.nextInt();
//判断number的正负情况
if(number > 0){
positiveNumber++;
}else if(number < 0){
negativeNumber++;
}else{
//一旦执行break,跳出循环
break;
}
}
System.out.println("输入的正数个数为:" + positiveNumber);
System.out.println("输入的负数个数为:" + negativeNumber);
}
}
/*
嵌套循环的应用1:
九九乘法表
1 * 1 = 1
2 * 1 = 2 2 * 2 = 4
。。。
9 * 1 = 9 。。。 9 * 9 = 81
*/
class NineNineTable {
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) + " ");
}
System.out.println();
}
}
}
/*
嵌套循环的使用
1.嵌套循环:将一个循环结构A声明在另一个循环结构B的循环体中,就构成了嵌套循环
外层循环:循环结构B
内层循环:循环结构A
-
说明
① 内层循环结构遍历一遍,只相当于外层循环循环体执行了一次
② 假设外层循环需要执行m次,内层循环需要执行n次。此时内层循环的循环体一共执行了m * n次 -
技巧:
外层循环控制行数,内层循环控制列数
*/
class ForForTest {
public static void main(String[] args) {//****** //System.out.println("******"); for(int i = 1;i <= 6;i++){ System.out.print('*'); } System.out.println("\n"); /* ****** ****** ****** ****** */ for(int j = 1;j <= 4;j++ ){ for(int i = 1;i <= 6;i++){ System.out.print('*'); } System.out.println(); } /* i(行号) j(*的个数) * 1 1 ** 2 2 *** 3 3 **** 4 4 ***** 5 5 */ for(int i = 1;i <= 5;i++){//控制行数 for(int j = 1;j <= i;j++){//控制列数 System.out.print("*"); } System.out.println(); } /* i(行号) j(*的个数) 规律:i + j = 5 换句话说:j = 5 - i; **** 1 4 *** 2 3 ** 3 2 * 4 1 */ for(int i = 1;i <= 4;i++){ for(int j = 1;j <= 5 - i;j++){ System.out.print("*"); } System.out.println(); } /* * ** *** **** ***** **** *** ** * */ //略
/*
----*
—* *
–* * *
-* * * *
*/
//上半部分
//下半部分
}
}
/*
break和continue关键字的使用
使用范围 循环中使用的作用(不同点) 相同点
break: switch-case
循环结构中 结束当前循环 关键字后面不能声明执行语句
continue: 循环结构中 结束当次循环 关键字后面不能声明执行语句
*/
class BreakContinueTest {
public static void main(String[] args) {
for(int i = 1;i <= 10;i++){
if(i % 4 == 0){
break;//123
//continue;//123567910
//System.out.println("今晚迪丽热巴要约我!!!");
}
System.out.print(i);
}
System.out.println("\n");
//******************************
label:for(int i = 1;i <= 4;i++){
for(int j = 1;j <= 10;j++){
if(j % 4 == 0){
//break;//默认跳出包裹此关键字最近的一层循环。
//continue;
//break label;//结束指定标识的一层循环结构
continue label;//结束指定标识的一层循环结构当次循环
}
System.out.print(j);
}
System.out.println();
}
}
}
/*
100000以内的所有质数的输出。实现方式二
质数:素数,只能被1和它本身整除的自然数。–>从2开始,到这个数-1结束为止,都不能被这个数本身整除。
对PrimeNumberTest.java文件中质数输出问题的优化
*/
class PrimeNumberTest2 {
public static void main(String[] args) {
int count = 0;//记录质数的个数
//获取当前时间距离1970-01-01 00:00:00 的毫秒数
long start = System.currentTimeMillis();
label:for(int i = 2;i <= 100000;i++){//遍历100000以内的自然数
for(int j = 2;j <= Math.sqrt(i);j++){//j:被i去除
if(i % j == 0){ //i被j除尽
continue label;
}
}
//能执行到此步骤的,都是质数
count++;
}
//获取当前时间距离1970-01-01 00:00:00 的毫秒数
long end = System.currentTimeMillis();
System.out.println("质数的个数为:" + count);
System.out.println("所花费的时间为:" + (end - start));//17110 - 优化一:break:1546 - 优化二:13
}
}
/*
100以内的所有质数的输出。
质数:素数,只能被1和它本身整除的自然数。–>从2开始,到这个数-1结束为止,都不能被这个数本身整除。
最小的质数是:2
*/
class PrimeNumberTest {
public static void main(String[] args) {
boolean isFlag = true;//标识i是否被j除尽,一旦除尽,修改其值
for(int i = 2;i <= 100;i++){//遍历100以内的自然数
for(int j = 2;j < i;j++){//j:被i去除
if(i % j == 0){ //i被j除尽
isFlag = false;
}
}
//
if(isFlag == true){
System.out.println(i);
}
//重置isFlag
isFlag = true;
}
}
}
/*
100000以内的所有质数的输出。实现方式一
质数:素数,只能被1和它本身整除的自然数。–>从2开始,到这个数-1结束为止,都不能被这个数本身整除。
对PrimeNumberTest.java文件中质数输出问题的优化
*/
class PrimeNumberTest1 {
public static void main(String[] args) {
boolean isFlag = true;//标识i是否被j除尽,一旦除尽,修改其值
int count = 0;//记录质数的个数
//获取当前时间距离1970-01-01 00:00:00 的毫秒数
long start = System.currentTimeMillis();
for(int i = 2;i <= 100000;i++){//遍历100000以内的自然数
//优化二:对本身是质数的自然数是有效的。
//for(int j = 2;j < i;j++){
for(int j = 2;j <= Math.sqrt(i);j++){//j:被i去除
if(i % j == 0){ //i被j除尽
isFlag = false;
break;//优化一:只对本身非质数的自然数是有效的。
}
}
//
if(isFlag == true){
//System.out.println(i);
count++;
}
//重置isFlag
isFlag = true;
}
//获取当前时间距离1970-01-01 00:00:00 的毫秒数
long end = System.currentTimeMillis();
System.out.println("质数的个数为:" + count);
System.out.println("所花费的时间为:" + (end - start));//17110 - 优化一:break:1546 - 优化二:13
}
}
第一学期:项目
class FamilyAccount{
public static void main(String[] args){
boolean isFlag = true;
//用于记录用户的收入和支出的详情
String details = "收支\t账户金额\t收支金额\t说 明\n";
//初始金额
int balance = 10000;
while(isFlag){
System.out.println("-----------------家庭收支记账软件-----------------\n");
System.out.println(" 1 收支明细");
System.out.println(" 2 登记收入");
System.out.println(" 3 登记支出");
System.out.println(" 4 退 出\n");
System.out.print(" 请选择(1-4):");
//获取用户的选择:1-4
char selection = Utility.readMenuSelection();
switch(selection){
case '1':
//System.out.println("1.收支明细");
System.out.println("-----------------当前收支明细记录-----------------");
System.out.println(details);
System.out.println("--------------------------------------------------");
break;
case '2':
//System.out.println("2.登记收入");
System.out.print("本次收入金额:");
int addMoney = Utility.readNumber();
System.out.print("本次收入说明:");
String addInfo = Utility.readString();
//处理balance
balance += addMoney;
//处理details
details += ("收入\t" + balance + "\t\t" + addMoney + "\t\t" + addInfo + "\n");
System.out.println("---------------------登记完成---------------------\n");
break;
case '3':
//System.out.println("3.登记支出");
System.out.print("本次支出金额:");
int minusMoney = Utility.readNumber();
System.out.print("本次支出说明:");
String minusInfo = Utility.readString();
//处理balance
if(balance >= minusMoney){
balance -= minusMoney;
//处理details
details += ("支出\t" + balance + "\t\t" + minusMoney + "\t\t" + minusInfo + "\n");
}else{
System.out.println("支出超出账户额度,支付失败");
}
System.out.println("---------------------登记完成---------------------\n");
break;
case '4':
//System.out.println("4.退 出");
System.out.print("确认是否退出(Y/N):");
char isExit = Utility.readConfirmSelection();
if(isExit == 'Y'){
isFlag = false;
}
//break;
}
}
}
}
第五章:工具和异常
import java.util.Scanner;
/**
Utility工具类:
将不同的功能封装为方法,就是可以直接通过调用方法使用它的功能,而无需考虑具体的功能实现细节。
/
public class Utility {
private static Scanner scanner = new Scanner(System.in);
/*
用于界面菜单的选择。该方法读取键盘,如果用户键入’1’-’4’中的任意字符,则方法返回。返回值为用户键入字符。
/
public static char readMenuSelection() {
char c;
for (; ; ) {
String str = readKeyBoard(1);
c = str.charAt(0);
if (c != ‘1’ && c != ‘2’ && c != ‘3’ && c != ‘4’) {
System.out.print(“选择错误,请重新输入:”);
} else break;
}
return c;
}
/*
用于收入和支出金额的输入。该方法从键盘读取一个不超过4位长度的整数,并将其作为方法的返回值。
/
public static int readNumber() {
int n;
for (; ; ) {
String str = readKeyBoard(4);
try {
n = Integer.parseInt(str);
break;
} catch (NumberFormatException e) {
System.out.print(“数字输入错误,请重新输入:”);
}
}
return n;
}
/*
用于收入和支出说明的输入。该方法从键盘读取一个不超过8位长度的字符串,并将其作为方法的返回值。
*/
public static String readString() {
String str = readKeyBoard(8);
return str;
}
/**
用于确认选择的输入。该方法从键盘读取‘Y’或’N’,并将其作为方法的返回值。
*/
public static char readConfirmSelection() {
char c;
for (; ; ) {
String str = readKeyBoard(1).toUpperCase();
c = str.charAt(0);
if (c == 'Y' || c == 'N') {
break;
} else {
System.out.print("选择错误,请重新输入:");
}
}
return c;
}
private static String readKeyBoard(int limit) {
String line = “”;
while (scanner.hasNext()) {
line = scanner.nextLine();
if (line.length() < 1 || line.length() > limit) {
System.out.print(“输入长度(不大于” + limit + “)错误,请重新输入:”);
continue;
}
break;
}
return line;
}
}
package com.atguigu.exer;
public class ArrayDemo {
public static void main(String[] args) {
int[] arr = new int[] { 8, 2, 1, 0, 3 };
int[] index = new int[] { 2, 0, 3, 2, 4, 0, 1, 3, 2, 3, 3 };
String tel = “”;
for (int i = 0; i < index.length; i++) {
tel += arr[index[i]];
}
System.out.println(“联系方式:” + tel);//18…
}
}
package com.atguigu.exer;
import java.util.Scanner;
/*
-
-
从键盘读入学生成绩,找出最高分,并输出学生成绩等级。
成绩>=最高分-10 等级为’A’
成绩>=最高分-20 等级为’B’
成绩>=最高分-30 等级为’C’
其余 等级为’D’提示:先读入学生人数,根据人数创建int数组,存放学生成绩。
-
*/
public class ArrayDemo1 {
public static void main(String[] args) {
//1.使用Scanner,读取学生个数
Scanner scanner = new Scanner(System.in);
System.out.println(“请输入学生人数:”);
int number = scanner.nextInt();
//2.创建数组,存储学生成绩:动态初始化
int[] scores = new int[number];
//3.给数组中的元素赋值
System.out.println("请输入" + number + "个学生成绩:");
int maxScore = 0;
for(int i = 0;i < scores.length;i++){
scores[i] = scanner.nextInt();
//4.获取数组中的元素的最大值:最高分
if(maxScore < scores[i]){
maxScore = scores[i];
}
}
// for(int i = 0;i < scores.length;i++){
// if(maxScore < scores[i]){
// maxScore = scores[i];
// }
// }
//5.根据每个学生成绩与最高分的差值,得到每个学生的等级,并输出等级和成绩
char level;
for(int i = 0;i < scores.length;i++){
if(maxScore - scores[i] <= 10){
level = 'A';
}else if(maxScore - scores[i] <= 20){
level = 'B';
}else if(maxScore - scores[i] <= 30){
level = 'C';
}else{
level = 'D';
}
System.out.println("student " + i +
" score is " + scores[i] + ",grade is " + level);
}
}
}
package com.atguigu.java;
/*
-
⑤ 数组元素的默认初始化值
-
> 数组元素是整型:0
-
> 数组元素是浮点型:0.0
-
> 数组元素是char型:0或'\u0000',而非'0'
-
> 数组元素是boolean型:false
-
> 数组元素是引用数据类型:null
-
⑥ 数组的内存解析
*/
public class ArrayTest1 {public static void main(String[] args) {
//5.数组元素的默认初始化值
int[] arr = new int[4];
for(int i = 0;i < arr.length;i++){
System.out.println(arr[i]);
}
System.out.println(“**********”);short[] arr1 = new short[4]; for(int i = 0;i < arr1.length;i++){ System.out.println(arr1[i]); } System.out.println("**********"); float[] arr2 = new float[5]; for(int i = 0;i < arr2.length;i++){ System.out.println(arr2[i]); } System.out.println("**********"); char[] arr3 = new char[4]; for(int i = 0;i < arr3.length;i++){ System.out.println("----" + arr3[i] + "****"); } if(arr3[0] == 0){ System.out.println("你好!"); } System.out.println("**********"); boolean[] arr4 = new boolean[5]; System.out.println(arr4[0]); System.out.println("**********"); String[] arr5 = new String[5]; System.out.println(arr5[0]); if(arr5[0] == null){ System.out.println("北京天气不错!"); }
}
}
第六章:数组
package com.atguigu.java;
/*
- 一、数组的概述
- 1.数组的理解:数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,
- 并通过编号的方式对这些数据进行统一管理。
- 2.数组相关的概念:
-
数组名
-
元素
-
角标、下标、索引
-
数组的长度:元素的个数
- 3.数组的特点:
- 1)数组是有序排列的
- 2)数组属于引用数据类型的变量。数组的元素,既可以是基本数据类型,也可以是引用数据类型
- 3)创建数组对象会在内存中开辟一整块连续的空间
- 4)数组的长度一旦确定,就不能修改。
-
- 数组的分类:
- ① 按照维数:一维数组、二维数组、。。。
- ② 按照数组元素的类型:基本数据类型元素的数组、引用数据类型元素的数组
-
- 一维数组的使用
- ① 一维数组的声明和初始化
- ② 如何调用数组的指定位置的元素
- ③ 如何获取数组的长度
- ④ 如何遍历数组
- ⑤ 数组元素的默认初始化值 :见ArrayTest1.java
- ⑥ 数组的内存解析 :见ArrayTest1.java
*/
public class ArrayTest {
public static void main(String[] args) {
//1. 一维数组的声明和初始化
int num;//声明
num = 10;//初始化
int id = 1001;//声明 + 初始化
int[] ids;//声明
//1.1 静态初始化:数组的初始化和数组元素的赋值操作同时进行
ids = new int[]{1001,1002,1003,1004};
//1.2动态初始化:数组的初始化和数组元素的赋值操作分开进行
String[] names = new String[5];
//错误的写法:
// int[] arr1 = new int[];
// int[5] arr2 = new int[5];
// int[] arr3 = new int[3]{1,2,3};
//也是正确的写法:
int[] arr4 = {1,2,3,4,5};//类型推断
//总结:数组一旦初始化完成,其长度就确定了。
//2.如何调用数组的指定位置的元素:通过角标的方式调用。
//数组的角标(或索引)从0开始的,到数组的长度-1结束。
names[0] = "王铭";
names[1] = "王赫";
names[2] = "张学良";
names[3] = "孙居龙";
names[4] = "王宏志";//charAt(0)
// names[5] = "周扬";
//3.如何获取数组的长度。
//属性:length
System.out.println(names.length);//5
System.out.println(ids.length);
//4.如何遍历数组
/*System.out.println(names[0]);
System.out.println(names[1]);
System.out.println(names[2]);
System.out.println(names[3]);
System.out.println(names[4]);*/
for(int i = 0;i < names.length;i++){
System.out.println(names[i]);
}
}
}
package com.atguigu.java;
/*
- 二维数组的使用
- 1.理解:
- 对于二维数组的理解,我们可以看成是一维数组array1又作为另一个一维数组array2的元素而存在。
- 其实,从数组底层的运行机制来看,其实没有多维数组。
-
- 二维数组的使用:
- ① 二维数组的声明和初始化
- ② 如何调用数组的指定位置的元素
- ③ 如何获取数组的长度
- ④ 如何遍历数组
- ⑤ 数组元素的默认初始化值 :见 ArrayTest3.java
- ⑥ 数组的内存解析 :见 ArrayTest3.java
*/
public class ArrayTest2 {
public static void main(String[] args) {
//1.二维数组的声明和初始化
int[] arr = new int[]{1,2,3};//一维数组
//静态初始化
int[][] arr1 = new int[][]{{1,2,3},{4,5},{6,7,8}};
//动态初始化1
String[][] arr2 = new String[3][2];
//动态初始化2
String[][] arr3 = new String[3][];
//错误的情况
// String[][] arr4 = new String[][4];
// String[4][3] arr5 = new String[][];
// int[][] arr6 = new int[4][3]{{1,2,3},{4,5},{6,7,8}};
//也是正确的写法:
int[] arr4[] = new int[][]{{1,2,3},{4,5,9,10},{6,7,8}};
int[] arr5[] = {{1,2,3},{4,5},{6,7,8}};
//2.如何调用数组的指定位置的元素
System.out.println(arr1[0][1]);//2
System.out.println(arr2[1][1]);//null
arr3[1] = new String[4];
System.out.println(arr3[1][0]);
//3.获取数组的长度
System.out.println(arr4.length);//3
System.out.println(arr4[0].length);//3
System.out.println(arr4[1].length);//4
//4.如何遍历二维数组
for(int i = 0;i < arr4.length;i++){
for(int j = 0;j < arr4[i].length;j++){
System.out.print(arr4[i][j] + " ");
}
System.out.println();
}
}
}
package com.atguigu.java;
/*
- 二维数组的使用:
- 规定:二维数组分为外层数组的元素,内层数组的元素
-
int[][] arr = new int[4][3];
-
外层元素:arr[0],arr[1]等
-
内层元素:arr[0][0],arr[1][2]等
- ⑤ 数组元素的默认初始化值
- 针对于初始化方式一:比如:int[][] arr = new int[4][3];
-
外层元素的初始化值为:地址值
-
内层元素的初始化值为:与一维数组初始化情况相同
- 针对于初始化方式二:比如:int[][] arr = new int[4][];
-
外层元素的初始化值为:null
-
内层元素的初始化值为:不能调用,否则报错。
- ⑥ 数组的内存解析
*/
public class ArrayTest3 {
public static void main(String[] args) {
int[][] arr = new int[4][3];
System.out.println(arr[0]);//[I@15db9742
System.out.println(arr[0][0]);//0
// System.out.println(arr);//[[I@6d06d69c
System.out.println("*****************");
float[][] arr1 = new float[4][3];
System.out.println(arr1[0]);//地址值
System.out.println(arr1[0][0]);//0.0
System.out.println("*****************");
String[][] arr2 = new String[4][2];
System.out.println(arr2[1]);//地址值
System.out.println(arr2[1][1]);//null
System.out.println("*****************");
double[][] arr3 = new double[4][];
System.out.println(arr3[1]);//null
// System.out.println(arr3[1][0]);//报错
}
}
第七天:package com.atguigu.exer;
public class ArrayExer1 {
public static void main(String[] args) {
int[][] arr = new int[][]{{3,5,8},{12,9},{7,0,6,4}};
int sum = 0;//记录总和
for(int i = 0;i < arr.length;i++){
for(int j = 0;j < arr[i].length;j++){
sum += arr[i][j];
}
}
System.out.println("总和为:" + sum);
}
}
package com.atguigu.exer;
/*
-
使用简单数组
(1)创建一个名为ArrayExer2的类,在main()方法中声明array1和array2两个变量,他们是int[]类型的数组。
(2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
(3)显示array1的内容。
(4)赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)。打印出array1。 -
思考:array1和array2是什么关系?array1和array2地址值相同,都指向了堆空间的唯一的一个数组实体。
-
拓展:修改题目,实现array2对array1数组的复制
*/
public class ArrayExer2 {
public static void main(String[] args) { //alt + /
int[] array1,array2;array1 = new int[]{2,3,5,7,11,13,17,19}; //显示array1的内容 for(int i = 0;i < array1.length;i++){ System.out.print(array1[i] + "\t"); } //赋值array2变量等于array1 //不能称作数组的复制。 array2 = array1; //修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2) for(int i = 0;i < array2.length;i++){ if(i % 2 == 0){ array2[i] = i; } } System.out.println(); //打印出array1 for(int i = 0;i < array1.length;i++){ System.out.print(array1[i] + "\t"); }
}
}
package com.atguigu.exer;
/*
-
使用简单数组
-
拓展:修改题目,实现array2对array1数组的复制
*/
public class ArrayExer3 {
public static void main(String[] args) { //alt + /
int[] array1,array2;array1 = new int[]{2,3,5,7,11,13,17,19}; //显示array1的内容 for(int i = 0;i < array1.length;i++){ System.out.print(array1[i] + "\t"); } //数组的复制: array2 = new int[array1.length]; for(int i = 0;i < array2.length;i++){ array2[i] = array1[i]; }
//修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)
for(int i = 0;i < array2.length;i++){
if(i % 2 == 0){
array2[i] = i;
}
}
System.out.println();
//打印出array1
for(int i = 0;i < array1.length;i++){
System.out.print(array1[i] + “\t”);
}
}
} -
package com.atguigu.exer;
/*- 使用二维数组打印一个 10 行杨辉三角。
【提示】
- 第一行有 1 个元素, 第 n 行有 n 个元素
- 每一行的第一个元素和最后一个元素都是 1
- 从第三行开始, 对于非第一个元素和最后一个元素的元素。即:
yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];
*/
public class YangHuiTest {public static void main(String[] args) { //1.声明并初始化二维数组 int[][] yangHui = new int[10][]; //2.给数组的元素赋值 for(int i = 0;i < yangHui.length;i++){ yangHui[i] = new int[i + 1]; //2.1 给首末元素赋值 yangHui[i][0] = yangHui[i][i] = 1; //2.2 给每行的非首末元素赋值 //if(i > 1){ for(int j = 1;j < yangHui[i].length - 1;j++){ yangHui[i][j] = yangHui[i-1][j-1] + yangHui[i-1][j]; } //} }
//3.遍历二维数组
for(int i = 0;i < yangHui.length;i++){
for(int j = 0;j < yangHui[i].length;j++){
System.out.print(yangHui[i][j] + " ");
}
System.out.println();
}
}
}
-
package com.atguigu.java;
/*- 算法的考查:求数值型数组中元素的最大值、最小值、平均数、总和等
- 定义一个int型的一维数组,包含10个元素,分别赋一些随机整数,
- 然后求出所有元素的最大值,最小值,和值,平均值,并输出出来。
- 要求:所有随机数都是两位数。
- [10,99]
- 公式:(int)(Math.random() * (99 - 10 + 1) + 10)
*/
public class ArrayTest1 {
public static void main(String[] args) {
int[] arr = new int[10];for(int i = 0;i < arr.length;i++){ arr[i] = (int)(Math.random() * (99 - 10 + 1) + 10); } //遍历 for(int i = 0;i < arr.length;i++){ System.out.print(arr[i] + "\t"); } System.out.println(); //求数组元素的最大值 int maxValue = arr[0]; for(int i = 1;i < arr.length;i++){ if(maxValue < arr[i]){ maxValue = arr[i]; } } System.out.println("最大值为:" + maxValue); //求数组元素的最小值 int minValue = arr[0]; for(int i = 1;i < arr.length;i++){ if(minValue > arr[i]){ minValue = arr[i]; } } System.out.println("最小值为:" + minValue); //求数组元素的总和 int sum = 0; for(int i = 0;i < arr.length;i++){ sum += arr[i]; } System.out.println("总和为:" + sum); //求数组元素的平均数 int avgValue = sum / arr.length; System.out.println("平均数为:" + avgValue);
}
}
package com.atguigu.java;
/*
-
算法的考查:数组的复制、反转、查找(线性查找、二分法查找)
-
*/
public class ArrayTest2 {public static void main(String[] args) {
String[] arr = new String[]{"JJ","DD","MM","BB","GG","AA"}; //数组的复制(区别于数组变量的赋值:arr1 = arr) String[] arr1 = new String[arr.length]; for(int i = 0;i < arr1.length;i++){ arr1[i] = arr[i]; } //数组的反转
//方法一:
// for(int i = 0;i < arr.length / 2;i++){
// String temp = arr[i];
// arr[i] = arr[arr.length - i -1];
// arr[arr.length - i -1] = temp;
// }//方法二:
// for(int i = 0,j = arr.length - 1;i < j;i++,j–){
// String temp = arr[i];
// arr[i] = arr[j];
// arr[j] = temp;
// }//遍历 for(int i = 0;i < arr.length;i++){ System.out.print(arr[i] + "\t"); } System.out.println(); //查找(或搜索) //线性查找: String dest = "BB"; dest = "CC"; boolean isFlag = true; for(int i = 0;i < arr.length;i++){ if(dest.equals(arr[i])){ System.out.println("找到了指定的元素,位置为:" + i); isFlag = false; break; } } if(isFlag){ System.out.println("很遗憾,没有找到的啦!"); } //二分法查找:(熟悉) //前提:所要查找的数组必须有序。 int[] arr2 = new int[]{-98,-34,2,34,54,66,79,105,210,333}; int dest1 = -34; dest1 = 35; int head = 0;//初始的首索引 int end = arr2.length - 1;//初始的末索引 boolean isFlag1 = true; while(head <= end){ int middle = (head + end)/2; if(dest1 == arr2[middle]){ System.out.println("找到了指定的元素,位置为:" + middle); isFlag1 = false; break; }else if(arr2[middle] > dest1){ end = middle - 1; }else{//arr2[middle] < dest1 head = middle + 1; } } if(isFlag1){ System.out.println("很遗憾,没有找到的啦!"); }
}
}
package com.atguigu.java;
/**
-
快速排序
-
通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,
-
则分别对这两部分继续进行排序,直到整个序列有序。
-
@author shkstart
-
2018-12-17
*/public class QuickSort {
private static void swap(int[] data, int i, int j) {
int temp = data[i];
data[i] = data[j];
data[j] = temp;
}private static void subSort(int[] data, int start, int end) {
if (start < end) {
int base = data[start];
int low = start;
int high = end + 1;
while (true) {
while (low < end && data[++low] - base <= 0)
;
while (high > start && data[–high] - base >= 0)
;
if (low < high) {
swap(data, low, high);
} else {
break;
}
}
swap(data, start, high);subSort(data, start, high - 1);//递归调用 subSort(data, high + 1, end); }
}
public static void quickSort(int[] data){
subSort(data,0,data.length-1);
}public static void main(String[] args) {
int[] data = { 9, -16, 30, 23, -30, -49, 25, 21, 30 };
System.out.println(“排序之前:\n” + java.util.Arrays.toString(data));
quickSort(data);
System.out.println(“排序之后:\n” + java.util.Arrays.toString(data));
}
}
package com.atguigu.java;
import java.util.Arrays;
/*
- java.util.Arrays:操作数组的工具类,里面定义了很多操作数组的方法
*/
public class ArraysTest {
public static void main(String[] args) {
//1.boolean equals(int[] a,int[] b):判断两个数组是否相等。
int[] arr1 = new int[]{1,2,3,4};
int[] arr2 = new int[]{1,3,2,4};
boolean isEquals = Arrays.equals(arr1, arr2);
System.out.println(isEquals);
//2.String toString(int[] a):输出数组信息。
System.out.println(Arrays.toString(arr1));
//3.void fill(int[] a,int val):将指定值填充到数组之中。
Arrays.fill(arr1,10);
System.out.println(Arrays.toString(arr1));
//4.void sort(int[] a):对数组进行排序。
Arrays.sort(arr2);
System.out.println(Arrays.toString(arr2));
//5.int binarySearch(int[] a,int key)
int[] arr3 = new int[]{-98,-34,2,34,54,66,79,105,210,333};
int index = Arrays.binarySearch(arr3, 210);
if(index >= 0){
System.out.println(index);
}else{
System.out.println("未找到");
}
}
}
package com.atguigu.java;
/*
- 数组的冒泡排序的实现
*/
public class BubbleSortTest {
public static void main(String[] args) {
int[] arr = new int[]{43,32,76,-98,0,64,33,-21,32,99};
//冒泡排序
for(int i = 0;i < arr.length - 1;i++){
for(int j = 0;j < arr.length - 1 - i;j++){
if(arr[j] > arr[j + 1]){
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
for(int i = 0;i < arr.length;i++){
System.out.print(arr[i] + "\t");
}
}
}
package com.atguigu.java;
/*
-
数组中的常见异常:
-
- 数组角标越界的异常:ArrayIndexOutOfBoundsExcetion
-
- 空指针异常:NullPointerException
-
*/
public class ArrayExceptionTest {
public static void main(String[] args) {//1. 数组角标越界的异常:ArrayIndexOutOfBoundsExcetion int[] arr = new int[]{1,2,3,4,5};
// for(int i = 0;i <= arr.length;i++){
// System.out.println(arr[i]);
// }
// System.out.println(arr[-2]);
// System.out.println(“hello”);
//2.2. 空指针异常:NullPointerException
//情况一:
// int[] arr1 = new int[]{1,2,3};
// arr1 = null;
// System.out.println(arr1[0]);
//情况二:
// int[][] arr2 = new int[4][];
// System.out.println(arr2[0][0]);
//情况三:
String[] arr3 = new String[]{"AA","BB","CC"};
arr3[0] = null;
System.out.println(arr3[0].toString());
}
}
第七章:面向对象
-
package com.atguigu.exer;
public class Person {
String name; int age; /** * sex:1 表明是男性 * sex:0 表明是女性 */ int sex; public void study(){ System.out.println("studying"); } public void showAge(){ System.out.println("age:" + age); } public int addAge(int i){ age += i; return age; }
}
package com.atguigu.exer;
/*- 要求:
- (1)创建Person类的对象,设置该对象的name、age和sex属性,调用study方法,
- 输出字符串“studying”,调用showAge()方法显示age值,
- 调用addAge()方法给对象的age属性值增加2岁。
- (2)创建第二个对象,执行上述操作,体会同一个类的不同对象之间的关系。
*/
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();p1.name = "Tom"; p1.age = 18; p1.sex = 1; p1.study(); p1.showAge(); int newAge = p1.addAge(2); System.out.println(p1.name + "的新年龄为:" + newAge); System.out.println(p1.age);//20 //************************* Person p2 = new Person(); p2.showAge();//0 p2.addAge(10); p2.showAge();//10 p1.showAge(); } }
-
package com.atguigu.exer;
/*-
2.利用面向对象的编程方法,设计类Circle计算圆的面积。
*/
//测试类
public class CircleTest {
public static void main(String[] args) {Circle c1 = new Circle(); c1.radius = 2.1; //对应方式一:
// double area = c1.findArea();
// System.out.println(area);//对应方式二: c1.findArea();
//错误的调用
// double area = c1.findArea(3.4);
// System.out.println(area);
}
} -
//圆
class Circle{//属性 double radius; //求圆的面积 //方式一:
// public double findArea(){
// double area = Math.PI * radius * radius;
// return area;
// }//方式二: public void findArea(){ double area = Math.PI * radius * radius; System.out.println("面积为:" + area); } //错误情况:
// public double findArea(double r){
// double area = 3.14 * r * r;
// return area;
// }
//
}
package com.atguigu.exer;
/*
- 3.1 编写程序,声明一个method方法,在方法中打印一个108 的型矩形,在main方法中调用该方法。
- 3.2 修改上一个程序,在method方法中,除打印一个108的型矩形外,再计算该矩形的面积,
- 并将其作为方法返回值。在main方法中调用该方法,接收返回的面积值并打印。
- 3.3 修改上一个程序,在method方法提供m和n两个参数,方法中打印一个mn的型矩形,
- 并计算该矩形的面积, 将其作为方法返回值。在main方法中调用该方法,接收返回的面积值并打印。
*/
public class Exer3Test {
public static void main(String[] args) {
Exer3Test test = new Exer3Test();
//3.1测试
// test.method();
//3.2测试
//方式一:
// int area = test.method();
// System.out.println(“面积为:” + area);
//方式二:
// System.out.println(test.method());
//3.3测试
int area = test.method(12, 10);
System.out.println("面积为:" + area);
}
//3.1
// public void method(){
// for(int i = 0;i < 10;i++){
// for(int j = 0;j < 8;j++){
// System.out.print("* “);
// }
// System.out.println();
// }
// }
//3.2
// public int method(){
// for(int i = 0;i < 10;i++){
// for(int j = 0;j < 8;j++){
// System.out.print(”* “);
// }
// System.out.println();
// }
//
// return 10 * 8;
// }
//3.3
public int method(int m,int n){
for(int i = 0;i < m;i++){
for(int j = 0;j < n;j++){
System.out.print(”* ");
}
System.out.println();
}
return m * n;
}
}
package com.atguigu.exer;
/*
-
- 对象数组题目:
定义类Student,包含三个属性:学号number(int),年级state(int),成绩score(int)。
创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。
问题一:打印出3年级(state值为3)的学生信息。
问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
- 对象数组题目:
提示:
- 生成随机数:Math.random(),返回值类型double;
- 四舍五入取整:Math.round(double d),返回值类型long。
*/
public class StudentTest {
public static void main(String[] args) {
// Student s1 = new Student();
// Student s1 = new Student();
// Student s1 = new Student();
// Student s1 = new Student();
// Student s1 = new Student();
// Student s1 = new Student();
//声明Student类型的数组
Student[] stus = new Student[20]; //String[] arr = new String[10];
for(int i = 0;i < stus.length;i++){
//给数组元素赋值
stus[i] = new Student();
//给Student对象的属性赋值
stus[i].number = (i + 1);
//年级:[1,6]
stus[i].state = (int)(Math.random() * (6 - 1 + 1) + 1);
//成绩:[0,100]
stus[i].score = (int)(Math.random() * (100 - 0 + 1));
}
//遍历学生数组
for(int i = 0;i <stus.length;i++){
// System.out.println(stus[i].number + “,” + stus[i].state
// + “,” + stus[i].score);
System.out.println(stus[i].info());
}
System.out.println("********************");
//问题一:打印出3年级(state值为3)的学生信息。
for(int i = 0;i <stus.length;i++){
if(stus[i].state == 3){
System.out.println(stus[i].info());
}
}
System.out.println("********************");
//问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
for(int i = 0;i < stus.length - 1;i++){
for(int j = 0;j < stus.length - 1 - i;j++){
if(stus[j].score > stus[j + 1].score){
//如果需要换序,交换的是数组的元素:Student对象!!!
Student temp = stus[j];
stus[j] = stus[j + 1];
stus[j + 1] = temp;
}
}
}
//遍历学生数组
for(int i = 0;i <stus.length;i++){
System.out.println(stus[i].info());
}
}
}
class Student{
int number;//学号
int state;//年级
int score;//成绩
//显示学生信息的方法
public String info(){
return "学号:" + number + ",年级:" + state + ",成绩:" + score;
}
}
package com.atguigu.exer;
/*
-
- 对象数组题目:
定义类Student,包含三个属性:学号number(int),年级state(int),成绩score(int)。
创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。
问题一:打印出3年级(state值为3)的学生信息。
问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
- 对象数组题目:
提示:
- 生成随机数:Math.random(),返回值类型double;
- 四舍五入取整:Math.round(double d),返回值类型long。
- 此代码是对StudentTest.java的改进:将操作数组的功能封装到方法中。
*/
public class StudentTest1 {
public static void main(String[] args) {
//声明Student类型的数组
Student1[] stus = new Student1[20];
for(int i = 0;i < stus.length;i++){
//给数组元素赋值
stus[i] = new Student1();
//给Student对象的属性赋值
stus[i].number = (i + 1);
//年级:[1,6]
stus[i].state = (int)(Math.random() * (6 - 1 + 1) + 1);
//成绩:[0,100]
stus[i].score = (int)(Math.random() * (100 - 0 + 1));
}
StudentTest1 test = new StudentTest1();
//遍历学生数组
test.print(stus);
System.out.println("********************");
//问题一:打印出3年级(state值为3)的学生信息。
test.searchState(stus, 3);
System.out.println("********************");
//问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
test.sort(stus);
//遍历学生数组
test.print(stus);
}
/**
*
* @Description 遍历Student1[]数组的操作
* @author shkstart
* @date 2019年1月15日下午5:10:19
* @param stus
*/
public void print(Student1[] stus){
for(int i = 0;i <stus.length;i++){
System.out.println(stus[i].info());
}
}
/**
*
* @Description 查找Stduent数组中指定年级的学生信息
* @author shkstart
* @date 2019年1月15日下午5:08:08
* @param stus 要查找的数组
* @param state 要找的年级
*/
public void searchState(Student1[] stus,int state){
for(int i = 0;i <stus.length;i++){
if(stus[i].state == state){
System.out.println(stus[i].info());
}
}
}
/**
*
* @Description 给Student1数组排序
* @author shkstart
* @date 2019年1月15日下午5:09:46
* @param stus
*/
public void sort(Student1[] stus){
for(int i = 0;i < stus.length - 1;i++){
for(int j = 0;j < stus.length - 1 - i;j++){
if(stus[j].score > stus[j + 1].score){
//如果需要换序,交换的是数组的元素:Student对象!!!
Student1 temp = stus[j];
stus[j] = stus[j + 1];
stus[j + 1] = temp;
}
}
}
}
}
class Student1{
int number;//学号
int state;//年级
int score;//成绩
//显示学生信息的方法
public String info(){
return "学号:" + number + ",年级:" + state + ",成绩:" + score;
}
}
package com.atguigu.java;
/*
- 一、Java面向对象学习的三条主线:(第4-6章)
- 1.Java类及类的成员:属性、方法、构造器;代码块、内部类
- 2.面向对象的三大特征:封装性、继承性、多态性、(抽象性)
- 3.其它关键字:this、super、static、final、abstract、interface、package、import等
- “大处着眼,小处着手”
- 二、“人把大象装进冰箱”
- 1.面向过程:强调的是功能行为,以函数为最小单位,考虑怎么做。
- ① 把冰箱门打开
- ② 抬起大象,塞进冰箱
- ② 把冰箱门关闭
- 2.面向对象:强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。
- 人{
-
打开(冰箱){
-
冰箱.开开();
-
}
-
抬起(大象){
-
大象.进入(冰箱);
-
}
-
关闭(冰箱){
-
冰箱.闭合();
-
}
- }
- 冰箱{
-
开开(){}
-
闭合(){}
- }
- 大象{
-
进入(冰箱){
-
}
- }
- 三、面向对象的两个要素:
- 类:对一类事物的描述,是抽象的、概念上的定义
- 对象:是实际存在的该类事物的每个个体,因而也称为实例(instance)
-
面向对象程序设计的重点是类的设计
-
设计类,就是设计类的成员。
*/
public class OOPTest {
}
package com.atguigu.java;
/*
-
一、设计类,其实就是设计类的成员
-
属性 = 成员变量 = field = 域、字段
-
方法 = 成员方法 = 函数 = method
-
创建类的对象 = 类的实例化 = 实例化类
-
二、类和对象的使用(面向对象思想落地的实现):
-
1.创建类,设计类的成员
-
2.创建类的对象
-
3.通过“对象.属性”或“对象.方法”调用对象的结构
-
三、如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的属性。(非static的)
-
意味着:如果我们修改一个对象的属性a,则不影响另外一个对象属性a的值。
-
四、对象的内存解析
*/
//测试类
public class PersonTest {
public static void main(String[] args) {
//2. 创建Person类的对象
Person p1 = new Person();
//Scanner scanner = new Scanner(System.in);//调用对象的结构:属性、方法 //调用属性:“对象.属性” p1.name = "Tom"; p1.isMale = true; System.out.println(p1.name); //调用方法:“对象.方法” p1.eat(); p1.sleep(); p1.talk("Chinese"); //******************************* Person p2 = new Person(); System.out.println(p2.name);//null System.out.println(p2.isMale); //******************************* //将p1变量保存的对象地址值赋给p3,导致p1和p3指向了堆空间中的同一个对象实体。 Person p3 = p1; System.out.println(p3.name);//Tom p3.age = 10; System.out.println(p1.age);//10
}
}
//1.创建类,设计类的成员
class Person{
//属性
String name;
int age = 1;
boolean isMale;
//方法
public void eat(){
System.out.println("人可以吃饭");
}
public void sleep(){
System.out.println("人可以睡觉");
}
public void talk(String language){
System.out.println("人可以说话,使用的是:" + language);
}
}
package com.atguigu.java;
/*
- 类中属性的使用
- 属性(成员变量) vs 局部变量
- 1.相同点:
-
1.1 定义变量的格式:数据类型 变量名 = 变量值
-
1.2 先声明,后使用
-
1.3 变量都有其对应的作用域
- 2.不同点:
-
2.1 在类中声明的位置的不同
-
属性:直接定义在类的一对{}内
-
局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量
-
2.2 关于权限修饰符的不同
-
属性:可以在声明属性时,指明其权限,使用权限修饰符。
-
常用的权限修饰符:private、public、缺省、protected --->封装性
-
目前,大家声明属性时,都使用缺省就可以了。
-
局部变量:不可以使用权限修饰符。
-
2.3 默认初始化值的情况:
-
属性:类的属性,根据其类型,都有默认初始化值。
-
整型(byte、short、int、long):0
-
浮点型(float、double):0.0
-
字符型(char):0 (或'\u0000')
-
布尔型(boolean):false
-
引用数据类型(类、数组、接口):null
-
局部变量:没有默认初始化值。
-
意味着,我们在调用局部变量之前,一定要显式赋值。
-
特别地:形参在调用时,我们赋值即可。
-
2.4 在内存中加载的位置:
-
属性:加载到堆空间中 (非static)
-
局部变量:加载到栈空间
*/
public class UserTest {
public static void main(String[] args) {
User u1 = new User();
System.out.println(u1.name);
System.out.println(u1.age);
System.out.println(u1.isMale);
u1.talk("韩语");
u1.eat();
}
}
class User{
//属性(或成员变量)
String name;
public int age;
boolean isMale;
public void talk(String language){//language:形参,也是局部变量
System.out.println("我们使用" + language + "进行交流");
}
public void eat(){
String food = "烙饼";//局部变量
System.out.println("北方人喜欢吃:" + food);
}
}
package com.atguigu.java;
/*
- 类中方法的声明和使用
- 方法:描述类应该具有的功能。
- 比如:Math类:sqrt()\random() …
-
Scanner类:nextXxx() ...
-
Arrays类:sort() \ binarySearch() \ toString() \ equals() \ ...
- 1.举例:
- public void eat(){}
- public void sleep(int hour){}
- public String getName(){}
- public String getNation(String nation){}
-
- 方法的声明:权限修饰符 返回值类型 方法名(形参列表){
-
方法体
-
}
- 注意:static、final、abstract 来修饰的方法,后面再讲。
-
- 说明:
-
3.1 关于权限修饰符:默认方法的权限修饰符先都使用public
-
Java规定的4种权限修饰符:private、public、缺省、protected -->封装性再细说
-
3.2 返回值类型: 有返回值 vs 没有返回值
-
3.2.1 如果方法有返回值,则必须在方法声明时,指定返回值的类型。同时,方法中,需要使用
-
return关键字来返回指定类型的变量或常量:“return 数据”。
-
如果方法没有返回值,则方法声明时,使用void来表示。通常,没有返回值的方法中,就不需要
-
使用return.但是,如果使用的话,只能“return;”表示结束此方法的意思。
-
3.2.2 我们定义方法该不该有返回值?
-
① 题目要求
-
② 凭经验:具体问题具体分析
-
3.3 方法名:属于标识符,遵循标识符的规则和规范,“见名知意”
-
3.4 形参列表: 方法可以声明0个,1个,或多个形参。
-
3.4.1 格式:数据类型1 形参1,数据类型2 形参2,...
-
3.4.2 我们定义方法时,该不该定义形参?
-
① 题目要求
-
② 凭经验:具体问题具体分析
-
3.5 方法体:方法功能的体现。
- 4.return关键字的使用:
-
1.使用范围:使用在方法体中
-
2.作用:① 结束方法
-
② 针对于有返回值类型的方法,使用"return 数据"方法返回所要的数据。
-
3.注意点:return关键字后面不可以声明执行语句。
-
- 方法的使用中,可以调用当前类的属性或方法
-
特殊的:方法A中又调用了方法A:递归方法。
-
方法中,不可以定义方法。
*/
public class CustomerTest {
public static void main(String[] args) {
Customer cust1 = new Customer();
cust1.eat();
//测试形参是否需要设置的问题
// int[] arr = new int[]{3,4,5,2,5};
// cust1.sort();
cust1.sleep(8);
}
}
//客户类
class Customer{
//属性
String name;
int age;
boolean isMale;
//方法
public void eat(){
System.out.println("客户吃饭");
return;
//return后不可以声明表达式
// System.out.println(“hello”);
}
public void sleep(int hour){
System.out.println("休息了" + hour + "个小时");
eat();
// sleep(10);
}
public String getName(){
if(age > 18){
return name;
}else{
return "Tom";
}
}
public String getNation(String nation){
String info = "我的国籍是:" + nation;
return info;
}
//体会形参是否需要设置的问题
// public void sort(int[] arr){
//
// }
// public void sort(){
// int[] arr = new int[]{3,4,5,2,5,63,2,5};
// //。。。。
// }
public void info(){
//错误的
// public void swim(){
//
// }
}
}
第九天:
package com.atguigu.java;
public class ArrayUtilTest {
public static void main(String[] args) {
ArrayUtil util = new ArrayUtil();
int[] arr = new int[]{32,34,32,5,3,54,654,-98,0,-53,5};
int max = util.getMax(arr);
System.out.println("最大值为:" + max);
System.out.println("排序前:");
util.print(arr);
util.sort(arr);
System.out.println(“排序后:”);
util.print(arr);
// System.out.println(“查找:”);
// int index = util.getIndex(arr, -5);
// if(index >= 0){
// System.out.println(“找到了,索引地址为:” + index);
// }else{
// System.out.println(“未找到”);
// }
// util.reverse(arr);
}
}
package com.atguigu.java;
/*
- 自定义数组的工具类
*/
public class ArrayUtil {
// 求数组的最大值
public int getMax(int[] arr) {
int maxValue = arr[0];
for (int i = 1; i < arr.length; i++) {
if (maxValue < arr[i]) {
maxValue = arr[i];
}
}
return maxValue;
}
// 求数组的最小值
public int getMin(int[] arr) {
int minValue = arr[0];
for (int i = 1; i < arr.length; i++) {
if (minValue > arr[i]) {
minValue = arr[i];
}
}
return minValue;
}
// 求数组的总和
public int getSum(int[] arr) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
// 求数组的平均值
public int getAvg(int[] arr) {
return getSum(arr) / arr.length;
}
//如下的两个同名方法构成了重载
// 反转数组
public void reverse(int[] arr) {
for (int i = 0; i < arr.length / 2; i++) {
int temp = arr[i];
arr[i] = arr[arr.length - i - 1];
arr[arr.length - i - 1] = temp;
}
}
public void reverse(String[] arr){
}
// 复制数组
public int[] copy(int[] arr) {
int[] arr1 = new int[arr.length];
for (int i = 0; i < arr1.length; i++) {
arr1[i] = arr[i];
}
return arr1;
}
// 数组排序
public void sort(int[] arr) {
// 冒泡排序
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
// int temp = arr[j];
// arr[j] = arr[j + 1];
// arr[j + 1] = temp;
//错误的:
// swap(arr[j],arr[j + 1]);
//正确的:
swap(arr,j,j + 1);
}
}
}
}
//错误的:交换数组中指定两个位置元素的值
// public void swap(int i,int j){
// int temp = i;
// i = j;
// j = temp;
// }
//正确的:交换数组中指定两个位置元素的值
public void swap(int[] arr,int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// 遍历数组
public void print(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
System.out.println();
}
// 查找指定元素
public int getIndex(int[] arr, int dest) {
// 线性查找:
for (int i = 0; i < arr.length; i++) {
if (dest == arr[i]) {
return i;
}
}
return -1;//返回一个负数,表示没有找到
}
}
package com.atguigu.java;
/*
- 一、理解“万事万物皆对象”
- 1.在Java语言范畴中,我们都将功能、结构等封装到类中,通过类的实例化,来调用具体的功能结构
-
>Scanner,String等
-
>文件:File
-
>网络资源:URL
- 2.涉及到Java语言与前端Html、后端的数据库交互时,前后端的结构在Java层面交互时,都体现为类、对象。
- 二、内存解析的说明
- 1.引用类型的变量,只可能存储两类值:null 或 地址值(含变量的类型)
- 三、匿名对象的使用
- 1.理解:我们创建的对象,没有显式的赋给一个变量名。即为匿名对象
- 2.特征:匿名对象只能调用一次。
- 3.使用:如下
*/
public class InstanceTest {
public static void main(String[] args) {
Phone p = new Phone();
// p = null;
System.out.println§;
p.sendEmail();
p.playGame();
//匿名对象
// new Phone().sendEmail();
// new Phone().playGame();
new Phone().price = 1999;
new Phone().showPrice();//0.0
//**********************************
PhoneMall mall = new PhoneMall();
// mall.show(p);
//匿名对象的使用
mall.show(new Phone());
}
}
class PhoneMall{
public void show(Phone phone){
phone.sendEmail();
phone.playGame();
}
}
class Phone{
double price;//价格
public void sendEmail(){
System.out.println("发送邮件");
}
public void playGame(){
System.out.println("玩游戏");
}
public void showPrice(){
System.out.println("手机价格为:" + price);
}
}
package com.atguigu.java1;
/*
- 可变个数形参的方法
- 1.jdk 5.0新增的内容
- 2.具体使用:
- 2.1 可变个数形参的格式:数据类型 … 变量名
- 2.2 当调用可变个数形参的方法时,传入的参数个数可以是:0个,1个,2个,。。。
- 2.3 可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载
- 2.4 可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载。换句话说,二者不能共存。
- 2.5 可变个数形参在方法的形参中,必须声明在末尾
- 2.6 可变个数形参在方法的形参中,最多只能声明一个可变形参。
*/
public class MethodArgsTest {
public static void main(String[] args) {
MethodArgsTest test = new MethodArgsTest();
test.show(12);
// test.show("hello");
// test.show("hello","world");
// test.show();
test.show(new String[]{"AA","BB","CC"});
}
public void show(int i){
}
public void show(String s){
System.out.println("show(String)");
}
public void show(String ... strs){
System.out.println("show(String ... strs)");
for(int i = 0;i < strs.length;i++){
System.out.println(strs[i]);
}
}
//不能与上一个方法同时存在
// public void show(String[] strs){
//
// }
//The variable argument type String of the method
//show must be the last parameter
// public void show(String ...strs,int i){
//
// }
}
package com.atguigu.java1;
/*
-
方法的重载(overload) loading…
-
1.定义:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
-
“两同一不同”:同一个类、相同方法名
-
参数列表不同:参数个数不同,参数类型不同
-
- 举例:
-
Arrays类中重载的sort() / binarySearch()
-
3.判断是否是重载:
-
跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系!
-
- 在通过对象调用方法时,如何确定某一个指定的方法:
-
方法名 ---> 参数列表
*/
public class OverLoadTest {
public static void main(String[] args) {OverLoadTest test = new OverLoadTest(); test.getSum(1,2);
}//如下的4个方法构成了重载
public void getSum(int i,int j){
System.out.println(“1”);
}public void getSum(double d1,double d2){
System.out.println(“2”);
}public void getSum(String s ,int i){
System.out.println(“3”);
}public void getSum(int i,String s){
System.out.println(“4”);
}//如下的3个方法不能与上述4个方法构成重载
// public int getSum(int i,int j){
// return 0;
// }
// public void getSum(int m,int n){
//
// }
// private void getSum(int i,int j){
//
// }
}
package com.atguigu.java1;
public class ArrayPrintTest {
public static void main(String[] args) {
int[] arr = new int[]{1,2,3};
System.out.println(arr);//地址值
char[] arr1 = new char[]{'a','b','c'};
System.out.println(arr1); //abc
}
}
package com.atguigu.java1;
/*
- 方法的形参的传递机制:值传递
- 1.形参:方法定义时,声明的小括号内的参数
- 实参:方法调用时,实际传递给形参的数据
- 2.值传递机制:
- 如果参数是基本数据类型,此时实参赋给形参的是实参真实存储的数据值。
- 如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值。
*/
public class ValueTransferTest1 {
public static void main(String[] args) {
int m = 10;
int n = 20;
System.out.println("m = " + m + ", n = " + n);
//交换两个变量的值的操作
// int temp = m ;
// m = n;
// n = temp;
ValueTransferTest1 test = new ValueTransferTest1();
test.swap(m, n);
System.out.println("m = " + m + ", n = " + n);
}
public void swap(int m,int n){
int temp = m ;
m = n;
n = temp;
}
}
package com.atguigu.java1;
public class ValueTransferTest2 {
public static void main(String[] args) {
Data data = new Data();
data.m = 10;
data.n = 20;
System.out.println("m = " + data.m + ", n = " + data.n);
//交换m和n的值
// int temp = data.m;
// data.m = data.n;
// data.n = temp;
ValueTransferTest2 test = new ValueTransferTest2();
test.swap(data);
System.out.println("m = " + data.m + ", n = " + data.n);
}
public void swap(Data data){
int temp = data.m;
data.m = data.n;
data.n = temp;
}
}
class Data{
int m;
int n;
}
package com.atguigu.java1;
/*
*
- 关于变量的赋值:
- 如果变量是基本数据类型,此时赋值的是变量所保存的数据值。
- 如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值。
*/
public class ValueTransferTest {
public static void main(String[] args) {
System.out.println("***********基本数据类型:****************");
int m = 10;
int n = m;
System.out.println("m = " + m + ", n = " + n);
n = 20;
System.out.println("m = " + m + ", n = " + n);
System.out.println("***********引用数据类型:****************");
Order o1 = new Order();
o1.orderId = 1001;
Order o2 = o1;//赋值以后,o1和o2的地址值相同,都指向了堆空间中同一个对象实体。
System.out.println("o1.orderId = " + o1.orderId + ",o2.orderId = " +o2.orderId);
o2.orderId = 1002;
System.out.println("o1.orderId = " + o1.orderId + ",o2.orderId = " +o2.orderId);
}
}
class Order{
int orderId;
}
package com.atguigu.java2;
/*
-
递归方法的使用(了解)
-
1.递归方法:一个方法体内调用它自身。
-
- 方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。
-
递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。
*/
public class RecursionTest {
public static void main(String[] args) {
// 例1:计算1-100之间所有自然数的和
// 方式一:
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
System.out.println(sum);
// 方式二:
RecursionTest test = new RecursionTest();
int sum1 = test.getSum(100);
System.out.println(sum1);
System.out.println("*****************");
int value = test.f(10);
System.out.println(value);
}
// 例1:计算1-n之间所有自然数的和
public int getSum(int n) {// 3
if (n == 1) {
return 1;
} else {
return n + getSum(n - 1);
}
}
// 例2:计算1-n之间所有自然数的乘积:n!
public int getSum1(int n) {
if (n == 1) {
return 1;
} else {
return n * getSum1(n - 1);
}
}
//例3:已知有一个数列:f(0) = 1,f(1) = 4,f(n+2)=2*f(n+1) + f(n),
//其中n是大于0的整数,求f(10)的值。
public int f(int n){
if(n == 0){
return 1;
}else if(n == 1){
return 4;
}else{
// return f(n + 2) - 2 * f(n + 1);
return 2*f(n - 1) + f(n - 2);
}
}
//例4:斐波那契数列
//例5:汉诺塔问题
//例6:快排
}
第十天:
package com.atguigu.java;
public class ValueTransferTest {
public static void main(String[] args) {
String s1 = "hello";
ValueTransferTest test = new ValueTransferTest();
test.change(s1);
System.out.println(s1);//hi~~
}
public void change(String s){
s = “hi~~”;
}
}
package com.atguigu.java;
public class OrderTest {
public static void main(String[] args) {
Order order = new Order();
order.orderDefault = 1;
order.orderPublic = 2;
//出了Order类之后,私有的结构就不可以调用了
// order.orderPrivate = 3;//The field Order.orderPrivate is not visible
order.methodDefault();
order.methodPublic();
//出了Order类之后,私有的结构就不可以调用了
// order.methodPrivate();//The method methodPrivate() from the type Order is not visible
}
}
package com.atguigu.java;
public class Order {
private int orderPrivate;
int orderDefault;
public int orderPublic;
private void methodPrivate(){
orderPrivate = 1;
orderDefault = 2;
orderPublic = 3;
}
void methodDefault(){
orderPrivate = 1;
orderDefault = 2;
orderPublic = 3;
}
public void methodPublic(){
orderPrivate = 1;
orderDefault = 2;
orderPublic = 3;
}
}
package com.atguigu.java;
/*
- 面向对象的特征一:封装与隐藏 3W:what? why? how?
- 一、问题的引入:
- 当我们创建一个类的对象以后,我们可以通过"对象.属性"的方式,对对象的属性进行赋值。这里,赋值操作要受到
- 属性的数据类型和存储范围的制约。除此之外,没有其他制约条件。但是,在实际问题中,我们往往需要给属性赋值
- 加入额外的限制条件。这个条件就不能在属性声明时体现,我们只能通过方法进行限制条件的添加。(比如:setLegs())
- 同时,我们需要避免用户再使用"对象.属性"的方式对属性进行赋值。则需要将属性声明为私有的(private).
- –>此时,针对于属性就体现了封装性。
- 二、封装性的体现:
- 我们将类的属性xxx私有化(private),同时,提供公共的(public)方法来获取(getXxx)和设置(setXxx)此属性的值
- 拓展:封装性的体现:① 如上 ② 不对外暴露的私有的方法 ③ 单例模式 …
- 三、封装性的体现,需要权限修饰符来配合。
- 1.Java规定的4种权限(从小到大排列):private、缺省、protected 、public
- 2.4种权限可以用来修饰类及类的内部结构:属性、方法、构造器、内部类
- 3.具体的,4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类
-
修饰类的话,只能使用:缺省、public
- 总结封装性:Java提供了4种权限修饰符来修饰类及类的内部结构,体现类及类的内部结构在被调用时的可见性的大小。
*/
public class AnimalTest {
public static void main(String[] args) {
Animal a = new Animal();
a.name = "大黄";
// a.age = 1;
// a.legs = 4;//The field Animal.legs is not visible
a.show();
// a.legs = -4;
// a.setLegs(6);
a.setLegs(-6);
// a.legs = -4;//The field Animal.legs is not visible
a.show();
System.out.println(a.name);
}
}
class Animal{
String name;
private int age;
private int legs;//腿的个数
//对属性的设置
public void setLegs(int l){
if(l >= 0 && l % 2 == 0){
legs = l;
}else{
legs = 0;
// 抛出一个异常(暂时没有讲)
}
}
//对属性的获取
public int getLegs(){
return legs;
}
public void eat(){
System.out.println(“动物进食”);
}
public void show(){
System.out.println("name = " + name + ",age = " + age + ",legs = " + legs);
}
//提供关于属性age的get和set方法
public int getAge(){
return age;
}
public void setAge(int a){
age = a;
}
}
//private class Dog{
//
//}
package com.atguigu.java1;
import com.atguigu.java.Order;
public class OrderTest {
public static void main(String[] args) {
Order order = new Order();
order.orderPublic = 2;
// 出了Order类所属的包之后,私有的结构、缺省声明的结构就不可以调用了
// order.orderDefault = 1;
// order.orderPrivate = 3;//The field Order.orderPrivate is not visible
order.methodPublic();
// 出了Order类所属的包之后,私有的结构、缺省声明的结构就不可以调用了
// order.methodDefault();
// order.methodPrivate();//The method methodPrivate() from the type Order is not visible
}
}
package com.atguigu.java1;
/*
-
JavaBean是一种Java语言写成的可重用组件。
所谓JavaBean,是指符合如下标准的Java类:
>类是公共的
>有一个无参的公共的构造器
>有属性,且有对应的get、set方法
*/
public class Customer {
private int id;
private String name;
public Customer(){
}
public void setId(int i){
id = i;
}
public int getId(){
return id;
}
public void setName(String n){
name = n;
}
public String getName(){
return name;
}
}
package com.atguigu.java1;
/*
- 总结:属性赋值的先后顺序
- ① 默认初始化
- ② 显式初始化
- ③ 构造器中初始化
- ④ 通过"对象.方法" 或 "对象.属性"的方式,赋值
- 以上操作的先后顺序:① - ② - ③ - ④
*/
public class UserTest {
public static void main(String[] args) {
User u = new User();
System.out.println(u.age);
User u1 = new User(2);
u1.setAge(3);
u1.setAge(5);
System.out.println(u1.age);
}
}
class User{
String name;
int age = 1;
public User(){
}
public User(int a){
age = a;
}
public void setAge(int a){
age = a;
}
}
package com.atguigu.java1;
/*
-
类的结构之三:构造器(或构造方法、constructor)的使用
-
construct:建设、建造。 construction:CCB constructor:建设者
-
一、构造器的作用:
-
1.创建对象
-
2.初始化对象的信息
-
二、说明:
-
1.如果没有显式的定义类的构造器的话,则系统默认提供一个空参的构造器
-
2.定义构造器的格式:权限修饰符 类名(形参列表){}
-
3.一个类中定义的多个构造器,彼此构成重载
-
4.一旦我们显式的定义了类的构造器之后,系统就不再提供默认的空参构造器
-
5.一个类中,至少会有一个构造器。
*/
public class PersonTest {
public static void main(String[] args) {
//创建类的对象:new + 构造器
Person p = new Person();p.eat(); Person p1 = new Person("Tom"); System.out.println(p1.name);
}
}
class Person{
//属性
String name;
int age;
//构造器
public Person(){
System.out.println("Person().....");
}
public Person(String n){
name = n;
}
//
public Person(String n,int a){
name = n;
age = a;
}
//方法
public void eat(){
System.out.println("人吃饭");
}
public void study(){
System.out.println("人可以学习");
}
}
package com.atguigu.java2;
/*
- this关键字的使用:
- 1.this可以用来修饰、调用:属性、方法、构造器
- 2.this修饰属性和方法:
- this理解为:当前对象 或 当前正在创建的对象
- 2.1 在类的方法中,我们可以使用"this.属性"或"this.方法"的方式,调用当前对象属性或方法。但是,
- 通常情况下,我们都选择省略"this."。特殊情况下,如果方法的形参和类的属性同名时,我们必须显式
- 的使用"this.变量"的方式,表明此变量是属性,而非形参。
- 2.2 在类的构造器中,我们可以使用"this.属性"或"this.方法"的方式,调用当前正在创建的对象属性或方法。
- 但是,通常情况下,我们都选择省略"this."。特殊情况下,如果构造器的形参和类的属性同名时,我们必须显式
- 的使用"this.变量"的方式,表明此变量是属性,而非形参。
-
- this调用构造器
- ① 我们在类的构造器中,可以显式的使用"this(形参列表)"方式,调用本类中指定的其他构造器
- ② 构造器中不能通过"this(形参列表)"方式调用自己
- ③ 如果一个类中有n个构造器,则最多有 n - 1构造器中使用了"this(形参列表)"
- ④ 规定:"this(形参列表)"必须声明在当前构造器的首行
- ⑤ 构造器内部,最多只能声明一个"this(形参列表)",用来调用其他的构造器
*/
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.setAge(1);
System.out.println(p1.getAge());
p1.eat();
System.out.println();
Person p2 = new Person("Jerry",20);
System.out.println(p2.getAge());
}
}
class Person{
private String name;
private int age;
public Person(){
// this.eat();
String info = “Person初始化时,需要考虑如下的1,2,3,4…(共40行代码)”;
System.out.println(info);
}
public Person(String name){
this();
this.name = name;
}
public Person(int age){
this();
this.age = age;
}
public Person(String name,int age){
this(age);
this.name = name;
//this.age = age;
//Person初始化时,需要考虑如下的1,2,3,4...(共40行代码)
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return this.age;
}
public void eat(){
System.out.println("人吃饭");
this.study();
}
public void study(){
System.out.println("人学习");
}
}
package com.atguigu.java2;
import java.lang.reflect.Field;
import java.util.*;
import com.atguigu.exer4.Account;
import com.atguigu.exer4.Bank;
import com.atguigu.java2.java3.Dog;
import static java.lang.System.;
import static java.lang.Math.;
/*
- 一、package关键字的使用
- 1.为了更好的实现项目中类的管理,提供包的概念
- 2.使用package声明类或接口所属的包,声明在源文件的首行
- 3.包,属于标识符,遵循标识符的命名规则、规范(xxxyyyzzz)、“见名知意”
- 4.每"."一次,就代表一层文件目录。
- 补充:同一个包下,不能命名同名的接口、类。
-
不同的包下,可以命名同名的接口、类。
- 二、import关键字的使用
- import:导入
-
- 在源文件中显式的使用import结构导入指定包下的类、接口
-
- 声明在包的声明和类的声明之间
-
- 如果需要导入多个结构,则并列写出即可
-
- 可以使用"xxx.*"的方式,表示可以导入xxx包下的所有结构
-
- 如果使用的类或接口是java.lang包下定义的,则可以省略import结构
-
- 如果使用的类或接口是本包下定义的,则可以省略import结构
-
- 如果在源文件中,使用了不同包下的同名的类,则必须至少有一个类需要以全类名的方式显示。
-
- 使用"xxx.*"方式表明可以调用xxx包下的所有结构。但是如果使用的是xxx子包下的结构,则仍需要显式导入
-
-
import static:导入指定类或接口中的静态结构:属性或方法。
*/
public class PackageImportTest {
public static void main(String[] args) {String info = Arrays.toString(new int[]{1,2,3});
Bank bank = new Bank();
ArrayList list = new ArrayList();
HashMap map = new HashMap();Scanner s = null;
System.out.println(“hello!”);
Person p = new Person();
Account acct = new Account(1000);
//全类名的方式显示
com.atguigu.exer3.Account acct1 = new com.atguigu.exer3.Account(1000,2000,0.0123);Date date = new Date();
java.sql.Date date1 = new java.sql.Date(5243523532535L);Dog dog = new Dog();
Field field = null;
out.println(“hello”);
long num = round(123.434);
}
}
-
package com.atguigu.exer;
/*
-
1.创建程序,在其中定义两个类:Person和PersonTest类。定义如下:
-
用setAge()设置人的合法年龄(0~130),用getAge()返回人的年龄。
-
2.练习2:
-
2.1. 在前面定义的Person类中添加构造器,利用构造器设置所有人的age属性初始值都为18。
-
2.2. 修改上题中类和构造器,增加name属性,使得每次创建Person对象的同时初始化对象的age属性值和name属性值。
*/
public class Person {
private int age;
private String name;
public Person(){
age = 18;
}
public Person(String n,int a){
name = n;
age = a;
}
public void setAge(int a){
if(a < 0 || a > 130){
// throw new RuntimeException("传入的数据非法!");
System.out.println("传入的数据非法!");
return;
}
age = a;
}
public int getAge(){
return age;
}
//绝对不要这样写!!
// public int doAge(int a){
// age = a;
// return age;
// }
public void setName(String n){
name = n;
}
public String getName(){
return name;
}
}
package com.atguigu.exer;
/*
- 在PersonTest类中实例化Person类的对象b,
- 调用setAge()和getAge()方法,体会Java的封装性。
*/
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
// p1.age = 1;编译不通过
p1.setAge(12);
System.out.println("年龄为:" + p1.getAge());
// p1.doAge(122);
Person p2 = new Person("Tom", 21);
System.out.println("name = " + p2.getName() + ",age = " + p2.getAge());
}
}
/*
- 编写两个类,TriAngle和TriAngleTest,其中TriAngle类中声明私有的底边长base和高height,同时声明公共方法访问私有变量。
- 此外,提供类必要的构造器。另一个类中使用这些公共方法,计算三角形的面积。
*/
public class TriAngle { //angle:角 angel:天使
private double base;//底边长
private double height;//高
public TriAngle(){
}
public TriAngle(double b,double h){
base = b;
height = h;
}
public void setBase(double b){
base = b;
}
public double getBase(){
return base;
}
public void setHeight(double h){
height = h;
}
public double getHeight(){
return height;
}
}
ackage com.atguigu.exer1;
public class TriAngleTest {
public static void main(String[] args) {
TriAngle t1 = new TriAngle();
t1.setBase(2.0);
t1.setHeight(2.4);
// t1.base = 2.5;//The field TriAngle.base is not visible
// t1.height = 4.3;
System.out.println("base : " + t1.getBase() + ",height : " + t1.getHeight());
TriAngle t2 = new TriAngle(5.1,5.6);
System.out.println("base : " + t2.getBase() + ",height : " + t2.getHeight());
}
}
package com.atguigu.exer2;
public class Girl {
private String name;
private int age;
public Girl() {
}
public Girl(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void marry(Boy boy){
System.out.println("我想嫁给" + boy.getName());
boy.marry(this);
}
/**
*
* @Description 比较两个对象的大小
* @author shkstart
* @date 2019年1月18日下午4:02:09
* @param girl
* @return 正数:当前对象大; 负数:当前对象小 ; 0:当前对象与形参对象相等
*/
public int compare(Girl girl){
// if(this.age > girl.age){
// return 1;
// }else if(this.age < girl.age){
// return -1;
// }else{
// return 0;
// }
return this.age - girl.age;
}
}
public class BoyGirlTest {
public static void main(String[] args) {
Boy boy = new Boy("罗密欧", 21);
boy.shout();
Girl girl = new Girl("朱丽叶", 18);
girl.marry(boy);
Girl girl1 = new Girl("祝英台",19);
int compare = girl.compare(girl1);
if(compare > 0){
System.out.println(girl.getName() + "大");
}else if(compare < 0){
System.out.println(girl1.getName() + "大");
}else{
System.out.println("一样大");
}
}
}
package com.atguigu.exer2;
public class Boy {
private String name;
private int age;
public Boy() {
}
public Boy(String name) {
this.name = name;
}
public Boy(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 void marry(Girl girl){
System.out.println("我想娶" + girl.getName());
}
public void shout(){
if(this.age >= 22){
System.out.println("你可以去合法登记结婚了!");
}else{
System.out.println("先多谈谈恋爱~~");
}
}
}
package com.atguigu.exer3;
public class Account {
private int id;//账号
private double balance;//余额
private double annualInterestRate;//年利率
public Account (int id, double balance, double annualInterestRate ){
this.id = id;
this.balance = balance;
this.annualInterestRate = annualInterestRate;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public double getAnnualInterestRate() {
return annualInterestRate;
}
public void setAnnualInterestRate(double annualInterestRate) {
this.annualInterestRate = annualInterestRate;
}
//在提款方法withdraw中,需要判断用户余额是否能够满足提款数额的要求,如果不能,应给出提示。
public void withdraw (double amount){//取钱
if(balance < amount){
System.out.println("余额不足,取款失败");
return;
}
balance -= amount;
System.out.println("成功取出:" + amount);
}
public void deposit (double amount){//存钱
if(amount > 0){
balance += amount;
System.out.println("成功存入:" + amount);
}
}
}
package com.atguigu.exer3;
public class Customer {
private String firstName;
private String lastName;
private Account account;
public Customer(String f,String l){
this.firstName = f;
this.lastName = l;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}
package com.atguigu.exer3;
/*
- 写一个测试程序。
(1) 创建一个Customer ,名字叫 Jane Smith,
他有一个账号为1000,余额为2000元,年利率为 1.23% 的账户。
(2) 对Jane Smith操作。
存入 100 元,再取出960元。再取出2000元。
打印出Jane Smith 的基本信息
成功存入 :100.0
成功取出:960.0
余额不足,取款失败
Customer [Smith, Jane] has a account: id is 1000,
annualInterestRate is 1.23%, balance is 1140.0
*/
public class CustomerTest {
public static void main(String[] args) {
Customer cust = new Customer(“Jane”, “Smith”);
Account acct = new Account(1000, 2000, 0.0123);
cust.setAccount(acct);
cust.getAccount().deposit(100);
cust.getAccount().withdraw(960);
cust.getAccount().withdraw(2000);
System.out.println("Customer[" + cust.getLastName() + "," + cust.getFirstName() +
"] has a account: id is " + cust.getAccount().getId() + ",annualInterestRate is "+
cust.getAccount().getAnnualInterestRate() * 100 + "% ,balance is " + cust.getAccount().getBalance());
}
}
package com.atguigu.exer4;
public class BankTest {
public static void main(String[] args) {
Bank bank = new Bank();
bank.addCustomer("Jane", "Smith");
//连续操作
bank.getCustomer(0).setAccount(new Account(2000));
bank.getCustomer(0).getAccount().withdraw(500);
double balance = bank.getCustomer(0).getAccount().getBalance();
System.out.println("客户:" + bank.getCustomer(0).getFirstName() + "的账户余额为:" + balance);
System.out.println("***********************");
bank.addCustomer("万里", "杨");
System.out.println("银行客户的个数为:" + bank.getNumOfCustomers());
}
}
package com.atguigu.exer4;
public class Account {
private double balance;
public Account(double init_balance){
this.balance = init_balance;
}
public double getBalance(){
return balance;
}
//存钱操作
public void deposit(double amt){
if(amt > 0){
balance += amt;
System.out.println("存钱成功");
}
}
//取钱操作
public void withdraw(double amt){
if(balance >= amt){
balance -= amt;
System.out.println("取钱成功");
}else{
System.out.println("余额不足");
}
}
}
package com.atguigu.exer4;
public class Customer {
private String firstName;
private String lastName;
private Account account;
public Customer(String f, String l) {
this.firstName = f;
this.lastName = l;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}
package com.atguigu.exer4;
public class Bank {
private Customer[] customers;// 存放多个客户的数组
private int numberOfCustomers;// 记录客户的个数
public Bank() {
customers = new Customer[10];
}
// 添加客户
public void addCustomer(String f, String l) {
Customer cust = new Customer(f, l);
// customers[numberOfCustomers] = cust;
// numberOfCustomers++;
// 或
customers[numberOfCustomers++] = cust;
}
// 获取客户的个数
public int getNumOfCustomers() {
return numberOfCustomers;
}
// 获取指定位置上的客户
public Customer getCustomer(int index) {
// return customers[index];//可能报异常
if (index >= 0 && index < numberOfCustomers) {
return customers[index];
}
return null;
}
}
package com.atguigu.java;
public class ValueTransferTest {
public static void main(String[] args) {
String s1 = "hello";
ValueTransferTest test = new ValueTransferTest();
test.change(s1);
System.out.println(s1);//hi~~
}
public void change(String s){
s = “hi~~”;
}
}
package com.atguigu.java;
public class OrderTest {
public static void main(String[] args) {
Order order = new Order();
order.orderDefault = 1;
order.orderPublic = 2;
//出了Order类之后,私有的结构就不可以调用了
// order.orderPrivate = 3;//The field Order.orderPrivate is not visible
order.methodDefault();
order.methodPublic();
//出了Order类之后,私有的结构就不可以调用了
// order.methodPrivate();//The method methodPrivate() from the type Order is not visible
}
}
package com.atguigu.java;
public class Order {
private int orderPrivate;
int orderDefault;
public int orderPublic;
private void methodPrivate(){
orderPrivate = 1;
orderDefault = 2;
orderPublic = 3;
}
void methodDefault(){
orderPrivate = 1;
orderDefault = 2;
orderPublic = 3;
}
public void methodPublic(){
orderPrivate = 1;
orderDefault = 2;
orderPublic = 3;
}
}
/*
-
面向对象的特征一:封装与隐藏 3W:what? why? how?
-
一、问题的引入:
-
当我们创建一个类的对象以后,我们可以通过"对象.属性"的方式,对对象的属性进行赋值。这里,赋值操作要受到
-
属性的数据类型和存储范围的制约。除此之外,没有其他制约条件。但是,在实际问题中,我们往往需要给属性赋值
-
加入额外的限制条件。这个条件就不能在属性声明时体现,我们只能通过方法进行限制条件的添加。(比如:setLegs())
-
同时,我们需要避免用户再使用"对象.属性"的方式对属性进行赋值。则需要将属性声明为私有的(private).
-
–>此时,针对于属性就体现了封装性。
-
二、封装性的体现:
-
我们将类的属性xxx私有化(private),同时,提供公共的(public)方法来获取(getXxx)和设置(setXxx)此属性的值
-
拓展:封装性的体现:① 如上 ② 不对外暴露的私有的方法 ③ 单例模式 …
-
三、封装性的体现,需要权限修饰符来配合。
-
1.Java规定的4种权限(从小到大排列):private、缺省、protected 、public
-
2.4种权限可以用来修饰类及类的内部结构:属性、方法、构造器、内部类
-
3.具体的,4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类
-
修饰类的话,只能使用:缺省、public
-
总结封装性:Java提供了4种权限修饰符来修饰类及类的内部结构,体现类及类的内部结构在被调用时的可见性的大小。
-
*/
-
类的结构之三:构造器(或构造方法、constructor)的使用
-
construct:建设、建造。 construction:CCB constructor:建设者
-
一、构造器的作用:
-
1.创建对象
-
2.初始化对象的信息
-
二、说明:
-
1.如果没有显式的定义类的构造器的话,则系统默认提供一个空参的构造器
-
2.定义构造器的格式:权限修饰符 类名(形参列表){}
-
3.一个类中定义的多个构造器,彼此构成重载
-
4.一旦我们显式的定义了类的构造器之后,系统就不再提供默认的空参构造器
-
5.一个类中,至少会有一个构造器。
public class PersonTest {
public static void main(String[] args) {
//创建类的对象:new + 构造器
Person p = new Person();
p.eat();
Person p1 = new Person("Tom");
System.out.println(p1.name);
}
}
class Person{
//属性
String name;
int age;
//构造器
public Person(){
System.out.println("Person().....");
}
public Person(String n){
name = n;
}
//
public Person(String n,int a){
name = n;
age = a;
}
//方法
public void eat(){
System.out.println("人吃饭");
}
public void study(){
System.out.println("人可以学习");
}
}
package com.atguigu.java1;
import com.atguigu.java.Order;
public class OrderTest {
public static void main(String[] args) {
Order order = new Order();
order.orderPublic = 2;
// 出了Order类所属的包之后,私有的结构、缺省声明的结构就不可以调用了
// order.orderDefault = 1;
// order.orderPrivate = 3;//The field Order.orderPrivate is not visible
order.methodPublic();
// 出了Order类所属的包之后,私有的结构、缺省声明的结构就不可以调用了
// order.methodDefault();
// order.methodPrivate();//The method methodPrivate() from the type Order is not visible
}
}
avaBean是一种Java语言写成的可重用组件。
所谓JavaBean,是指符合如下标准的Java类:
>类是公共的
>有一个无参的公共的构造器
>有属性,且有对应的get、set方法
public class Customer {
private int id;
private String name;
public Customer(){
}
public void setId(int i){
id = i;
}
public int getId(){
return id;
}
public void setName(String n){
name = n;
}
public String getName(){
return name;
}
}
总结:属性赋值的先后顺序
*
*
- ① 默认初始化
- ② 显式初始化
- ③ 构造器中初始化
- ④ 通过"对象.方法" 或 "对象.属性"的方式,赋值
- 以上操作的先后顺序:① - ② - ③ - ④
public class UserTest {
public static void main(String[] args) {
User u = new User();
System.out.println(u.age);
User u1 = new User(2);
u1.setAge(3);
u1.setAge(5);
System.out.println(u1.age);
}
}
class User{
String name;
int age = 1;
public User(){
}
public User(int a){
age = a;
}
public void setAge(int a){
age = a;
}
}
this关键字的使用:
1.this可以用来修饰、调用:属性、方法、构造器
2.this修饰属性和方法:
this理解为:当前对象 或 当前正在创建的对象
2.1 在类的方法中,我们可以使用"this.属性"或"this.方法"的方式,调用当前对象属性或方法。但是,
通常情况下,我们都选择省略"this."。特殊情况下,如果方法的形参和类的属性同名时,我们必须显式
的使用"this.变量"的方式,表明此变量是属性,而非形参。
2.2 在类的构造器中,我们可以使用"this.属性"或"this.方法"的方式,调用当前正在创建的对象属性或方法。
但是,通常情况下,我们都选择省略"this."。特殊情况下,如果构造器的形参和类的属性同名时,我们必须显式
的使用"this.变量"的方式,表明此变量是属性,而非形参。
-
this调用构造器
① 我们在类的构造器中,可以显式的使用"this(形参列表)"方式,调用本类中指定的其他构造器
② 构造器中不能通过"this(形参列表)“方式调用自己
③ 如果一个类中有n个构造器,则最多有 n - 1构造器中使用了"this(形参列表)”
④ 规定:"this(形参列表)“必须声明在当前构造器的首行
⑤ 构造器内部,最多只能声明一个"this(形参列表)”,用来调用其他的构造器
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.setAge(1);
System.out.println(p1.getAge());
p1.eat();
System.out.println();
Person p2 = new Person("Jerry",20);
System.out.println(p2.getAge());
}
}
class Person{
private String name;
private int age;
public Person(){
// this.eat();
String info = “Person初始化时,需要考虑如下的1,2,3,4…(共40行代码)”;
System.out.println(info);
}
public Person(String name){
this();
this.name = name;
}
public Person(int age){
this();
this.age = age;
}
public Person(String name,int age){
this(age);
this.name = name;
//this.age = age;
//Person初始化时,需要考虑如下的1,2,3,4...(共40行代码)
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return this.age;
}
public void eat(){
System.out.println("人吃饭");
this.study();
}
public void study(){
System.out.println("人学习");
}
}
package com.atguigu.java2;
import java.lang.reflect.Field;
import java.util.*;
import com.atguigu.exer4.Account;
import com.atguigu.exer4.Bank;
import com.atguigu.java2.java3.Dog;
import static java.lang.System.;
import static java.lang.Math.;
/*
-
一、package关键字的使用
-
1.为了更好的实现项目中类的管理,提供包的概念
-
2.使用package声明类或接口所属的包,声明在源文件的首行
-
3.包,属于标识符,遵循标识符的命名规则、规范(xxxyyyzzz)、“见名知意”
-
4.每"."一次,就代表一层文件目录。
-
补充:同一个包下,不能命名同名的接口、类。
-
不同的包下,可以命名同名的接口、类。
-
二、import关键字的使用
-
import:导入
-
- 在源文件中显式的使用import结构导入指定包下的类、接口
-
- 声明在包的声明和类的声明之间
-
- 如果需要导入多个结构,则并列写出即可
-
- 可以使用"xxx.*"的方式,表示可以导入xxx包下的所有结构
-
- 如果使用的类或接口是java.lang包下定义的,则可以省略import结构
-
- 如果使用的类或接口是本包下定义的,则可以省略import结构
-
- 如果在源文件中,使用了不同包下的同名的类,则必须至少有一个类需要以全类名的方式显示。
-
- 使用"xxx.*"方式表明可以调用xxx包下的所有结构。但是如果使用的是xxx子包下的结构,则仍需要显式导入
-
- import static:导入指定类或接口中的静态结构:属性或方法。
*/
public class PackageImportTest {
public static void main(String[] args) {
String info = Arrays.toString(new int[]{1,2,3});
Bank bank = new Bank();
ArrayList list = new ArrayList();
HashMap map = new HashMap();Scanner s = null;
System.out.println(“hello!”);
Person p = new Person();
Account acct = new Account(1000);
//全类名的方式显示
com.atguigu.exer3.Account acct1 = new com.atguigu.exer3.Account(1000,2000,0.0123);Date date = new Date();
java.sql.Date date1 = new java.sql.Date(5243523532535L);Dog dog = new Dog();
Field field = null;
out.println(“hello”);
long num = round(123.434);
}
} - import static:导入指定类或接口中的静态结构:属性或方法。
Eclipse中的快捷键:
- 1.补全代码的声明:alt + /
- 2.快速修复: ctrl + 1
- 3.批量导包:ctrl + shift + o
- 4.使用单行注释:ctrl + /
- 5.使用多行注释: ctrl + shift + /
- 6.取消多行注释:ctrl + shift + \
- 7.复制指定行的代码:ctrl + alt + down 或 ctrl + alt + up
- 8.删除指定行的代码:ctrl + d
- 9.上下移动代码:alt + up 或 alt + down
- 10.切换到下一行代码空位:shift + enter
- 11.切换到上一行代码空位:ctrl + shift + enter
- 12.如何查看源码:ctrl + 选中指定的结构 或 ctrl + shift + t
- 13.退回到前一个编辑的页面:alt + left
- 14.进入到下一个编辑的页面(针对于上面那条来说的):alt + right
- 15.光标选中指定的类,查看继承树结构:ctrl + t
- 16.复制代码: ctrl + c
- 17.撤销: ctrl + z
- 18.反撤销: ctrl + y
- 19.剪切:ctrl + x
- 20.粘贴:ctrl + v
- 21.保存: ctrl + s
- 22.全选:ctrl + a
- 23.格式化代码: ctrl + shift + f
- 24.选中数行,整体往后移动:tab
- 25.选中数行,整体往前移动:shift + tab
- 26.在当前类中,显示类结构,并支持搜索指定的方法、属性等:ctrl + o
- 27.批量修改指定的变量名、方法名、类名等:alt + shift + r
- 28.选中的结构的大小写的切换:变成大写: ctrl + shift + x
- 29.选中的结构的大小写的切换:变成小写:ctrl + shift + y
- 30.调出生成getter/setter/构造器等结构: alt + shift + s
- 31.显示当前选择资源(工程 or 文件)的属性:alt + enter
- 32.快速查找:参照选中的Word快速定位到下一个 :ctrl + k
- 33.关闭当前窗口:ctrl + w
- 34.关闭所有的窗口:ctrl + shift + w
- 35.查看指定的结构使用过的地方:ctrl + alt + g
- 36.查找与替换:ctrl + f
- 37.最大化当前的View:ctrl + m
- 38.直接定位到当前行的首位:home
- 39.直接定位到当前行的末位:end
package com.atguigu.java;
import java.sql.Date;
import java.util.ArrayList;
import java.util.HashMap;
public class EclipseKeys {
final double PROJECT_ACCOUNT_ID = 3.14;
public static void main(String[] args) {
String s = new String();
String str = new String();
char c = str.charAt(0);
int num = 1;
ArrayList list123 = new ArrayList();
list123.add(123);
list123.add(123);
list123.add(123);
list123.add(123);
list123.add(123);
list123.add(123);
HashMap map = null;
map = new HashMap();
Date date = new Date(32423324L);
HashMap map1 = null;
}
}
class User{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User() {
}
public User(int id, String name) {
this.id = id;
this.name = name;
}
}
package com.atguigu.java;
public class Student extends Person{
// String name;
// int age;
String major;
public Student(){
}
public Student(String name,int age,String major){
this.name = name;
// this.age = age;
setAge(age);
this.major = major;
}
// public void eat(){
// System.out.println(“吃饭”);
// }
//
// public void sleep(){
// System.out.println(“睡觉”);
// }
public void study(){
System.out.println("学习");
}
public void show(){
System.out.println("name:" + name + ",age:" + getAge());
}
}
package com.atguigu.java;
public class Creature {
public void breath(){
System.out.println("呼吸");
}
}
package com.atguigu.java;
public class Person extends Creature{
String name;
private int age;
public Person(){
}
public Person(String name,int age){
this.name = name;
this.age = age;
}
public void eat(){
System.out.println("吃饭");
sleep();
}
private void sleep(){
System.out.println("睡觉");
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.atguigu.java;
/*
-
面向对象的特征之二:继承性 why?
-
一、继承性的好处:
-
① 减少了代码的冗余,提高了代码的复用性
-
② 便于功能的扩展
-
③ 为之后多态性的使用,提供了前提
-
二、继承性的格式:
-
class A extends B{}
-
A:子类、派生类、subclass
-
B:父类、超类、基类、superclass
-
2.1体现:一旦子类A继承父类B以后,子类A中就获取了父类B中声明的所有的属性和方法。
-
特别的,父类中声明为private的属性或方法,子类继承父类以后,仍然认为获取了父类中私有的结构。
-
只有因为封装性的影响,使得子类不能直接调用父类的结构而已。
-
2.2 子类继承父类以后,还可以声明自己特有的属性或方法:实现功能的拓展。
-
子类和父类的关系,不同于子集和集合的关系。
-
extends:延展、扩展
-
三、Java中关于继承性的规定:
-
1.一个类可以被多个子类继承。
-
2.Java中类的单继承性:一个类只能有一个父类
-
3.子父类是相对的概念。
-
4.子类直接继承的父类,称为:直接父类。间接继承的父类称为:间接父类
-
5.子类继承父类以后,就获取了直接父类以及所有间接父类中声明的属性和方法
-
四、 1. 如果我们没有显式的声明一个类的父类的话,则此类继承于java.lang.Object类
-
- 所有的java类(除java.lang.Object类之外)都直接或间接的继承于java.lang.Object类
-
- 意味着,所有的java类具有java.lang.Object类声明的功能。
*/
public class ExtendsTest {
public static void main(String[] args) {
Person p1 = new Person();
// p1.age = 1;
p1.eat();
System.out.println(“*****************”);Student s1 = new Student();
s1.eat();
// s1.sleep();
s1.name = “Tom”;
s1.setAge(10);
System.out.println(s1.getAge());s1.breath();
Creature c = new Creature();
System.out.println(c.toString());
}
} - 意味着,所有的java类具有java.lang.Object类声明的功能。
package com.atguigu.java;
/*
- 如何调试程序:
-
- System.out.println().
-
- Eclipse - Debug调试
*/
public class DebugTest {
public static void main(String[] args) {
int i = 10;
int j = 20;
System.out.println("i = " + i + ", j = " + j);
DebugTest test = new DebugTest();
int max = test.getMax(i, j);
System.out.println("max = " + max);
}
private int getMax(int k, int m) {
int max = 0;
if (k < m) {
max = k;
} else {
max = m;
}
return max;
}
}
package com.atguigu.java;
public class DebugTest1 {
public static void main(String[] args) {
int[] arr = new int[] {1,2,3,4,5};
System.out.println(arr);//地址值
char[] arr1 = new char[] {'a','b','c'};
System.out.println(arr1);//abc
}
}
package com.atguigu.java1;
public class Person {
String name;
int age;
public Person(){
}
public Person(String name,int age){
this.name = name;
this.age = age;
}
void eat(){
System.out.println("吃饭");
}
public void walk(int distance){
System.out.println("走路,走的距离是:" + distance + "公里");
show();
eat();
}
private void show(){
System.out.println("我是一个人");
}
public Object info(){
return null;
}
public double info1(){
return 1.0;
}
}
package com.atguigu.java1;
/*
- 方法的重写(override / overwrite)
- 1.重写:子类继承父类以后,可以对父类中同名同参数的方法,进行覆盖操作
- 2.应用:重写以后,当创建子类对象以后,通过子类对象调用子父类中的同名同参数的方法时,实际执行的是子类重写父类的方法。
-
- 重写的规定:
-
方法的声明: 权限修饰符 返回值类型 方法名(形参列表) throws 异常的类型{
-
//方法体
-
}
-
约定俗称:子类中的叫重写的方法,父类中的叫被重写的方法
-
① 子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和形参列表相同
-
② 子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符
-
>特殊情况:子类不能重写父类中声明为private权限的方法
-
③ 返回值类型:
-
>父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void
-
>父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可以是A类或A类的子类
-
>父类被重写的方法的返回值类型是基本数据类型(比如:double),则子类重写的方法的返回值类型必须是相同的基本数据类型(必须也是double)
-
④ 子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型(具体放到异常处理时候讲)
-
子类和父类中的同名同参数的方法要么都声明为非static的(考虑重写),要么都声明为static的(不是重写)。
-
面试题:区分方法的重载与重写
*/
public class PersonTest {public static void main(String[] args) {
Student s = new Student("计算机科学与技术"); s.eat(); s.walk(10); System.out.println("**************"); s.study(); Person p1 = new Person(); p1.eat();
}
}
package com.atguigu.java1;
public class Student extends Person{
String major;
public Student(){
}
public Student(String major){
this.major = major;
}
public void study(){
System.out.println("学习。专业是:" + major);
}
//对父类中的eat()进行了重写
public void eat(){
System.out.println("学生应该多吃有营养的食物");
}
public void show(){
System.out.println("我是一个学生");
}
public String info(){
return null;
}
// public int info1(){
// return 1;
// }
// public void walk(int distance){
// System.out.println(“重写的方法”);
// }
public void walk(int distance) {
System.out.println("重写的方法");
}
}
-
package com.atguigu.java2;
/*- 体会4种不同的权限修饰
*/
public class Order {private int orderPrivate; int orderDefault; protected int orderProtected; public int orderPublic; private void methodPrivate(){ orderPrivate = 1; orderDefault = 2; orderProtected = 3; orderPublic = 4;
}
void methodDefault(){
orderPrivate = 1;
orderDefault = 2;
orderProtected = 3;
orderPublic = 4;
}
protected void methodProtected(){
orderPrivate = 1;
orderDefault = 2;
orderProtected = 3;
orderPublic = 4;
}public void methodPublic(){
orderPrivate = 1;
orderDefault = 2;
orderProtected = 3;
orderPublic = 4;
}
}
package com.atguigu.java2;
public class OrderTest {
public static void main(String[] args) {
Order order = new Order();
order.orderDefault = 1;
order.orderProtected = 2;
order.orderPublic = 3;
order.methodDefault();
order.methodProtected();
order.methodPublic();
//同一个包中的其他类,不可以调用Order类中私有的属性、方法
// order.orderPrivate = 4;
// order.methodPrivate();
}
}
package com.atguigu.java3;
/*
- 子类对象实例化的全过程
-
- 从结果上来看:(继承性)
-
子类继承父类以后,就获取了父类中声明的属性或方法。
-
创建子类的对象,在堆空间中,就会加载所有父类中声明的属性。
-
- 从过程上来看:
-
当我们通过子类的构造器创建子类对象时,我们一定会直接或间接的调用其父类的构造器,进而调用父类的父类的构造器,...
- 直到调用了java.lang.Object类中空参的构造器为止。正因为加载过所有的父类的结构,所以才可以看到内存中有
- 父类中的结构,子类对象才可以考虑进行调用。
- 明确:虽然创建子类对象时,调用了父类的构造器,但是自始至终就创建过一个对象,即为new的子类对象。
*/
public class InstanceTest {
}
package com.atguigu.java3;
import com.atguigu.java2.Order;
public class OrderTest {
public static void main(String[] args) {
Order order = new Order();
order.orderPublic = 1;
order.methodPublic();
//不同包下的普通类(非子类)要使用Order类,不可以调用声明为private、缺省、protected权限的属性、方法
// order.orderPrivate = 2;
// order.orderDefault = 3;
// order.orderProtected = 4;
//
// order.methodPrivate();
// order.methodDefault();
// order.methodProtected();
}
public void show(Order order){
order.orderPublic = 1;
order.methodPublic();
//不同包下的普通类(非子类)要使用Order类,不可以调用声明为private、缺省、protected权限的属性、方法
// order.orderPrivate = 2;
// order.orderDefault = 3;
// order.orderProtected = 4;
//
// order.methodPrivate();
// order.methodDefault();
// order.methodProtected();
//
}
}
package com.atguigu.java3;
public class Person {
String name;
int age;
int id = 1001;//身份证号
public Person(){
System.out.println("我无处不在!");
}
public Person(String name){
this.name = name;
}
public Person(String name,int age){
this(name);
this.age = age;
}
public void eat(){
System.out.println("人:吃饭");
}
public void walk(){
System.out.println("人:走路");
}
}
package com.atguigu.java3;
public class Student extends Person{
String major;
int id = 1002;//学号
public Student(){
super();
}
public Student(String major){
super();
this.major = major;
}
public Student(String name,int age,String major){
// this.name = name;
// this.age = age;
super(name,age);
this.major = major;
}
@Override
public void eat() {
System.out.println("学生:多吃有营养的食物");
}
public void study(){
System.out.println("学生:学习知识");
this.eat();
super.eat();
walk();
}
public void show(){
System.out.println("name = " + name + ", age = " + age);
System.out.println("id = " + this.id);
System.out.println("id = " + super.id);
}
}
package com.atguigu.java3;
import com.atguigu.java2.Order;
public class SubOrder extends Order {
public void method(){
orderProtected = 1;
orderPublic = 2;
methodProtected();
methodPublic();
//在不同包的子类中,不能调用Order类中声明为private和缺省权限的属性、方法
// orderDefault = 3;
// orderPrivate = 4;
//
// methodDefault();
// methodPrivate();
}
}
package com.atguigu.java3;
/*
-
super关键字的使用
-
1.super理解为:父类的
-
2.super可以用来调用:属性、方法、构造器
-
3.super的使用:调用属性和方法
-
3.1 我们可以在子类的方法或构造器中。通过使用"super.属性"或"super.方法"的方式,显式的调用
-
父类中声明的属性或方法。但是,通常情况下,我们习惯省略"super."
-
3.2 特殊情况:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须显式的
-
使用"super.属性"的方式,表明调用的是父类中声明的属性。
-
3.3 特殊情况:当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须显式的
-
使用"super.方法"的方式,表明调用的是父类中被重写的方法。
-
4.super调用构造器
-
4.1 我们可以在子类的构造器中显式的使用"super(形参列表)"的方式,调用父类中声明的指定的构造器
-
4.2 "super(形参列表)"的使用,必须声明在子类构造器的首行!
-
4.3 我们在类的构造器中,针对于"this(形参列表)"或"super(形参列表)"只能二选一,不能同时出现
-
4.4 在构造器的首行,没有显式的声明"this(形参列表)“或"super(形参列表)”,则默认调用的是父类中空参的构造器:super()
-
4.5 在类的多个构造器中,至少有一个类的构造器中使用了"super(形参列表)",调用父类中的构造器
*/
public class SuperTest {
public static void main(String[] args) {Student s = new Student();
s.show();System.out.println();
s.study();
Student s1 = new Student(“Tom”, 21, “IT”);
s1.show();System.out.println(“************”);
Student s2 = new Student();}
}package com.atguigu.java4;
/*
- 面向对象特征之三:多态性
- 1.理解多态性:可以理解为一个事物的多种形态。
- 2.何为多态性:
- 对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)
-
- 多态的使用:虚拟方法调用
- 有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
- 总结:编译,看左边;运行,看右边。
- 4.多态性的使用前提: ① 类的继承关系 ② 方法的重写
- 5.对象的多态性,只适用于方法,不适用于属性(编译和运行都看左边)
*/
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person(); p1.eat(); Man man = new Man(); man.eat(); man.age = 25; man.earnMoney(); //************************************************* System.out.println("*******************"); //对象的多态性:父类的引用指向子类的对象 Person p2 = new Man();
// Person p3 = new Woman();
//多态的使用:当调用子父类同名同参数的方法时,实际执行的是子类重写父类的方法 —虚拟方法调用
p2.eat();
p2.walk();// p2.earnMoney();
System.out.println(p2.id);//1001
}
} -
package com.atguigu.java4;
import java.sql.Connection;
//多态性的使用举例一:
public class AnimalTest {public static void main(String[] args) {
AnimalTest test = new AnimalTest(); test.func(new Dog());
test.func(new Cat());
}public void func(Animal animal){//Animal animal = new Dog();
animal.eat();
animal.shout();if(animal instanceof Dog){ Dog d = (Dog)animal; d.watchDoor(); }
}
// public void func(Dog dog){
// dog.eat();
// dog.shout();
// }
// public void func(Cat cat){
// cat.eat();
// cat.shout();
// }
}class Animal{
public void eat(){
System.out.println(“动物:进食”);
}public void shout(){
System.out.println(“动物:叫”);
}
}class Dog extends Animal{
public void eat(){
System.out.println(“狗吃骨头”);
}public void shout(){
System.out.println(“汪!汪!汪!”);
}public void watchDoor(){
System.out.println(“看门”);
}
}
class Cat extends Animal{
public void eat(){
System.out.println(“猫吃鱼”);
}public void shout(){
System.out.println(“喵!喵!喵!”);
}
}//举例二:
class Order{
public void method(Object obj){
}
}//举例三:
class Driver{public void doData(Connection conn){//conn = new MySQlConnection(); / conn = new OracleConnection();
//规范的步骤去操作数据
// conn.method1();
// conn.method2();
// conn.method3();}
}
package com.atguigu.java4;
public class Man extends Person{
boolean isSmoking;
int id = 1002;
public void earnMoney(){
System.out.println(“男人负责挣钱养家”);
}public void eat(){
System.out.println(“男人多吃肉,长肌肉”);
}public void walk(){
System.out.println(“男人霸气的走路”);
}}
package com.atguigu.java4;
public class Person {
String name;
int age;int id = 1001;
public void eat(){
System.out.println(“人:吃饭”);
}public void walk(){
System.out.println(“人:走路”);
}}
package com.atguigu.java4;
public class Woman extends Person{
boolean isBeauty;
public void goShopping(){
System.out.println(“女人喜欢购物”);
}public void eat(){
System.out.println(“女人少吃,为了减肥”);
}public void walk(){
System.out.println(“女人窈窕的走路”);
}
} -
package com.atguigu.java5;
import java.util.Random;
//面试题:多态是编译时行为还是运行时行为?
//证明如下:
class Animal {protected void eat() {
System.out.println(“animal eat food”);
}
}class Cat extends Animal {
protected void eat() {
System.out.println(“cat eat fish”);
}
}class Dog extends Animal {
public void eat() {
System.out.println(“Dog eat bone”);}
}
class Sheep extends Animal {
public void eat() {
System.out.println(“Sheep eat grass”);}
}
public class InterviewTest {
public static Animal getInstance(int key) {
switch (key) {
case 0:
return new Cat ();
case 1:
return new Dog ();
default:
return new Sheep ();
}
}
public static void main(String[] args) {
int key = new Random().nextInt(3);
System.out.println(key);
Animal animal = getInstance(key);
animal.eat();
}
}
第十八天:
package com.atguigu.exer;
/*
-
建立InstanceTest 类,在类中定义方法method(Person e);
在method中:
(1)根据e的类型调用相应类的getInfo()方法。
(2)根据e的类型执行:
如果e为Person类的对象,输出:
“a person”;
如果e为Student类的对象,输出:
“a student”
“a person ”
如果e为Graduate类的对象,输出:
“a graduated student”
“a student”
“a person”
*/
public class InstanceTest {
public static void main(String[] args) {
InstanceTest test = new InstanceTest();
test.method(new Student());
}
public void method(Person e){
//虚拟方法调用
String info = e.getInfo();
System.out.println(info);
//方式一
// if(e instanceof Graduate){
// System.out.println("a graduated student");
// System.out.println("a student");
// System.out.println("a person");
// }else if(e instanceof Student){
// System.out.println("a student");
// System.out.println("a person");
// }else{
// System.out.println("a person");
// }
//方式二
if(e instanceof Graduate){
System.out.println("a graduated student");
}
if(e instanceof Student){
System.out.println("a student");
}
if(e instanceof Person){
System.out.println("a person");
}
}
}
class Person {
protected String name = “person”;
protected int age = 50;
public String getInfo() {
return "Name: " + name + "\n" + "age: " + age;
}
}
class Student extends Person {
protected String school = “pku”;
public String getInfo() {
return "Name: " + name + "\nage: " + age + "\nschool: " + school;
}
}
class Graduate extends Student {
public String major = “IT”;
public String getInfo() {
return "Name: " + name + "\nage: " + age + "\nschool: " + school + "\nmajor:" + major;
}
}
package com.atguigu.exer;
/*
- 练习:
- 1.若子类重写了父类方法,就意味着子类里定义的方法彻底覆盖了父类里的同名方法,
- 系统将不可能把父类里的方法转移到子类中:编译看左边,运行看右边
- 2.对于实例变量则不存在这样的现象,即使子类里定义了与父类完全相同的实例变量,
- 这个实例变量依然不可能覆盖父类中定义的实例变量:编译运行都看左边
*/
class Base {
int count = 10;
public void display() {
System.out.println(this.count);
}
}
class Sub extends Base {
int count = 20;
public void display() {
System.out.println(this.count);
}
}
public class FieldMethodTest {
public static void main(String[] args) {
Sub s = new Sub();
System.out.println(s.count);//20
s.display();//20
Base b = s;//多态性
//==:对于引用数据类型来讲,比较的是两个引用数据类型变量的地址值是否相同
System.out.println(b == s);//true
System.out.println(b.count);//10
b.display();//20
}
}
package com.atguigu.exer;
//考查多态的笔试题目:
public class InterviewTest1 {
public static void main(String[] args) {
Base1 base = new Sub1();
base.add(1, 2, 3);
Sub1 s = (Sub1)base;
s.add(1,2,3);
}
}
class Base1 {
public void add(int a, int… arr) {
System.out.println(“base1”);
}
}
class Sub1 extends Base1 {
public void add(int a, int[] arr) {
System.out.println("sub_1");
}
public void add(int a, int b, int c) {
System.out.println("sub_2");
}
}
package com.atguigu.exer1;
public class MyRectangle extends GeometricObject {
private double width;
private double height;
public MyRectangle(double width,double height,String color, double weight) {
super(color, weight);
this.width = width;
this.height = height;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
@Override
public double findArea() {
return width * height;
}
}
package com.atguigu.exer1;
public class GeometricObject {//几何图形
protected String color;
protected double weight;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public GeometricObject(String color, double weight) {
super();
this.color = color;
this.weight = weight;
}
public double findArea(){
return 0.0;
}
}
package com.atguigu.exer1;
public class Circle extends GeometricObject {
private double radius;
public Circle(double radius,String color, double weight) {
super(color, weight);
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double findArea(){
return 3.14 * radius * radius;
}
}
package com.atguigu.exer1;
/*
*
- 定义一个测试类GeometricTest,
- 编写equalsArea方法测试两个对象的面积是否相等(注意方法的参数类型,利用动态绑定技术),
- 编写displayGeometricObject方法显示对象的面积(注意方法的参数类型,利用动态绑定技术)。
*/
public class GeometricTest {
public static void main(String[] args) {
GeometricTest test = new GeometricTest();
Circle c1 = new Circle(3.3, "white", 1.0);
test.displayGeometricObject(c1);
Circle c2 = new Circle(3.3, "white", 1.0);
test.displayGeometricObject(c2);
boolean isEquals = test.equalsArea(c1, c2);
System.out.println("c1 和 c2的面积是否相等:" + isEquals);
MyRectangle rect = new MyRectangle(2.1, 3.4, "red", 2.0);
test.displayGeometricObject(rect);
}
public void displayGeometricObject(GeometricObject o){//GeometricObject o = new Circle(...)
System.out.println("面积为:" + o.findArea());
}
//测试两个对象的面积是否相等
public boolean equalsArea(GeometricObject o1,GeometricObject o2){
return o1.findArea() == o2.findArea();
}
}
package com.atguigu.exer2;
/*
- 编写Order类,有int型的orderId,String型的orderName,
- 相应的getter()和setter()方法,两个参数的构造器,
- 重写父类的equals()方法:public boolean equals(Object obj),
- 并判断测试类中创建的两个对象是否相等。
*/
public class OrderTest {
public static void main(String[] args) {
Order order1 = new Order(1001, “AA”);
Order order2 = new Order(1001, new String(“BB”));
System.out.println(order1.equals(order2));
Order order3 = new Order(1001, "BB");
System.out.println(order2.equals(order3));
// String s1 = “BB”;
// String s2 = “BB”;
// System.out.println(s1 == s2);//true
}
}
class Order{
private int orderId;
private String orderName;
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
public Order(int orderId, String orderName) {
super();
this.orderId = orderId;
this.orderName = orderName;
}
@Override
public boolean equals(Object obj) {
if(this == obj){
return true;
}
if(obj instanceof Order){
Order order = (Order)obj;
//正确的:
return this.orderId == order.orderId &&
this.orderName.equals(order.orderName);
//错误的:
// return this.orderId == order.orderId &&
// this.orderName == order.orderName;
}
return false;
}
}
package com.atguigu.exer2;
public class MyDateTest {
public static void main(String[] args) {
MyDate m1 = new MyDate(14, 3, 1976);
MyDate m2 = new MyDate(14, 3, 1976);
if (m1 == m2) {
System.out.println(“m1==m2”);
} else {
System.out.println(“m1!=m2”); // m1 != m2
}
if (m1.equals(m2)) {
System.out.println("m1 is equal to m2");// m1 is equal to m2
} else {
System.out.println("m1 is not equal to m2");
}
}
}
class MyDate{
private int day;
private int month;
private int year;
public MyDate(int day, int month, int year) {
super();
this.day = day;
this.month = month;
this.year = year;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
@Override
public boolean equals(Object obj) {
if(this == obj){
return true;
}
if(obj instanceof MyDate){
MyDate myDate = (MyDate)obj;
return this.day == myDate.day && this.month == myDate.month &&
this.year == myDate.year;
}
return false;
}
// @Override
// public boolean equals(Object obj) {
// if (this == obj)
// return true;
// if (obj == null)
// return false;
// if (getClass() != obj.getClass())
// return false;
// MyDate other = (MyDate) obj;
// if (day != other.day)
// return false;
// if (month != other.month)
// return false;
// if (year != other.year)
// return false;
// return true;
// }
}
package com.atguigu.exer3;
public class GeometricObject {
protected String color;
protected double weight;
public GeometricObject() {
super();
this.color = "white";
this.weight = 1.0;
}
public GeometricObject(String color, double weight) {
super();
this.color = color;
this.weight = weight;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
}
package com.atguigu.exer4;
import java.util.Scanner;
import java.util.Vector;
/*
-
利用Vector代替数组处理:从键盘读入学生成绩(以负数代表输入结束),找出最高分,并输出学生成绩等级。
提示:数组一旦创建,长度就固定不变,所以在创建数组前就需要知道它的长度。
而向量类java.util.Vector可以根据需要动态伸缩。创建Vector对象:Vector v=new Vector();
给向量添加元素:v.addElement(Object obj); //obj必须是对象
取出向量中的元素:Object obj=v.elementAt(0);
注意第一个元素的下标是0,返回值是Object类型的。
计算向量的长度:v.size();
若与最高分相差10分内:A等;20分内:B等;
30分内:C等;其它:D等
*/
public class ScoreTest {
public static void main(String[] args) {
//1.实例化Scanner,用于从键盘获取学生成绩
Scanner scan = new Scanner(System.in);
//2.创建Vector对象:Vector v=new Vector();相当于原来的数组
Vector v = new Vector();
//3.通过for(;;)或while(true)方式,给Vector中添加数组
int maxScore = 0;
for(;;){
System.out.println("请输入学生成绩(以负数代表输入结束)");
int score = scan.nextInt();
//3.2 当输入是负数时,跳出循环
if(score < 0){
break;
}
if(score > 100){
System.out.println("输入的数据非法,请重新输入");
continue;
}
//3.1 添加操作::v.addElement(Object obj)
//jdk5.0之前:
// Integer inScore = new Integer(score);
// v.addElement(inScore);//多态
//jdk5.0之后:
v.addElement(score);//自动装箱
//4.获取学生成绩的最大值
if(maxScore < score){
maxScore = score;
}
}
//5.遍历Vector,得到每个学生的成绩,并与最大成绩比较,得到每个学生的等级。
char level;
for(int i = 0;i < v.size();i++){
Object obj = v.elementAt(i);
//jdk 5.0之前:
// Integer inScore = (Integer)obj;
// int score = inScore.intValue();
//jdk 5.0之后:
int score = (int)obj;
if(maxScore - score <= 10){
level = 'A';
}else if(maxScore - score <= 20){
level = 'B';
}else if(maxScore - score <= 30){
level = 'C';
}else{
level = 'D';
}
System.out.println("student-" + i + " score is " + score + ",level is " + level);
}
}
}
package com.atguigu.java;
import java.util.Date;
/*
- 面向对象特征之三:多态性
- 1.理解多态性:可以理解为一个事物的多种形态。
- 2.何为多态性:
- 对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)
-
- 多态的使用:虚拟方法调用
- 有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
- 总结:编译,看左边;运行,看右边。
- 4.多态性的使用前提: ① 类的继承关系 ② 方法的重写
- 5.对象的多态性,只适用于方法,不适用于属性(编译和运行都看左边)
*/
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.eat();
Man man = new Man();
man.eat();
man.age = 25;
man.earnMoney();
//*************************************************
System.out.println("*******************");
//对象的多态性:父类的引用指向子类的对象
Person p2 = new Man();
// Person p3 = new Woman();
//多态的使用:当调用子父类同名同参数的方法时,实际执行的是子类重写父类的方法 ---虚拟方法调用
p2.eat();
p2.walk();
// p2.earnMoney();
System.out.println(p2.id);//1001
System.out.println("****************************");
//不能调用子类所特有的方法、属性:编译时,p2是Person类型。
p2.name = "Tom";
// p2.earnMoney();
// p2.isSmoking = true;
//有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法的,但是由于变量声明为父类类型,导致
//编译时,只能调用父类中声明的属性和方法。子类特有的属性和方法不能调用。
//如何才能调用子类特有的属性和方法?
//向下转型:使用强制类型转换符。
Man m1 = (Man)p2;
m1.earnMoney();
m1.isSmoking = true;
//使用强转时,可能出现ClassCastException的异常。
// Woman w1 = (Woman)p2;
// w1.goShopping();
/*
* instanceof关键字的使用
*
* a instanceof A:判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false。
*
*
* 使用情境:为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先
* 进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,不进行向下转型。
*
* 如果 a instanceof A返回true,则 a instanceof B也返回true.
* 其中,类B是类A的父类。
*/
if(p2 instanceof Woman){
Woman w1 = (Woman)p2;
w1.goShopping();
System.out.println("******Woman******");
}
if(p2 instanceof Man){
Man m2 = (Man)p2;
m2.earnMoney();
System.out.println("******Man******");
}
if(p2 instanceof Person){
System.out.println("******Person******");
}
if(p2 instanceof Object){
System.out.println("******Object******");
}
// if(p2 instanceof String){
//
// }
//练习:
//问题一:编译时通过,运行时不通过
//举例一:
// Person p3 = new Woman();
// Man m3 = (Man)p3;
//举例二:
// Person p4 = new Person();
// Man m4 = (Man)p4;
//问题二:编译通过,运行时也通过
// Object obj = new Woman();
// Person p = (Person)obj;
//问题三:编译不通过
// Man m5 = new Woman();
// String str = new Date();
// Object o = new Date();
// String str1 = (String)o;
}
}
//class Order{
//
//}
package com.atguigu.java1;
//Object类的clone()的使用
public class CloneTest {
public static void main(String[] args) {
Animal a1 = new Animal(“花花”);
try {
Animal a2 = (Animal) a1.clone();
System.out.println(“原始对象:” + a1);
a2.setName(“毛毛”);
System.out.println(“clone之后的对象:” + a2);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
class Animal implements Cloneable{
private String name;
public Animal() {
super();
}
public Animal(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Animal [name=" + name + "]";
}
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
}
package com.atguigu.java1;
public class FinalizeTest {
public static void main(String[] args) {
Person p = new Person(“Peter”, 12);
System.out.println§;
p = null;//此时对象实体就是垃圾对象,等待被回收。但时间不确定。
System.gc();//强制性释放空间
}
}
class Person{
private String name;
private int age;
public Person(String name, int age) {
super();
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;
}
//子类重写此方法,可在释放对象前进行某些操作
@Override
protected void finalize() throws Throwable {
System.out.println("对象被释放--->" + this);
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
package com.atguigu.java1;
/*
- java.lang.Object类
- 1.Object类是所有Java类的根父类
- 2.如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object类
- 3.Object类中的功能(属性、方法)就具有通用性。
- 属性:无
- 方法:equals() / toString() / getClass() /hashCode() / clone() / finalize()
-
wait() 、 notify()、notifyAll()
-
- Object类只声明了一个空参的构造器
- 面试题:
- final、finally、finalize的区别?
*/
public class ObjectTest {
public static void main(String[] args) {
Order order = new Order();
System.out.println(order.getClass().getSuperclass());
}
}
class Order{
}
package com.atguigu.java1;
import java.util.Date;
/*
-
Object类中toString()的使用:
-
- 当我们输出一个对象的引用时,实际上就是调用当前对象的toString()
-
- Object类中toString()的定义:
-
public String toString() {
return getClass().getName() + “@” + Integer.toHexString(hashCode());
} -
- 像String、Date、File、包装类等都重写了Object类中的toString()方法。
-
使得在调用对象的toString()时,返回"实体内容"信息
-
- 自定义类也可以重写toString()方法,当调用此方法时,返回对象的"实体内容"
*/
public class ToStringTest {
public static void main(String[] args) {Customer cust1 = new Customer(“Tom”,21);
System.out.println(cust1.toString());//com.atguigu.java1.Customer@15db9742–>Customer[name = Tom,age = 21]
System.out.println(cust1);//com.atguigu.java1.Customer@15db9742–>Customer[name = Tom,age = 21]String str = new String(“MM”);
System.out.println(str);//MMDate date = new Date(4534534534543L);
System.out.println(date.toString());//Mon Sep 11 08:55:34 GMT+08:00 2113 - 自定义类也可以重写toString()方法,当调用此方法时,返回对象的"实体内容"
}
}
package com.atguigu.java1;
public class Customer {
private String name;
private int 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 Customer() {
super();
}
public Customer(String name, int age) {
super();
this.name = name;
this.age = age;
}
//自动生成的equals()
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Customer other = (Customer) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
//重写的原则:比较两个对象的实体内容(即:name和age)是否相同
//手动实现equals()的重写
// @Override
// public boolean equals(Object obj) {
//
System.out.println(“Customer equals()…”);
// if (this == obj) {
// return true;
// }
//
// if(obj instanceof Customer){
// Customer cust = (Customer)obj;
// //比较两个对象的每个属性是否都相同
if(this.age == cust.age && this.name.equals(cust.name)){
return true;
}else{
return false;
}
//
// //或
// return this.age == cust.age && this.name.equals(cust.name);
// }else{
// return false;
//
// }
//
// }
//手动实现
// @Override
// public String toString() {
// return "Customer[name = " + name + ",age = " + age + “]”;
// }
//自动实现
@Override
public String toString() {
return “Customer [name=” + name + “, age=” + age + “]”;
}
}
package com.atguigu.java2;
import java.util.Date;
import org.junit.Test;
/*
-
Java中的JUnit单元测试
-
步骤:
-
1.选中当前工程 - 右键选择:build path - add libraries - JUnit 4 - 下一步
-
2.创建Java类,进行单元测试。
-
此时的Java类要求:① 此类是public的 ②此类提供公共的无参的构造器
-
3.此类中声明单元测试方法。
-
此时的单元测试方法:方法的权限是public,没有返回值,没有形参
-
4.此单元测试方法上需要声明注解:@Test,并在单元测试类中导入:import org.junit.Test;
-
5.声明好单元测试方法以后,就可以在方法体内测试相关的代码。
-
6.写完代码以后,左键双击单元测试方法名,右键:run as - JUnit Test
-
说明:
-
1.如果执行结果没有任何异常:绿条
-
2.如果执行结果出现异常:红条
*/
public class JUnitTest {int num = 10;
@Test
public void testEquals(){
String s1 = “MM”;
String s2 = “MM”;
System.out.println(s1.equals(s2));
//ClassCastException的异常
// Object obj = new String(“GG”);
// Date date = (Date)obj;System.out.println(num); show();
}
public void show(){
num = 20;
System.out.println(“show()…”);
}@Test
public void testToString(){
String s2 = “MM”;
System.out.println(s2.toString());
}
}
package com.atguigu.java2;
import org.junit.Test;
/*
- 包装类的使用:
- 1.java提供了8种基本数据类型对应的包装类,使得基本数据类型的变量具有类的特征
- 2.掌握的:基本数据类型、包装类、String三者之间的相互转换
*/
public class WrapperTest {
//String类型 --->基本数据类型、包装类:调用包装类的parseXxx(String s)
@Test
public void test5(){
String str1 = "123";
//错误的情况:
// int num1 = (int)str1;
// Integer in1 = (Integer)str1;
//可能会报NumberFormatException
int num2 = Integer.parseInt(str1);
System.out.println(num2 + 1);
String str2 = "true1";
boolean b1 = Boolean.parseBoolean(str2);
System.out.println(b1);
}
//基本数据类型、包装类--->String类型:调用String重载的valueOf(Xxx xxx)
@Test
public void test4(){
int num1 = 10;
//方式1:连接运算
String str1 = num1 + "";
//方式2:调用String的valueOf(Xxx xxx)
float f1 = 12.3f;
String str2 = String.valueOf(f1);//"12.3"
Double d1 = new Double(12.4);
String str3 = String.valueOf(d1);
System.out.println(str2);
System.out.println(str3);//"12.4"
}
/*
* JDK 5.0 新特性:自动装箱 与自动拆箱
*/
@Test
public void test3(){
// int num1 = 10;
// //基本数据类型-->包装类的对象
// method(num1);
//自动装箱:基本数据类型 --->包装类
int num2 = 10;
Integer in1 = num2;//自动装箱
boolean b1 = true;
Boolean b2 = b1;//自动装箱
//自动拆箱:包装类--->基本数据类型
System.out.println(in1.toString());
int num3 = in1;//自动拆箱
}
public void method(Object obj){
System.out.println(obj);
}
//包装类--->基本数据类型:调用包装类Xxx的xxxValue()
@Test
public void test2(){
Integer in1 = new Integer(12);
int i1 = in1.intValue();
System.out.println(i1 + 1);
Float f1 = new Float(12.3);
float f2 = f1.floatValue();
System.out.println(f2 + 1);
}
//基本数据类型 --->包装类:调用包装类的构造器
@Test
public void test1(){
int num1 = 10;
// System.out.println(num1.toString());
Integer in1 = new Integer(num1);
System.out.println(in1.toString());
Integer in2 = new Integer("123");
System.out.println(in2.toString());
//报异常
// Integer in3 = new Integer("123abc");
// System.out.println(in3.toString());
Float f1 = new Float(12.3f);
Float f2 = new Float("12.3");
System.out.println(f1);
System.out.println(f2);
Boolean b1 = new Boolean(true);
Boolean b2 = new Boolean("TrUe");
System.out.println(b2);
Boolean b3 = new Boolean("true123");
System.out.println(b3);//false
Order order = new Order();
System.out.println(order.isMale);//false
System.out.println(order.isFemale);//null
}
}
class Order{
boolean isMale;
Boolean isFemale;
}
package com.atguigu.java2;
import java.util.Date;
import org.junit.Test;
/*
-
Java中的JUnit单元测试
-
步骤:
-
1.选中当前工程 - 右键选择:build path - add libraries - JUnit 4 - 下一步
-
2.创建Java类,进行单元测试。
-
此时的Java类要求:① 此类是public的 ②此类提供公共的无参的构造器
-
3.此类中声明单元测试方法。
-
此时的单元测试方法:方法的权限是public,没有返回值,没有形参
-
4.此单元测试方法上需要声明注解:@Test,并在单元测试类中导入:import org.junit.Test;
-
5.声明好单元测试方法以后,就可以在方法体内测试相关的代码。
-
6.写完代码以后,左键双击单元测试方法名,右键:run as - JUnit Test
-
说明:
-
1.如果执行结果没有任何异常:绿条
-
2.如果执行结果出现异常:红条
*/
public class JUnitTest {int num = 10;
@Test
public void testEquals(){
String s1 = “MM”;
String s2 = “MM”;
System.out.println(s1.equals(s2));
//ClassCastException的异常
// Object obj = new String(“GG”);
// Date date = (Date)obj;System.out.println(num); show();
}
public void show(){
num = 20;
System.out.println(“show()…”);
}@Test
public void testToString(){
String s2 = “MM”;
System.out.println(s2.toString());
}
} -
package com.atguigu.java2;
import org.junit.Test;
/*
* 关于包装类使用的面试题
*
*
*/
public class InterviewTest {
@Test
public void test1() {
Object o1 = true ? new Integer(1) : new Double(2.0);
System.out.println(o1);// 1.0
}
@Test
public void test2() {
Object o2;
if (true)
o2 = new Integer(1);
else
o2 = new Double(2.0);
System.out.println(o2);// 1
}
@Test
public void test3() {
Integer i = new Integer(1);
Integer j = new Integer(1);
System.out.println(i == j);//false
//Integer内部定义了IntegerCache结构,IntegerCache中定义了Integer[],
//保存了从-128~127范围的整数。如果我们使用自动装箱的方式,给Integer赋值的范围在
//-128~127范围内时,可以直接使用数组中的元素,不用再去new了。目的:提高效率
Integer m = 1;
Integer n = 1;
System.out.println(m == n);//true
Integer x = 128;//相当于new了一个Integer对象
Integer y = 128;//相当于new了一个Integer对象
System.out.println(x == y);//false
}
}
第十四天
package com.atguigu.java;
public class Man extends Person{
public Man(String name, int age) {
super(name, age);
}
public void earnMoney(){
System.out.println("男人负责挣钱养家");
}
public void eat(){
System.out.println("男人多吃肉,长肌肉");
}
public void walk(){
System.out.println("男人霸气的走路");
}
}
package com.atguigu.java;
public class Person {
String name;
int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public void eat() {
System.out.println("人:吃饭");
}
public void walk() {
System.out.println("人:走路");
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
// public boolean equals(Object obj) {
// if (obj == this) {
// return true;
// }
//
// if (obj instanceof Person) {
// Person p = (Person) obj;
// return this.age == p.age && this.name.equals(p.name);
// }
//
// return false;
// }
}
package com.atguigu.java;
import org.junit.Test;
public class ReviewTest {
//关于toString()
@Test
public void test3(){
String s = "abc";
s = null;
System.out.println(s);//null
System.out.println("*********");
System.out.println(s.toString());//出现NullPointerException
}
//区别手动写的和自动生成的equals()
@Test
public void test2(){
Person p = new Person("Tom", 12);
Man m = new Man("Tom", 12);
System.out.println(p.equals(m));
}
//数组也作为Object类的子类出现,可以调用Object类中声明的方法
@Test
public void test1(){
int[] arr = new int[]{1,2,3};
print(arr);
System.out.println(arr.getClass().getSuperclass());
}
public void print(Object obj){
System.out.println(obj);
}
}
package com.atguigu.java1;
/*
- 自定义数组的工具类
*/
public class ArrayUtil {
// 求数组的最大值
public static int getMax(int[] arr) {
int maxValue = arr[0];
for (int i = 1; i < arr.length; i++) {
if (maxValue < arr[i]) {
maxValue = arr[i];
}
}
return maxValue;
}
// 求数组的最小值
public static int getMin(int[] arr) {
int minValue = arr[0];
for (int i = 1; i < arr.length; i++) {
if (minValue > arr[i]) {
minValue = arr[i];
}
}
return minValue;
}
// 求数组的总和
public static int getSum(int[] arr) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
// 求数组的平均值
public static int getAvg(int[] arr) {
return getSum(arr) / arr.length;
}
//如下的两个同名方法构成了重载
// 反转数组
public static void reverse(int[] arr) {
for (int i = 0; i < arr.length / 2; i++) {
int temp = arr[i];
arr[i] = arr[arr.length - i - 1];
arr[arr.length - i - 1] = temp;
}
}
// public static void reverse(String[] arr){
//
// }
// 复制数组
public static int[] copy(int[] arr) {
int[] arr1 = new int[arr.length];
for (int i = 0; i < arr1.length; i++) {
arr1[i] = arr[i];
}
return arr1;
}
// 数组排序
public static void sort(int[] arr) {
// 冒泡排序
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
// int temp = arr[j];
// arr[j] = arr[j + 1];
// arr[j + 1] = temp;
//错误的:
// swap(arr[j],arr[j + 1]);
//正确的:
swap(arr,j,j + 1);
}
}
}
}
//错误的:交换数组中指定两个位置元素的值
// public void swap(int i,int j){
// int temp = i;
// i = j;
// j = temp;
// }
//正确的:交换数组中指定两个位置元素的值
private static void swap(int[] arr,int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// 遍历数组
public static void print(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
System.out.println();
}
// 查找指定元素
public static int getIndex(int[] arr, int dest) {
// 线性查找:
for (int i = 0; i < arr.length; i++) {
if (dest == arr[i]) {
return i;
}
}
return -1;//返回一个负数,表示没有找到
}
}
package com.atguigu.java1;
public class ArrayUtilTest {
public static void main(String[] args) {
// ArrayUtil util = new ArrayUtil();
int[] arr = new int[]{32,34,32,5,3,54,654,-98,0,-53,5};
int max = ArrayUtil.getMax(arr);
System.out.println(“最大值为:” + max);
System.out.println("排序前:");
ArrayUtil.print(arr);
ArrayUtil.sort(arr);
System.out.println(“排序后:”);
ArrayUtil.print(arr);
// System.out.println(“查找:”);
// int index = util.getIndex(arr, -5);
// if(index >= 0){
// System.out.println(“找到了,索引地址为:” + index);
// }else{
// System.out.println(“未找到”);
// }
// util.reverse(arr);
}
}
package com.atguigu.java1;
//static关键字的应用
public class CircleTest {
public static void main(String[] args) {
Circle c1 = new Circle();
Circle c2 = new Circle();
Circle c3 = new Circle(3.4);
System.out.println("c1的id:" + c1.getId() );
System.out.println("c2的id:" + c2.getId() );
System.out.println("c3的id:" + c3.getId() );
System.out.println("创建的圆的个数为:" + Circle.getTotal());
}
}
class Circle{
private double radius;
private int id;//自动赋值
public Circle(){
id = init++;
total++;
}
public Circle(double radius){
this();
// id = init++;
// total++;
this.radius = radius;
}
private static int total;//记录创建的圆的个数
private static int init = 1001;//static声明的属性被所有对象所共享
public double findArea(){
return 3.14 * radius * radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public int getId() {
return id;
}
public static int getTotal() {
return total;
}
}
package com.atguigu.java1;
/*
-
static关键字的使用
-
1.static:静态的
-
2.static可以用来修饰:属性、方法、代码块、内部类
-
3.使用static修饰属性:静态变量(或类变量)
-
3.1 属性,按是否使用static修饰,又分为:静态属性 vs 非静态属性(实例变量)
-
实例变量:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性。当修改其中一个对象中的
-
非静态属性时,不会导致其他对象中同样的属性值的修改。
-
静态变量:我们创建了类的多个对象,多个对象共享同一个静态变量。当通过某一个对象修改静态变量时,会导致
-
其他对象调用此静态变量时,是修改过了的。
-
3.2 static修饰属性的其他说明:
-
① 静态变量随着类的加载而加载。可以通过"类.静态变量"的方式进行调用
-
② 静态变量的加载要早于对象的创建。
-
③ 由于类只会加载一次,则静态变量在内存中也只会存在一份:存在方法区的静态域中。
-
④ 类变量 实例变量
-
类 yes no
-
对象 yes yes
-
3.3 静态属性举例:System.out; Math.PI;
-
4.使用static修饰方法:静态方法
-
① 随着类的加载而加载,可以通过"类.静态方法"的方式进行调用
-
② 静态方法 非静态方法
-
类 yes no
-
对象 yes yes
-
③ 静态方法中,只能调用静态的方法或属性
-
非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性
-
- static注意点:
-
5.1 在静态的方法内,不能使用this关键字、super关键字
-
5.2 关于静态属性和静态方法的使用,大家都从生命周期的角度去理解。
-
- 开发中,如何确定一个属性是否要声明为static的?
-
> 属性是可以被多个对象所共享的,不会随着对象的不同而不同的。
-
> 类中的常量也常常声明为static
-
开发中,如何确定一个方法是否要声明为static的?
-
> 操作静态属性的方法,通常设置为static的
-
工具类中的方法,习惯上声明为static的。 比如:Math、Arrays、Collections
*/
public class StaticTest {
public static void main(String[] args) {Chinese.nation = “中国”;
Chinese c1 = new Chinese();
c1.name = “姚明”;
c1.age = 40;
c1.nation = “CHN”;Chinese c2 = new Chinese();
c2.name = “马龙”;
c2.age = 30;
c2.nation = “CHINA”;System.out.println(c1.nation);
//编译不通过
// Chinese.name = “张继科”;c1.eat();
Chinese.show();
//编译不通过
// Chinese.eat();
// Chinese.info();
}
}
//中国人
class Chinese{String name;
int age;
static String nation;public void eat(){
System.out.println(“中国人吃中餐”);
//调用非静态结构
this.info();
System.out.println(“name :” +name);
//调用静态结构
walk();
System.out.println("nation : " + nation);
}public static void show(){
System.out.println(“我是一个中国人!”);
//不能调用非静态的结构
// eat();
// name = “Tom”;
//可以调用静态的结构
System.out.println(Chinese.nation);
walk();
}public void info(){
System.out.println(“name :” + name +",age : " + age);
}public static void walk(){
}
}
package com.atguigu.java2;
/*
- main()方法的使用说明:
-
- main()方法作为程序的入口
-
- main()方法也是一个普通的静态方法
-
- main()方法可以作为我们与控制台交互的方式。(之前:使用Scanner)
*/
public class MainTest {
public static void main(String[] args) {//入口
Main.main(new String[100]);
MainTest test = new MainTest();
test.show();
}
public void show(){
}
}
class Main{
public static void main(String[] args) {
for(int i = 0;i < args.length;i++){
args[i] = "args_" + i;
System.out.println(args[i]);
}
}
}
package com.atguigu.java2;
public class MainDemo {
public static void main(String[] args) {
for(int i = 0;i < args.length;i++){
System.out.println("*****" + args[i]);
int num = Integer.parseInt(args[i]);
System.out.println("#####" + num);
}
}
}
package com.atguigu.java2;
/*
- 单例设计模式:
-
- 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例。
-
- 如何实现?
- 饿汉式 vs 懒汉式
-
- 区分饿汉式 和 懒汉式
- 饿汉式:
-
坏处:对象加载时间过长。
-
好处:饿汉式是线程安全的
- 懒汉式:好处:延迟对象的创建。
-
目前的写法坏处:线程不安全。--->到多线程内容时,再修改
*/
public class SingletonTest1 {
public static void main(String[] args) {
// Bank bank1 = new Bank();
// Bank bank2 = new Bank();
Bank bank1 = Bank.getInstance();
Bank bank2 = Bank.getInstance();
System.out.println(bank1 == bank2);
}
}
//饿汉式
class Bank{
//1.私有化类的构造器
private Bank(){
}
//2.内部创建类的对象
//4.要求此对象也必须声明为静态的
private static Bank instance = new Bank();
//3.提供公共的静态的方法,返回类的对象
public static Bank getInstance(){
return instance;
}
}
package com.atguigu.java2;
/*
- 单例模式的懒汉式实现
*/
public class SingletonTest2 {
public static void main(String[] args) {
Order order1 = Order.getInstance();
Order order2 = Order.getInstance();
System.out.println(order1 == order2);
}
}
class Order{
//1.私有化类的构造器
private Order(){
}
//2.声明当前类对象,没有初始化
//4.此对象也必须声明为static的
private static Order instance = null;
//3.声明public、static的返回当前类对象的方法
public static Order getInstance(){
if(instance == null){
instance = new Order();
}
return instance;
}
}
package com.atguigu.java3;
//总结:由父及子,静态先行
class Root{
static{
System.out.println(“Root的静态初始化块”);
}
{
System.out.println(“Root的普通初始化块”);
}
public Root(){
super();
System.out.println(“Root的无参数的构造器”);
}
}
class Mid extends Root{
static{
System.out.println(“Mid的静态初始化块”);
}
{
System.out.println(“Mid的普通初始化块”);
}
public Mid(){
super();
System.out.println(“Mid的无参数的构造器”);
}
public Mid(String msg){
//通过this调用同一类中重载的构造器
this();
System.out.println(“Mid的带参数构造器,其参数值:”
+ msg);
}
}
class Leaf extends Mid{
static{
System.out.println(“Leaf的静态初始化块”);
}
{
System.out.println(“Leaf的普通初始化块”);
}
public Leaf(){
//通过super调用父类中有一个字符串参数的构造器
super(“尚硅谷”);
System.out.println(“Leaf的构造器”);
}
}
public class LeafTest{
public static void main(String[] args){
new Leaf();
System.out.println();
new Leaf();
}
}
package com.atguigu.java3;
/*
- 对属性可以赋值的位置:
- ①默认初始化
- ②显式初始化/⑤在代码块中赋值
- ③构造器中初始化
- ④有了对象以后,可以通过"对象.属性"或"对象.方法"的方式,进行赋值
- 执行的先后顺序:① - ② / ⑤ - ③ - ④
*/
public class OrderTest {
public static void main(String[] args) {
Order order = new Order();
System.out.println(order.orderId);
}
}
class Order{
int orderId = 3;
{
orderId = 4;
}
}
package com.atguigu.java3;
/*
- 类的成员之四:代码块(或初始化块)
-
- 代码块的作用:用来初始化类、对象
-
- 代码块如果有修饰的话,只能使用static.
-
- 分类:静态代码块 vs 非静态代码块
-
- 静态代码块
-
>内部可以有输出语句
-
>随着类的加载而执行,而且只执行一次
-
>作用:初始化类的信息
-
>如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行
-
>静态代码块的执行要优先于非静态代码块的执行
-
>静态代码块内只能调用静态的属性、静态的方法,不能调用非静态的结构
-
- 非静态代码块
-
>内部可以有输出语句
-
>随着对象的创建而执行
-
>每创建一个对象,就执行一次非静态代码块
-
>作用:可以在创建对象时,对对象的属性等进行初始化
-
>如果一个类中定义了多个非静态代码块,则按照声明的先后顺序执行
-
>非静态代码块内可以调用静态的属性、静态的方法,或非静态的属性、非静态的方法
*/
public class BlockTest {
public static void main(String[] args) {
String desc = Person.desc;
System.out.println(desc);
Person p1 = new Person();
Person p2 = new Person();
System.out.println(p1.age);
Person.info();
}
}
class Person{
//属性
String name;
int age;
static String desc = "我是一个人";
//构造器
public Person(){
}
public Person(String name,int age){
this.name = name;
this.age = age;
}
//非static的代码块
{
System.out.println("hello, block - 2");
}
{
System.out.println("hello, block - 1");
//调用非静态结构
age = 1;
eat();
//调用静态结构
desc = "我是一个爱学习的人1";
info();
}
//static的代码块
static{
System.out.println("hello,static block-2");
}
static{
System.out.println("hello,static block-1");
//调用静态结构
desc = "我是一个爱学习的人";
info();
//不可以调用非静态结构
// eat();
// name = “Tom”;
}
//方法
public void eat(){
System.out.println("吃饭");
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public static void info(){
System.out.println("我是一个快乐的人!");
}
}
package com.atguigu.java3;
/*
-
final:最终的
-
- final可以用来修饰的结构:类、方法、变量
-
- final 用来修饰一个类:此类不能被其他类所继承。
-
比如:String类、System类、StringBuffer类
-
- final 用来修饰方法:表明此方法不可以被重写
-
比如:Object类中getClass();
-
- final 用来修饰变量:此时的"变量"就称为是一个常量
-
4.1 final修饰属性:可以考虑赋值的位置有:显式初始化、代码块中初始化、构造器中初始化
-
4.2 final修饰局部变量:
-
尤其是使用final修饰形参时,表明此形参是一个常量。当我们调用此方法时,给常量形参赋一个实参。一旦赋值
-
以后,就只能在方法体内使用此形参,但不能进行重新赋值。
-
static final 用来修饰属性:全局常量
*/
public class FinalTest {final int WIDTH = 0;
final int LEFT;
final int RIGHT;
// final int DOWN;{
LEFT = 1;
}public FinalTest(){
RIGHT = 2;
}public FinalTest(int n){
RIGHT = n;
}
// public void setDown(int down){
// this.DOWN = down;
// }
public void doWidth(){
// width = 20;
}
public void show(){
final int NUM = 10;//常量
// NUM += 20;
}
public void show(final int num){
// num = 20;//编译不通过
System.out.println(num);
}
public static void main(String[] args) {
int num = 10;
num = num + 5;
FinalTest test = new FinalTest();
// test.setDown(3);
test.show(10);
}
}
final class FinalA{
}
//class B extends FinalA{
//
//}
//class C extends String{
//
//}
class AA{
public final void show(){
}
}
class BB extends AA{
// public void show(){
//
// }
}
package com.atguigu.java3;
class Father {
static {
System.out.println(“11111111111”);
}
{
System.out.println(“22222222222”);
}
public Father() {
System.out.println("33333333333");
}
}
public class Son extends Father {
static {
System.out.println(“44444444444”);
}
{
System.out.println(“55555555555”);
}
public Son() {
System.out.println(“66666666666”);
}
public static void main(String[] args) { // 由父及子 静态先行
System.out.println("77777777777");
System.out.println("************************");
new Son();
System.out.println("************************");
new Son();
System.out.println("************************");
new Father();
}
}
作业:
package com.atguigu.exer;
/*
-
编写一个类实现银行账户的概念,包含的属性有“帐号”、“密码”、“存款余额”、“利率”、“最小余额”,
-
定义封装这些属性的方法。账号要自动生成。
编写主类,使用银行账户类,输入、输出3个储户的上述信息。
考虑:哪些属性可以设计成static属性。
*/
public class Account {
private int id;
private String pwd = "000000";
private double balance;
private static double interestRate;
private static double minMoney = 1.0;
private static int init = 1001;//用于自动生成id使用的
public Account(){
id = init++;
}
public Account(String pwd,double balance){
id = init++;
this.pwd = pwd;
this.balance = balance;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public static double getInterestRate() {
return interestRate;
}
public static void setInterestRate(double interestRate) {
Account.interestRate = interestRate;
}
public static double getMinMoney() {
return minMoney;
}
public static void setMinMoney(double minMoney) {
Account.minMoney = minMoney;
}
public int getId() {
return id;
}
public double getBalance() {
return balance;
}
@Override
public String toString() {
return "Account [id=" + id + ", pwd=" + pwd + ", balance=" + balance + "]";
}
}
package com.atguigu.exer;
public class AccountTest {
public static void main(String[] args) {
Account acct1 = new Account();
Account acct2 = new Account("qwerty",2000);
Account.setInterestRate(0.012);
Account.setMinMoney(100);
System.out.println(acct1);
System.out.println(acct2);
System.out.println(acct1.getInterestRate());
System.out.println(acct1.getMinMoney());
}
}
第十五天:
package com.atguigu.java;
public class SingletonTest {
public static void main(String[] args) {
Bank bank1 = Bank.instance;
// Bank.instance = null;
Bank bank2 = Bank.instance;
System.out.println(bank1 == bank2);
}
}
class Bank{
private Bank(){
}
public static final Bank instance = new Bank();
}
package com.atguigu.java;
/*
- abstract使用上的注意点:
- 1.abstract不能用来修饰:属性、构造器等结构
- 2.abstract不能用来修饰私有方法、静态方法、final的方法、final的类
- */
public class AbstractTest1 {
}
package com.atguigu.java;
/*
- abstract关键字的使用
- 1.abstract:抽象的
- 2.abstract可以用来修饰的结构:类、方法
-
- abstract修饰类:抽象类
-
> 此类不能实例化
-
> 抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化的全过程)
-
> 开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作
-
- abstract修饰方法:抽象方法
-
> 抽象方法只有方法的声明,没有方法体
-
> 包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法的。
-
> 若子类重写了父类中的所有的抽象方法后,此子类方可实例化
-
若子类没有重写父类中的所有的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰
*/
public class AbstractTest {
public static void main(String[] args) {
//一旦Person类抽象了,就不可实例化
// Person p1 = new Person();
// p1.eat();
}
}
abstract class Creature{
public abstract void breath();
}
abstract class Person extends Creature{
String name;
int age;
public Person(){
}
public Person(String name,int age){
this.name = name;
this.age = age;
}
//不是抽象方法:
// public void eat(){
//
// }
//抽象方法
public abstract void eat();
public void walk(){
System.out.println("人走路");
}
}
class Student extends Person{
public Student(String name,int age){
super(name,age);
}
public Student(){
}
public void eat(){
System.out.println("学生多吃有营养的食物");
}
@Override
public void breath() {
System.out.println("学生应该呼吸新鲜的没有雾霾的空气");
}
}
package com.atguigu.java;
/*
- 抽象类的匿名子类
*/
public class PersonTest {
public static void main(String[] args) {
method(new Student());//匿名对象
Worker worker = new Worker();
method1(worker);//非匿名的类非匿名的对象
method1(new Worker());//非匿名的类匿名的对象
System.out.println("********************");
//创建了一匿名子类的对象:p
Person p = new Person(){
@Override
public void eat() {
System.out.println("吃东西");
}
@Override
public void breath() {
System.out.println("好好呼吸");
}
};
method1(p);
System.out.println("********************");
//创建匿名子类的匿名对象
method1(new Person(){
@Override
public void eat() {
System.out.println("吃好吃东西");
}
@Override
public void breath() {
System.out.println("好好呼吸新鲜空气");
}
});
}
public static void method1(Person p){
p.eat();
p.breath();
}
public static void method(Student s){
}
}
class Worker extends Person{
@Override
public void eat() {
}
@Override
public void breath() {
}
}
package com.atguigu.java;
/*
- 抽象类的应用:模板方法的设计模式
*/
public class TemplateTest {
public static void main(String[] args) {
SubTemplate t = new SubTemplate();
t.spendTime();
}
}
abstract class Template{
//计算某段代码执行所需要花费的时间
public void spendTime(){
long start = System.currentTimeMillis();
this.code();//不确定的部分、易变的部分
long end = System.currentTimeMillis();
System.out.println("花费的时间为:" + (end - start));
}
public abstract void code();
}
class SubTemplate extends Template{
@Override
public void code() {
for(int i = 2;i <= 1000;i++){
boolean isFlag = true;
for(int j = 2;j <= Math.sqrt(i);j++){
if(i % j == 0){
isFlag = false;
break;
}
}
if(isFlag){
System.out.println(i);
}
}
}
}
package com.atguigu.java;
//抽象类的应用:模板方法的设计模式
public class TemplateMethodTest {
public static void main(String[] args) {
BankTemplateMethod btm = new DrawMoney();
btm.process();
BankTemplateMethod btm2 = new ManageMoney();
btm2.process();
}
}
abstract class BankTemplateMethod {
// 具体方法
public void takeNumber() {
System.out.println(“取号排队”);
}
public abstract void transact(); // 办理具体的业务 //钩子方法
public void evaluate() {
System.out.println("反馈评分");
}
// 模板方法,把基本操作组合到一起,子类一般不能重写
public final void process() {
this.takeNumber();
this.transact();// 像个钩子,具体执行时,挂哪个子类,就执行哪个子类的实现代码
this.evaluate();
}
}
class DrawMoney extends BankTemplateMethod {
public void transact() {
System.out.println(“我要取款!!!”);
}
}
class ManageMoney extends BankTemplateMethod {
public void transact() {
System.out.println(“我要理财!我这里有2000万美元!!”);
}
}
package com.atguigu.java1;
/*
- 接口的使用
- 1.接口使用interface来定义
- 2.Java中,接口和类是并列的两个结构
- 3.如何定义接口:定义接口中的成员
-
3.1 JDK7及以前:只能定义全局常量和抽象方法
-
>全局常量:public static final的.但是书写时,可以省略不写
-
>抽象方法:public abstract的
-
3.2 JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法(略)
-
- 接口中不能定义构造器的!意味着接口不可以实例化
-
- Java开发中,接口通过让类去实现(implements)的方式来使用.
- 如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化
- 如果实现类没有覆盖接口中所有的抽象方法,则此实现类仍为一个抽象类
-
- Java类可以实现多个接口 —>弥补了Java单继承性的局限性
- 格式:class AA extends BB implements CC,DD,EE
-
- 接口与接口之间可以继承,而且可以多继承
-
- 接口的具体使用,体现多态性
-
- 接口,实际上可以看做是一种规范
- 面试题:抽象类与接口有哪些异同?
*/
public class InterfaceTest {
public static void main(String[] args) {
System.out.println(Flyable.MAX_SPEED);
System.out.println(Flyable.MIN_SPEED);
// Flyable.MIN_SPEED = 2;
Plane plane = new Plane();
plane.fly();
}
}
interface Flyable{
//全局常量
public static final int MAX_SPEED = 7900;//第一宇宙速度
int MIN_SPEED = 1;//省略了public static final
//抽象方法
public abstract void fly();
//省略了public abstract
void stop();
//Interfaces cannot have constructors
// public Flyable(){
//
// }
}
interface Attackable{
void attack();
}
class Plane implements Flyable{
@Override
public void fly() {
System.out.println("通过引擎起飞");
}
@Override
public void stop() {
System.out.println("驾驶员减速停止");
}
}
abstract class Kite implements Flyable{
@Override
public void fly() {
}
}
class Bullet extends Object implements Flyable,Attackable,CC{
@Override
public void attack() {
// TODO Auto-generated method stub
}
@Override
public void fly() {
// TODO Auto-generated method stub
}
@Override
public void stop() {
// TODO Auto-generated method stub
}
@Override
public void method1() {
// TODO Auto-generated method stub
}
@Override
public void method2() {
// TODO Auto-generated method stub
}
}
//************************************
interface AA{
void method1();
}
interface BB{
void method2();
}
interface CC extends AA,BB{
}
package com.atguigu.java1;
/*
- 接口的使用
- 1.接口使用上也满足多态性
- 2.接口,实际上就是定义了一种规范
- 3.开发中,体会面向接口编程!
*/
public class USBTest {
public static void main(String[] args) {
Computer com = new Computer();
//1.创建了接口的非匿名实现类的非匿名对象
Flash flash = new Flash();
com.transferData(flash);
//2. 创建了接口的非匿名实现类的匿名对象
com.transferData(new Printer());
//3. 创建了接口的匿名实现类的非匿名对象
USB phone = new USB(){
@Override
public void start() {
System.out.println("手机开始工作");
}
@Override
public void stop() {
System.out.println("手机结束工作");
}
};
com.transferData(phone);
//4. 创建了接口的匿名实现类的匿名对象
com.transferData(new USB(){
@Override
public void start() {
System.out.println("mp3开始工作");
}
@Override
public void stop() {
System.out.println("mp3结束工作");
}
});
}
}
class Computer{
public void transferData(USB usb){//USB usb = new Flash();
usb.start();
System.out.println("具体传输数据的细节");
usb.stop();
}
}
interface USB{
//常量:定义了长、宽、最大最小的传输速度等
void start();
void stop();
}
class Flash implements USB{
@Override
public void start() {
System.out.println("U盘开启工作");
}
@Override
public void stop() {
System.out.println("U盘结束工作");
}
}
class Printer implements USB{
@Override
public void start() {
System.out.println(“打印机开启工作”);
}
@Override
public void stop() {
System.out.println("打印机结束工作");
}
}
package com.atguigu.java1;
public class StaticProxyTest {
public static void main(String[] args) {
Proxy s = new Proxy(new RealStar());
s.confer();
s.signContract();
s.bookTicket();
s.sing();
s.collectMoney();
}
}
interface Star {
void confer();// 面谈
void signContract();// 签合同
void bookTicket();// 订票
void sing();// 唱歌
void collectMoney();// 收钱
}
//被代理类
class RealStar implements Star {
public void confer() {
}
public void signContract() {
}
public void bookTicket() {
}
public void sing() {
System.out.println("明星:歌唱~~~");
}
public void collectMoney() {
}
}
//代理类
class Proxy implements Star {
private Star real;
public Proxy(Star real) {
this.real = real;
}
public void confer() {
System.out.println("经纪人面谈");
}
public void signContract() {
System.out.println("经纪人签合同");
}
public void bookTicket() {
System.out.println("经纪人订票");
}
public void sing() {
real.sing();
}
public void collectMoney() {
System.out.println("经纪人收钱");
}
}
package com.atguigu.java1;
/*
- 接口的应用:代理模式
*/
public class NetWorkTest {
public static void main(String[] args) {
Server server = new Server();
// server.browse();
ProxyServer proxyServer = new ProxyServer(server);
proxyServer.browse();
}
}
interface NetWork{
public void browse();
}
//被代理类
class Server implements NetWork{
@Override
public void browse() {
System.out.println("真实的服务器访问网络");
}
}
//代理类
class ProxyServer implements NetWork{
private NetWork work;
public ProxyServer(NetWork work){
this.work = work;
}
public void check(){
System.out.println("联网之前的检查工作");
}
@Override
public void browse() {
check();
work.browse();
}
}
package com.atguigu.java1;
interface A {
int x = 0;
}
class B {
int x = 1;
}
class C extends B implements A {
public void pX() {
//编译不通过。因为x是不明确的
// System.out.println(x);
System.out.println(super.x);//1
System.out.println(A.x);//0
}
public static void main(String[] args) {
new C().pX();
}
}
package com.atguigu.java2;
public class InnerClassTest1 {
//开发中很少见
public void method(){
//局部内部类
class AA{
}
}
//返回一个实现了Comparable接口的类的对象
public Comparable getComparable(){
//创建一个实现了Comparable接口的类:局部内部类
//方式一:
// class MyComparable implements Comparable{
//
// @Override
// public int compareTo(Object o) {
// return 0;
// }
//
// }
//
// return new MyComparable();
//方式二:
return new Comparable(){
@Override
public int compareTo(Object o) {
return 0;
}
};
}
}
package com.atguigu.java2;
/*
- 类的内部成员之五:内部类
-
- Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类
- 2.内部类的分类:成员内部类(静态、非静态) vs 局部内部类(方法内、代码块内、构造器内)
- 3.成员内部类:
-
一方面,作为外部类的成员:
-
>调用外部类的结构
-
>可以被static修饰
-
>可以被4种不同的权限修饰
-
另一方面,作为一个类:
-
> 类内可以定义属性、方法、构造器等
-
> 可以被final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承
-
> 可以被abstract修饰
- 4.关注如下的3个问题
- 4.1 如何实例化成员内部类的对象
- 4.2 如何在成员内部类中区分调用外部类的结构
- 4.3 开发中局部内部类的使用 见《InnerClassTest1.java》
*/
public class InnerClassTest {
public static void main(String[] args) {
//创建Dog实例(静态的成员内部类):
Person.Dog dog = new Person.Dog();
dog.show();
//创建Bird实例(非静态的成员内部类):
// Person.Bird bird = new Person.Bird();//错误的
Person p = new Person();
Person.Bird bird = p.new Bird();
bird.sing();
System.out.println();
bird.display("黄鹂");
}
}
class Person{
String name = "小明";
int age;
public void eat(){
System.out.println("人:吃饭");
}
//静态成员内部类
static class Dog{
String name;
int age;
public void show(){
System.out.println(“卡拉是条狗”);
// eat();
}
}
//非静态成员内部类
class Bird{
String name = “杜鹃”;
public Bird(){
}
public void sing(){
System.out.println(“我是一只小小鸟”);
Person.this.eat();//调用外部类的非静态属性
eat();
System.out.println(age);
}
public void display(String name){
System.out.println(name);//方法的形参
System.out.println(this.name);//内部类的属性
System.out.println(Person.this.name);//外部类的属性
}
}
public void method(){
//局部内部类
class AA{
}
}
{
//局部内部类
class BB{
}
}
public Person(){
//局部内部类
class CC{
}
}
}
package com.atguigu.java2;
/*
- 类的内部成员之五:内部类
-
- Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类
- 2.内部类的分类:成员内部类(静态、非静态) vs 局部内部类(方法内、代码块内、构造器内)
- 3.成员内部类:
-
一方面,作为外部类的成员:
-
>调用外部类的结构
-
>可以被static修饰
-
>可以被4种不同的权限修饰
-
另一方面,作为一个类:
-
> 类内可以定义属性、方法、构造器等
-
> 可以被final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承
-
> 可以被abstract修饰
- 4.关注如下的3个问题
- 4.1 如何实例化成员内部类的对象
- 4.2 如何在成员内部类中区分调用外部类的结构
- 4.3 开发中局部内部类的使用 见《InnerClassTest1.java》
*/
public class InnerClassTest {
public static void main(String[] args) {
//创建Dog实例(静态的成员内部类):
Person.Dog dog = new Person.Dog();
dog.show();
//创建Bird实例(非静态的成员内部类):
// Person.Bird bird = new Person.Bird();//错误的
Person p = new Person();
Person.Bird bird = p.new Bird();
bird.sing();
System.out.println();
bird.display("黄鹂");
}
}
class Person{
String name = "小明";
int age;
public void eat(){
System.out.println("人:吃饭");
}
//静态成员内部类
static class Dog{
String name;
int age;
public void show(){
System.out.println(“卡拉是条狗”);
// eat();
}
}
//非静态成员内部类
class Bird{
String name = “杜鹃”;
public Bird(){
}
public void sing(){
System.out.println(“我是一只小小鸟”);
Person.this.eat();//调用外部类的非静态属性
eat();
System.out.println(age);
}
public void display(String name){
System.out.println(name);//方法的形参
System.out.println(this.name);//内部类的属性
System.out.println(Person.this.name);//外部类的属性
}
}
public void method(){
//局部内部类
class AA{
}
}
{
//局部内部类
class BB{
}
}
public Person(){
//局部内部类
class CC{
}
}
}
package com.atguigu.java8;
public class SuperClass {
public void method3(){
System.out.println("SuperClass:北京");
}
}
package com.atguigu.java8;
public class SubClassTest {
public static void main(String[] args) {
SubClass s = new SubClass();
// s.method1();
// SubClass.method1();
//知识点1:接口中定义的静态方法,只能通过接口来调用。
CompareA.method1();
//知识点2:通过实现类的对象,可以调用接口中的默认方法。
//如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法
s.method2();
//知识点3:如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的默认方法,
//那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法。–>类优先原则
//知识点4:如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,
//那么在实现类没有重写此方法的情况下,报错。–>接口冲突。
//这就需要我们必须在实现类中重写此方法
s.method3();
}
}
class SubClass extends SuperClass implements CompareA,CompareB{
public void method2(){
System.out.println("SubClass:上海");
}
public void method3(){
System.out.println("SubClass:深圳");
}
//知识点5:如何在子类(或实现类)的方法中调用父类、接口中被重写的方法
public void myMethod(){
method3();//调用自己定义的重写的方法
super.method3();//调用的是父类中声明的
//调用接口中的默认方法
CompareA.super.method3();
CompareB.super.method3();
}
}
package com.atguigu.java8;
interface Filial {// 孝顺的
default void help() {
System.out.println(“老妈,我来救你了”);
}
}
interface Spoony {// 痴情的
default void help() {
System.out.println(“媳妇,别怕,我来了”);
}
}
class Father{
public void help(){
System.out.println(“儿子,就我媳妇!”);
}
}
class Man extends Father implements Filial, Spoony {
@Override
public void help() {
System.out.println("我该就谁呢?");
Filial.super.help();
Spoony.super.help();
}
}
package com.atguigu.java8;
public interface CompareB {
default void method3(){
System.out.println("CompareB:上海");
}
}
package com.atguigu.exer;
/*
*
- 定义一个测试类GeometricTest,
- 编写equalsArea方法测试两个对象的面积是否相等(注意方法的参数类型,利用动态绑定技术),
- 编写displayGeometricObject方法显示对象的面积(注意方法的参数类型,利用动态绑定技术)。
*/
public class GeometricTest {
public static void main(String[] args) {
GeometricTest test = new GeometricTest();
Circle c1 = new Circle(3.3, "white", 1.0);
test.displayGeometricObject(c1);
Circle c2 = new Circle(3.3, "white", 1.0);
test.displayGeometricObject(c2);
boolean isEquals = test.equalsArea(c1, c2);
System.out.println("c1 和 c2的面积是否相等:" + isEquals);
MyRectangle rect = new MyRectangle(2.1, 3.4, "red", 2.0);
test.displayGeometricObject(rect);
}
public void displayGeometricObject(GeometricObject o){//GeometricObject o = new Circle(...)
System.out.println("面积为:" + o.findArea());
}
//测试两个对象的面积是否相等
public boolean equalsArea(GeometricObject o1,GeometricObject o2){
return o1.findArea() == o2.findArea();
}
}
package com.atguigu.exer;
public class Circle extends GeometricObject {
private double radius;
public Circle(double radius,String color, double weight) {
super(color, weight);
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double findArea(){
return 3.14 * radius * radius;
}
}
package com.atguigu.exer;
public abstract class GeometricObject {//几何图形
protected String color;
protected double weight;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public GeometricObject(String color, double weight) {
super();
this.color = color;
this.weight = weight;
}
public abstract double findArea();
}
package com.atguigu.exer;
public class MyRectangle extends GeometricObject {
private double width;
private double height;
public MyRectangle(double width,double height,String color, double weight) {
super(color, weight);
this.width = width;
this.height = height;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
@Override
public double findArea() {
return width * height;
}
}
package com.atguigu.exer1;
/*
- 编写一个Employee类,声明为抽象类,
包含如下三个属性:name,id,salary。
提供必要的构造器和抽象方法:work()。
*/
public abstract class Employee {
private String name;
private int id;
private double salary;
public Employee() {
super();
}
public Employee(String name, int id, double salary) {
super();
this.name = name;
this.id = id;
this.salary = salary;
}
public abstract void work();
}
package com.atguigu.exer1;
/*
-
对于Manager类来说,他既是员工,还具有奖金(bonus)的属性。
*/
public class Manager extends Employee{private double bonus;//奖金
public Manager(double bonus) {
super();
this.bonus = bonus;
}public Manager(String name, int id, double salary, double bonus) {
super(name, id, salary);
this.bonus = bonus;
}@Override
public void work() {
System.out.println(“管理员工,提供公司运行的效率”);
}
}
package com.atguigu.exer1;
public class CommonEmployee extends Employee {
@Override
public void work() {
System.out.println("员工在一线车间生产产品");
}
}
package com.atguigu.exer1;
/*
-
请使用继承的思想,设计CommonEmployee类和Manager类,要求类中提供必要的方法进行属性访问。
*/
public class EmployeeTest {
public static void main(String[] args) {//多态 Employee manager = new Manager("库克", 1001, 5000, 50000); manager.work(); CommonEmployee commonEmployee = new CommonEmployee(); commonEmployee.work();
}
} -
package com.atguigu.exer2;
/*- MyDate类包含:
private成员变量year,month,day ;
toDateString()方法返回日期对应的字符串:xxxx年xx月xx日
*/
public class MyDate {
private int year;
private int month;
private int day;public MyDate(int year, int month, int day) {
super();
this.year = year;
this.month = month;
this.day = day;
}public int getYear() {
return year;
}public void setYear(int year) {
this.year = year;
}public int getMonth() {
return month;
}public void setMonth(int month) {
this.month = month;
}public int getDay() {
return day;
}public void setDay(int day) {
this.day = day;
}public String toDateString(){
return year + “年” + month + “月” + day + “日”;
}
} - MyDate类包含:
-
package com.atguigu.exer2;
/*-
定义一个Employee类,该类包含:
private成员变量name,number,birthday,其中birthday 为MyDate类的对象;
abstract方法earnings();
toString()方法输出对象的name,number和birthday。
*/
public abstract class Employee {
private String name;
private int number;
private MyDate birthday;public Employee(String name, int number, MyDate birthday) {
super();
this.name = name;
this.number = number;
this.birthday = birthday;
}public String getName() {
return name;
}public void setName(String name) {
this.name = name;
}public int getNumber() {
return number;
}public void setNumber(int number) {
this.number = number;
}public MyDate getBirthday() {
return birthday;
}public void setBirthday(MyDate birthday) {
this.birthday = birthday;
}public abstract double earnings();
@Override
public String toString() {
return “name=” + name + “, number=” + number + “, birthday=” + birthday.toDateString();
} -
}
package com.atguigu.exer2;
/*
- 参照SalariedEmployee类定义HourlyEmployee类,实现按小时计算工资的员工处理。该类包括:
private成员变量wage和hour;
实现父类的抽象方法earnings(),该方法返回wage*hour值;
toString()方法输出员工类型信息及员工的name,number,birthday。
*/
public class HourlyEmployee extends Employee{
private int wage;//每小时的工资
private int hour;//月工作的小时数
public HourlyEmployee(String name, int number, MyDate birthday) {
super(name, number, birthday);
}
public HourlyEmployee(String name, int number, MyDate birthday,int wage,int hour) {
super(name, number, birthday);
this.wage = wage;
this.hour = hour;
}
public int getWage() {
return wage;
}
public void setWage(int wage) {
this.wage = wage;
}
public int getHour() {
return hour;
}
public void setHour(int hour) {
this.hour = hour;
}
@Override
public double earnings() {
return wage * hour;
}
public String toString(){
return "HourlyEmployee[" + super.toString() + "]";
}
}
-
package com.atguigu.exer2;
/*-
定义SalariedEmployee类继承Employee类,
-
实现按月计算工资的员工处理。该类包括:private成员变量monthlySalary;
实现父类的抽象方法earnings(),该方法返回monthlySalary值;
toString()方法输出员工类型信息及员工的name,number,birthday。
*/
public class SalariedEmployee extends Employee{
private double monthlySalary;//月工资public SalariedEmployee(String name, int number, MyDate birthday) {
super(name, number, birthday);
}
public SalariedEmployee(String name, int number, MyDate birthday,double monthlySalary) {
super(name, number, birthday);
this.monthlySalary = monthlySalary;
}public double getMonthlySalary() {
return monthlySalary;
}public void setMonthlySalary(double monthlySalary) {
this.monthlySalary = monthlySalary;
}@Override
public double earnings() {
return monthlySalary;
}public String toString(){
return “SalariedEmployee[” + super.toString() + “]”;
}
} -
package com.atguigu.exer2;
import java.util.Calendar;
import java.util.Scanner;
/*
- 定义PayrollSystem类,创建Employee变量数组并初始化,该数组存放各类雇员对象的引用。
- 利用循环结构遍历数组元素,输出各个对象的类型,name,number,birthday。
- 当键盘输入本月月份值时,如果本月是某个Employee对象的生日,还要输出增加工资信息。
*/
public class PayrollSystem {
public static void main(String[] args) {
//方式一:
// Scanner scanner = new Scanner(System.in);
// System.out.println(“请输入当月的月份:”);
// int month = scanner.nextInt();
//方式二:
Calendar calendar = Calendar.getInstance();
int month = calendar.get(Calendar.MONTH);//获取当前的月份
// System.out.println(month);//一月份:0
Employee[] emps = new Employee[2];
emps[0] = new SalariedEmployee("马森", 1002,new MyDate(1992, 2, 28),10000);
emps[1] = new HourlyEmployee("潘雨生", 2001, new MyDate(1991, 1, 6),60,240);
for(int i = 0;i < emps.length;i++){
System.out.println(emps[i]);
double salary = emps[i].earnings();
System.out.println("月工资为:" + salary);
if((month+1) == emps[i].getBirthday().getMonth()){
System.out.println("生日快乐!奖励100元");
}
}
}
}
package com.atguigu.exer3;
/*
-
interface CompareObject{
public int compareTo(Object o);
//若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小
}
*/
public interface CompareObject {
//若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小
public int compareTo(Object o);
}
package com.atguigu.exer3;
/*
- 定义一个Circle类,声明radius属性,提供getter和setter方法
*/
public class Circle {
private Double radius;
public Double getRadius() {
return radius;
}
public void setRadius(Double radius) {
this.radius = radius;
}
public Circle() {
super();
}
public Circle(Double radius) {
super();
this.radius = radius;
}
}
package com.atguigu.exer3;
public class ComparableCircleTest {
public static void main(String[] args) {
ComparableCircle c1 = new ComparableCircle(3.4);
ComparableCircle c2 = new ComparableCircle(3.6);
int compareValue = c1.compareTo(c2);
if(compareValue > 0){
System.out.println("c1对象大");
}else if(compareValue < 0){
System.out.println("c2对象大");
}else{
System.out.println("c1与c2一样大");
}
int compareValue1 = c1.compareTo(new String(“AA”));
System.out.println(compareValue1);
}
}
package com.atguigu.exer3;
/*
- 定义一个ComparableCircle类,继承Circle类并且实现CompareObject接口。
- 在ComparableCircle类中给出接口中方法compareTo的实现体,用来比较两个圆的半径大小。
*/
public class ComparableCircle extends Circle implements CompareObject{
public ComparableCircle(double radius) {
super(radius);
}
@Override
public int compareTo(Object o) {
if(this == o){
return 0;
}
if(o instanceof ComparableCircle){
ComparableCircle c = (ComparableCircle)o;
//错误的:
// return (int) (this.getRadius() - c.getRadius());
//正确的方式一:
// if(this.getRadius() > c.getRadius()){
// return 1;
// }else if(this.getRadius() < c.getRadius()){
// return -1;
// }else{
// return 0;
// }
//当属性radius声明为Double类型时,可以调用包装类的方法
//正确的方式二:
return this.getRadius().compareTo(c.getRadius());
}else{
// return 0;
throw new RuntimeException(“传入的数据类型不匹配”);
}
}
}
第十五天:
package com.atguigu.exer;
public abstract class GeometricObject {//几何图形
protected String color;
protected double weight;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public GeometricObject(String color, double weight) {
super();
this.color = color;
this.weight = weight;
}
public abstract double findArea();
}
package com.atguigu.exer;
/*
*
- 定义一个测试类GeometricTest,
- 编写equalsArea方法测试两个对象的面积是否相等(注意方法的参数类型,利用动态绑定技术),
- 编写displayGeometricObject方法显示对象的面积(注意方法的参数类型,利用动态绑定技术)。
*/
public class GeometricTest {
public static void main(String[] args) {
GeometricTest test = new GeometricTest();
Circle c1 = new Circle(3.3, "white", 1.0);
test.displayGeometricObject(c1);
Circle c2 = new Circle(3.3, "white", 1.0);
test.displayGeometricObject(c2);
boolean isEquals = test.equalsArea(c1, c2);
System.out.println("c1 和 c2的面积是否相等:" + isEquals);
MyRectangle rect = new MyRectangle(2.1, 3.4, "red", 2.0);
test.displayGeometricObject(rect);
}
public void displayGeometricObject(GeometricObject o){//GeometricObject o = new Circle(...)
System.out.println("面积为:" + o.findArea());
}
//测试两个对象的面积是否相等
public boolean equalsArea(GeometricObject o1,GeometricObject o2){
return o1.findArea() == o2.findArea();
}
}
package com.atguigu.exer;
public class Circle extends GeometricObject {
private double radius;
public Circle(double radius,String color, double weight) {
super(color, weight);
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double findArea(){
return 3.14 * radius * radius;
}
}
package com.atguigu.exer;
public class MyRectangle extends GeometricObject {
private double width;
private double height;
public MyRectangle(double width,double height,String color, double weight) {
super(color, weight);
this.width = width;
this.height = height;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
@Override
public double findArea() {
return width * height;
}
}
package com.atguigu.exer1;
/*
- 编写一个Employee类,声明为抽象类,
包含如下三个属性:name,id,salary。
提供必要的构造器和抽象方法:work()。
*/
public abstract class Employee {
private String name;
private int id;
private double salary;
public Employee() {
super();
}
public Employee(String name, int id, double salary) {
super();
this.name = name;
this.id = id;
this.salary = salary;
}
public abstract void work();
}
-
package com.atguigu.exer1;
/*-
对于Manager类来说,他既是员工,还具有奖金(bonus)的属性。
*/
public class Manager extends Employee{private double bonus;//奖金
public Manager(double bonus) {
super();
this.bonus = bonus;
}public Manager(String name, int id, double salary, double bonus) {
super(name, id, salary);
this.bonus = bonus;
}@Override
public void work() {
System.out.println(“管理员工,提供公司运行的效率”);
}
}
-
package com.atguigu.exer1;
public class CommonEmployee extends Employee {
@Override
public void work() {
System.out.println("员工在一线车间生产产品");
}
}
package com.atguigu.exer1;
/*
-
请使用继承的思想,设计CommonEmployee类和Manager类,要求类中提供必要的方法进行属性访问。
*/
public class EmployeeTest {
public static void main(String[] args) {//多态 Employee manager = new Manager("库克", 1001, 5000, 50000); manager.work(); CommonEmployee commonEmployee = new CommonEmployee(); commonEmployee.work();
}
}
package com.atguigu.exer2;
/*
- MyDate类包含:
private成员变量year,month,day ;
toDateString()方法返回日期对应的字符串:xxxx年xx月xx日
*/
public class MyDate {
private int year;
private int month;
private int day;
public MyDate(int year, int month, int day) {
super();
this.year = year;
this.month = month;
this.day = day;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public String toDateString(){
return year + "年" + month + "月" + day + "日";
}
}
package com.atguigu.exer2;
/*
- MyDate类包含:
private成员变量year,month,day ;
toDateString()方法返回日期对应的字符串:xxxx年xx月xx日
*/
public class MyDate {
private int year;
private int month;
private int day;
public MyDate(int year, int month, int day) {
super();
this.year = year;
this.month = month;
this.day = day;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public String toDateString(){
return year + "年" + month + "月" + day + "日";
}
}
package com.atguigu.exer2;
/*
- 参照SalariedEmployee类定义HourlyEmployee类,实现按小时计算工资的员工处理。该类包括:
private成员变量wage和hour;
实现父类的抽象方法earnings(),该方法返回wage*hour值;
toString()方法输出员工类型信息及员工的name,number,birthday。
*/
public class HourlyEmployee extends Employee{
private int wage;//每小时的工资
private int hour;//月工作的小时数
public HourlyEmployee(String name, int number, MyDate birthday) {
super(name, number, birthday);
}
public HourlyEmployee(String name, int number, MyDate birthday,int wage,int hour) {
super(name, number, birthday);
this.wage = wage;
this.hour = hour;
}
public int getWage() {
return wage;
}
public void setWage(int wage) {
this.wage = wage;
}
public int getHour() {
return hour;
}
public void setHour(int hour) {
this.hour = hour;
}
@Override
public double earnings() {
return wage * hour;
}
public String toString(){
return "HourlyEmployee[" + super.toString() + "]";
}
}
package com.atguigu.exer2;
/*
-
定义SalariedEmployee类继承Employee类,
-
实现按月计算工资的员工处理。该类包括:private成员变量monthlySalary;
实现父类的抽象方法earnings(),该方法返回monthlySalary值;
toString()方法输出员工类型信息及员工的name,number,birthday。
*/
public class SalariedEmployee extends Employee{
private double monthlySalary;//月工资public SalariedEmployee(String name, int number, MyDate birthday) {
super(name, number, birthday);
}
public SalariedEmployee(String name, int number, MyDate birthday,double monthlySalary) {
super(name, number, birthday);
this.monthlySalary = monthlySalary;
}public double getMonthlySalary() {
return monthlySalary;
}public void setMonthlySalary(double monthlySalary) {
this.monthlySalary = monthlySalary;
}@Override
public double earnings() {
return monthlySalary;
}public String toString(){
return “SalariedEmployee[” + super.toString() + “]”;
}
}
package com.atguigu.exer2;
import java.util.Calendar;
import java.util.Scanner;
/*
- 定义PayrollSystem类,创建Employee变量数组并初始化,该数组存放各类雇员对象的引用。
- 利用循环结构遍历数组元素,输出各个对象的类型,name,number,birthday。
- 当键盘输入本月月份值时,如果本月是某个Employee对象的生日,还要输出增加工资信息。
*/
public class PayrollSystem {
public static void main(String[] args) {
//方式一:
// Scanner scanner = new Scanner(System.in);
// System.out.println(“请输入当月的月份:”);
// int month = scanner.nextInt();
//方式二:
Calendar calendar = Calendar.getInstance();
int month = calendar.get(Calendar.MONTH);//获取当前的月份
// System.out.println(month);//一月份:0
Employee[] emps = new Employee[2];
emps[0] = new SalariedEmployee("马森", 1002,new MyDate(1992, 2, 28),10000);
emps[1] = new HourlyEmployee("潘雨生", 2001, new MyDate(1991, 1, 6),60,240);
for(int i = 0;i < emps.length;i++){
System.out.println(emps[i]);
double salary = emps[i].earnings();
System.out.println("月工资为:" + salary);
if((month+1) == emps[i].getBirthday().getMonth()){
System.out.println("生日快乐!奖励100元");
}
}
}
}
package com.atguigu.exer3;
/*
- interface CompareObject{
public int compareTo(Object o);
//若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小
}
*/
public interface CompareObject {
//若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小
public int compareTo(Object o);
}
package com.atguigu.exer3;
/*
- 定义一个Circle类,声明radius属性,提供getter和setter方法
*/
public class Circle {
private Double radius;
public Double getRadius() {
return radius;
}
public void setRadius(Double radius) {
this.radius = radius;
}
public Circle() {
super();
}
public Circle(Double radius) {
super();
this.radius = radius;
}
}
package com.atguigu.exer3;
public class ComparableCircleTest {
public static void main(String[] args) {
ComparableCircle c1 = new ComparableCircle(3.4);
ComparableCircle c2 = new ComparableCircle(3.6);
int compareValue = c1.compareTo(c2);
if(compareValue > 0){
System.out.println("c1对象大");
}else if(compareValue < 0){
System.out.println("c2对象大");
}else{
System.out.println("c1与c2一样大");
}
int compareValue1 = c1.compareTo(new String(“AA”));
System.out.println(compareValue1);
}
}
package com.atguigu.exer3;
/*
- 定义一个ComparableCircle类,继承Circle类并且实现CompareObject接口。
- 在ComparableCircle类中给出接口中方法compareTo的实现体,用来比较两个圆的半径大小。
*/
public class ComparableCircle extends Circle implements CompareObject{
public ComparableCircle(double radius) {
super(radius);
}
@Override
public int compareTo(Object o) {
if(this == o){
return 0;
}
if(o instanceof ComparableCircle){
ComparableCircle c = (ComparableCircle)o;
//错误的:
// return (int) (this.getRadius() - c.getRadius());
//正确的方式一:
// if(this.getRadius() > c.getRadius()){
// return 1;
// }else if(this.getRadius() < c.getRadius()){
// return -1;
// }else{
// return 0;
// }
//当属性radius声明为Double类型时,可以调用包装类的方法
//正确的方式二:
return this.getRadius().compareTo(c.getRadius());
}else{
// return 0;
throw new RuntimeException(“传入的数据类型不匹配”);
}
}
}
package com.atguigu.java;
public class SingletonTest {
public static void main(String[] args) {
Bank bank1 = Bank.instance;
// Bank.instance = null;
Bank bank2 = Bank.instance;
System.out.println(bank1 == bank2);
}
}
class Bank{
private Bank(){
}
public static final Bank instance = new Bank();
}
package com.atguigu.java;
/*
- abstract使用上的注意点:
- 1.abstract不能用来修饰:属性、构造器等结构
- 2.abstract不能用来修饰私有方法、静态方法、final的方法、final的类
*/
public class AbstractTest1 {
}
package com.atguigu.java;
/*
- abstract关键字的使用
- 1.abstract:抽象的
- 2.abstract可以用来修饰的结构:类、方法
-
- abstract修饰类:抽象类
-
> 此类不能实例化
-
> 抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化的全过程)
-
> 开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作
-
- abstract修饰方法:抽象方法
-
> 抽象方法只有方法的声明,没有方法体
-
> 包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法的。
-
> 若子类重写了父类中的所有的抽象方法后,此子类方可实例化
-
若子类没有重写父类中的所有的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰
*/
public class AbstractTest {
public static void main(String[] args) {
//一旦Person类抽象了,就不可实例化
// Person p1 = new Person();
// p1.eat();
}
}
abstract class Creature{
public abstract void breath();
}
abstract class Person extends Creature{
String name;
int age;
public Person(){
}
public Person(String name,int age){
this.name = name;
this.age = age;
}
//不是抽象方法:
// public void eat(){
//
// }
//抽象方法
public abstract void eat();
public void walk(){
System.out.println("人走路");
}
}
class Student extends Person{
public Student(String name,int age){
super(name,age);
}
public Student(){
}
public void eat(){
System.out.println("学生多吃有营养的食物");
}
@Override
public void breath() {
System.out.println("学生应该呼吸新鲜的没有雾霾的空气");
}
}
package com.atguigu.java;
/*
- 抽象类的匿名子类
*/
public class PersonTest {
public static void main(String[] args) {
method(new Student());//匿名对象
Worker worker = new Worker();
method1(worker);//非匿名的类非匿名的对象
method1(new Worker());//非匿名的类匿名的对象
System.out.println("********************");
//创建了一匿名子类的对象:p
Person p = new Person(){
@Override
public void eat() {
System.out.println("吃东西");
}
@Override
public void breath() {
System.out.println("好好呼吸");
}
};
method1(p);
System.out.println("********************");
//创建匿名子类的匿名对象
method1(new Person(){
@Override
public void eat() {
System.out.println("吃好吃东西");
}
@Override
public void breath() {
System.out.println("好好呼吸新鲜空气");
}
});
}
public static void method1(Person p){
p.eat();
p.breath();
}
public static void method(Student s){
}
}
class Worker extends Person{
@Override
public void eat() {
}
@Override
public void breath() {
}
}
package com.atguigu.java;
/*
- 抽象类的应用:模板方法的设计模式
*/
public class TemplateTest {
public static void main(String[] args) {
SubTemplate t = new SubTemplate();
t.spendTime();
}
}
abstract class Template{
//计算某段代码执行所需要花费的时间
public void spendTime(){
long start = System.currentTimeMillis();
this.code();//不确定的部分、易变的部分
long end = System.currentTimeMillis();
System.out.println("花费的时间为:" + (end - start));
}
public abstract void code();
}
class SubTemplate extends Template{
@Override
public void code() {
for(int i = 2;i <= 1000;i++){
boolean isFlag = true;
for(int j = 2;j <= Math.sqrt(i);j++){
if(i % j == 0){
isFlag = false;
break;
}
}
if(isFlag){
System.out.println(i);
}
}
}
}
package com.atguigu.java;
//抽象类的应用:模板方法的设计模式
public class TemplateMethodTest {
public static void main(String[] args) {
BankTemplateMethod btm = new DrawMoney();
btm.process();
BankTemplateMethod btm2 = new ManageMoney();
btm2.process();
}
}
abstract class BankTemplateMethod {
// 具体方法
public void takeNumber() {
System.out.println(“取号排队”);
}
public abstract void transact(); // 办理具体的业务 //钩子方法
public void evaluate() {
System.out.println("反馈评分");
}
// 模板方法,把基本操作组合到一起,子类一般不能重写
public final void process() {
this.takeNumber();
this.transact();// 像个钩子,具体执行时,挂哪个子类,就执行哪个子类的实现代码
this.evaluate();
}
}
class DrawMoney extends BankTemplateMethod {
public void transact() {
System.out.println(“我要取款!!!”);
}
}
class ManageMoney extends BankTemplateMethod {
public void transact() {
System.out.println(“我要理财!我这里有2000万美元!!”);
}
}
package com.atguigu.java1;
/*
- 接口的使用
- 1.接口使用interface来定义
- 2.Java中,接口和类是并列的两个结构
- 3.如何定义接口:定义接口中的成员
-
3.1 JDK7及以前:只能定义全局常量和抽象方法
-
>全局常量:public static final的.但是书写时,可以省略不写
-
>抽象方法:public abstract的
-
3.2 JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法(略)
-
- 接口中不能定义构造器的!意味着接口不可以实例化
-
- Java开发中,接口通过让类去实现(implements)的方式来使用.
- 如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化
- 如果实现类没有覆盖接口中所有的抽象方法,则此实现类仍为一个抽象类
-
- Java类可以实现多个接口 —>弥补了Java单继承性的局限性
- 格式:class AA extends BB implements CC,DD,EE
-
- 接口与接口之间可以继承,而且可以多继承
-
- 接口的具体使用,体现多态性
-
- 接口,实际上可以看做是一种规范
- 面试题:抽象类与接口有哪些异同?
*/
public class InterfaceTest {
public static void main(String[] args) {
System.out.println(Flyable.MAX_SPEED);
System.out.println(Flyable.MIN_SPEED);
// Flyable.MIN_SPEED = 2;
Plane plane = new Plane();
plane.fly();
}
}
interface Flyable{
//全局常量
public static final int MAX_SPEED = 7900;//第一宇宙速度
int MIN_SPEED = 1;//省略了public static final
//抽象方法
public abstract void fly();
//省略了public abstract
void stop();
//Interfaces cannot have constructors
// public Flyable(){
//
// }
}
interface Attackable{
void attack();
}
class Plane implements Flyable{
@Override
public void fly() {
System.out.println("通过引擎起飞");
}
@Override
public void stop() {
System.out.println("驾驶员减速停止");
}
}
abstract class Kite implements Flyable{
@Override
public void fly() {
}
}
class Bullet extends Object implements Flyable,Attackable,CC{
@Override
public void attack() {
// TODO Auto-generated method stub
}
@Override
public void fly() {
// TODO Auto-generated method stub
}
@Override
public void stop() {
// TODO Auto-generated method stub
}
@Override
public void method1() {
// TODO Auto-generated method stub
}
@Override
public void method2() {
// TODO Auto-generated method stub
}
}
//************************************
interface AA{
void method1();
}
interface BB{
void method2();
}
interface CC extends AA,BB{
}
package com.atguigu.java1;
/*
- 接口的使用
- 1.接口使用上也满足多态性
- 2.接口,实际上就是定义了一种规范
- 3.开发中,体会面向接口编程!
*/
public class USBTest {
public static void main(String[] args) {
Computer com = new Computer();
//1.创建了接口的非匿名实现类的非匿名对象
Flash flash = new Flash();
com.transferData(flash);
//2. 创建了接口的非匿名实现类的匿名对象
com.transferData(new Printer());
//3. 创建了接口的匿名实现类的非匿名对象
USB phone = new USB(){
@Override
public void start() {
System.out.println("手机开始工作");
}
@Override
public void stop() {
System.out.println("手机结束工作");
}
};
com.transferData(phone);
//4. 创建了接口的匿名实现类的匿名对象
com.transferData(new USB(){
@Override
public void start() {
System.out.println("mp3开始工作");
}
@Override
public void stop() {
System.out.println("mp3结束工作");
}
});
}
}
class Computer{
public void transferData(USB usb){//USB usb = new Flash();
usb.start();
System.out.println("具体传输数据的细节");
usb.stop();
}
}
interface USB{
//常量:定义了长、宽、最大最小的传输速度等
void start();
void stop();
}
class Flash implements USB{
@Override
public void start() {
System.out.println("U盘开启工作");
}
@Override
public void stop() {
System.out.println("U盘结束工作");
}
}
class Printer implements USB{
@Override
public void start() {
System.out.println(“打印机开启工作”);
}
@Override
public void stop() {
System.out.println("打印机结束工作");
}
}
package com.atguigu.java1;
/*
- 接口的应用:代理模式
*/
public class NetWorkTest {
public static void main(String[] args) {
Server server = new Server();
// server.browse();
ProxyServer proxyServer = new ProxyServer(server);
proxyServer.browse();
}
}
interface NetWork{
public void browse();
}
//被代理类
class Server implements NetWork{
@Override
public void browse() {
System.out.println("真实的服务器访问网络");
}
}
//代理类
class ProxyServer implements NetWork{
private NetWork work;
public ProxyServer(NetWork work){
this.work = work;
}
public void check(){
System.out.println("联网之前的检查工作");
}
@Override
public void browse() {
check();
work.browse();
}
}
package com.atguigu.java1;
public class StaticProxyTest {
public static void main(String[] args) {
Proxy s = new Proxy(new RealStar());
s.confer();
s.signContract();
s.bookTicket();
s.sing();
s.collectMoney();
}
}
interface Star {
void confer();// 面谈
void signContract();// 签合同
void bookTicket();// 订票
void sing();// 唱歌
void collectMoney();// 收钱
}
//被代理类
class RealStar implements Star {
public void confer() {
}
public void signContract() {
}
public void bookTicket() {
}
public void sing() {
System.out.println("明星:歌唱~~~");
}
public void collectMoney() {
}
}
//代理类
class Proxy implements Star {
private Star real;
public Proxy(Star real) {
this.real = real;
}
public void confer() {
System.out.println("经纪人面谈");
}
public void signContract() {
System.out.println("经纪人签合同");
}
public void bookTicket() {
System.out.println("经纪人订票");
}
public void sing() {
real.sing();
}
public void collectMoney() {
System.out.println("经纪人收钱");
}
}
package com.atguigu.java1;
interface A {
int x = 0;
}
class B {
int x = 1;
}
class C extends B implements A {
public void pX() {
//编译不通过。因为x是不明确的
// System.out.println(x);
System.out.println(super.x);//1
System.out.println(A.x);//0
}
public static void main(String[] args) {
new C().pX();
}
}
package com.atguigu.java2;
public class InnerClassTest1 {
//开发中很少见
public void method(){
//局部内部类
class AA{
}
}
//返回一个实现了Comparable接口的类的对象
public Comparable getComparable(){
//创建一个实现了Comparable接口的类:局部内部类
//方式一:
// class MyComparable implements Comparable{
//
// @Override
// public int compareTo(Object o) {
// return 0;
// }
//
// }
//
// return new MyComparable();
//方式二:
return new Comparable(){
@Override
public int compareTo(Object o) {
return 0;
}
};
}
}
package com.atguigu.java2;
/*
- 类的内部成员之五:内部类
-
- Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类
- 2.内部类的分类:成员内部类(静态、非静态) vs 局部内部类(方法内、代码块内、构造器内)
- 3.成员内部类:
-
一方面,作为外部类的成员:
-
>调用外部类的结构
-
>可以被static修饰
-
>可以被4种不同的权限修饰
-
另一方面,作为一个类:
-
> 类内可以定义属性、方法、构造器等
-
> 可以被final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承
-
> 可以被abstract修饰
- 4.关注如下的3个问题
- 4.1 如何实例化成员内部类的对象
- 4.2 如何在成员内部类中区分调用外部类的结构
- 4.3 开发中局部内部类的使用 见《InnerClassTest1.java》
*/
public class InnerClassTest {
public static void main(String[] args) {
//创建Dog实例(静态的成员内部类):
Person.Dog dog = new Person.Dog();
dog.show();
//创建Bird实例(非静态的成员内部类):
// Person.Bird bird = new Person.Bird();//错误的
Person p = new Person();
Person.Bird bird = p.new Bird();
bird.sing();
System.out.println();
bird.display("黄鹂");
}
}
class Person{
String name = "小明";
int age;
public void eat(){
System.out.println("人:吃饭");
}
//静态成员内部类
static class Dog{
String name;
int age;
public void show(){
System.out.println(“卡拉是条狗”);
// eat();
}
}
//非静态成员内部类
class Bird{
String name = “杜鹃”;
public Bird(){
}
public void sing(){
System.out.println("我是一只小小鸟");
Person.this.eat();//调用外部类的非静态属性
eat();
System.out.println(age);
}
public void display(String name){
System.out.println(name);//方法的形参
System.out.println(this.name);//内部类的属性
System.out.println(Person.this.name);//外部类的属性
}
}
public void method(){
//局部内部类
class AA{
}
}
{
//局部内部类
class BB{
}
}
public Person(){
//局部内部类
class CC{
}
}
}
package com.atguigu.java8;
/*
*
- JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法
*/
public interface CompareA {
//静态方法
public static void method1(){
System.out.println("CompareA:北京");
}
//默认方法
public default void method2(){
System.out.println("CompareA:上海");
}
default void method3(){
System.out.println("CompareA:上海");
}
}
package com.atguigu.java8;
public class SuperClass {
public void method3(){
System.out.println("SuperClass:北京");
}
}
package com.atguigu.java8;
public class SubClassTest {
public static void main(String[] args) {
SubClass s = new SubClass();
// s.method1();
// SubClass.method1();
//知识点1:接口中定义的静态方法,只能通过接口来调用。
CompareA.method1();
//知识点2:通过实现类的对象,可以调用接口中的默认方法。
//如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法
s.method2();
//知识点3:如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的默认方法,
//那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法。–>类优先原则
//知识点4:如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,
//那么在实现类没有重写此方法的情况下,报错。–>接口冲突。
//这就需要我们必须在实现类中重写此方法
s.method3();
}
}
class SubClass extends SuperClass implements CompareA,CompareB{
public void method2(){
System.out.println("SubClass:上海");
}
public void method3(){
System.out.println("SubClass:深圳");
}
//知识点5:如何在子类(或实现类)的方法中调用父类、接口中被重写的方法
public void myMethod(){
method3();//调用自己定义的重写的方法
super.method3();//调用的是父类中声明的
//调用接口中的默认方法
CompareA.super.method3();
CompareB.super.method3();
}
}
- package com.atguigu.java8;
interface Filial {// 孝顺的
default void help() {
System.out.println(“老妈,我来救你了”);
}
}
interface Spoony {// 痴情的
default void help() {
System.out.println("媳妇,别怕,我来了");
}
}
class Father{
public void help(){
System.out.println("儿子,就我媳妇!");
}
}
class Man extends Father implements Filial, Spoony {
@Override
public void help() {
System.out.println("我该就谁呢?");
Filial.super.help();
Spoony.super.help();
}
}
package com.atguigu.java8;
public interface CompareB {
default void method3(){
System.out.println("CompareB:上海");
}
}
package com.atguigu.exer;
//自定义异常类
public class EcDef extends Exception {
static final long serialVersionUID = -33875164229948L;
public EcDef() {
}
public EcDef(String msg) {
super(msg);
}
}
package com.atguigu.exer;
/*
* 编写应用程序EcmDef.java,接收命令行的两个参数,要求不能输入负数,计算两数相除。
对数据类型不一致(NumberFormatException)、缺少命令行参数(ArrayIndexOutOfBoundsException、
除0(ArithmeticException)及输入负数(EcDef 自定义的异常)进行异常处理。
提示:
(1)在主类(EcmDef)中定义异常方法(ecm)完成两数相除功能。
(2)在main()方法中使用异常处理语句进行异常处理。
(3)在程序中,自定义对应输入负数的异常类(EcDef)。
(4)运行时接受参数 java EcmDef 20 10 //args[0]=“20” args[1]=“10”
(5)Interger类的static方法parseInt(String s)将s转换成对应的int值。
如:int a=Interger.parseInt(“314”); //a=314;
*/
public class EcmDef {
public static void main(String[] args) {
try{
int i = Integer.parseInt(args[0]);
int j = Integer.parseInt(args[1]);
int result = ecm(i,j);
System.out.println(result);
}catch(NumberFormatException e){
System.out.println("数据类型不一致");
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("缺少命令行参数");
}catch(ArithmeticException e){
System.out.println("除0");
}catch(EcDef e){
System.out.println(e.getMessage());
}
}
public static int ecm(int i,int j) throws EcDef{
if(i < 0 || j < 0){
throw new EcDef("分子或分母为负数了!");
}
return i / j;
}
}
package 下学期;
package com.atguigu.java;
/*
* Error:
* Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。比如:StackOverflowError和OOM。
*
* 一般不编写针对性的代码进行处理。
*
*
*/
public class ErrorTest {
public static void main(String[] args) {
//1.栈溢出:java.lang.StackOverflowError
// main(args);
//2.堆溢出:java.lang.OutOfMemoryError
Integer[] arr = new Integer[1024*1024*1024];
}
}
package com.atguigu.java;
public class InnerClassTest {
// public void onCreate(){
//
// int number = 10;
//
// View.OnClickListern listener = new View.OnClickListener(){
//
// public void onClick(){
// System.out.println("hello!");
// System.out.println(number);
// }
//
// }
//
// button.setOnClickListener(listener);
//
// }
/*
* 在局部内部类的方法中(比如:show)如果调用局部内部类所声明的方法(比如:method)中的局部变量(比如:num)的话,
* 要求此局部变量声明为final的。
*
* jdk 7及之前版本:要求此局部变量显式的声明为final的
* jdk 8及之后的版本:可以省略final的声明
*
*/
public void method(){
//局部变量
int num = 10;
class AA{
public void show(){
// num = 20;
System.out.println(num);
}
}
}
}
package com.atguigu.java1;
import java.io.File;
import java.io.FileInputStream;
import java.util.Date;
import java.util.Scanner;
import org.junit.Test;
/*
* 一、异常体系结构
*
* java.lang.Throwable
* |-----java.lang.Error:一般不编写针对性的代码进行处理。
* |-----java.lang.Exception:可以进行异常的处理
* |------编译时异常(checked)
* |-----IOException
* |-----FileNotFoundException
* |-----ClassNotFoundException
* |------运行时异常(unchecked,RuntimeException)
* |-----NullPointerException
* |-----ArrayIndexOutOfBoundsException
* |-----ClassCastException
* |-----NumberFormatException
* |-----InputMismatchException
* |-----ArithmeticException
*
*
*
* 面试题:常见的异常都有哪些?举例说明
*/
public class ExceptionTest {
//******************以下是编译时异常***************************
@Test
public void test7(){
// File file = new File("hello.txt");
// FileInputStream fis = new FileInputStream(file);
//
// int data = fis.read();
// while(data != -1){
// System.out.print((char)data);
// data = fis.read();
// }
//
// fis.close();
}
//******************以下是运行时异常***************************
//ArithmeticException
@Test
public void test6(){
int a = 10;
int b = 0;
System.out.println(a / b);
}
//InputMismatchException
@Test
public void test5(){
Scanner scanner = new Scanner(System.in);
int score = scanner.nextInt();
System.out.println(score);
scanner.close();
}
//NumberFormatException
@Test
public void test4(){
String str = "123";
str = "abc";
int num = Integer.parseInt(str);
}
//ClassCastException
@Test
public void test3(){
Object obj = new Date();
String str = (String)obj;
}
//IndexOutOfBoundsException
@Test
public void test2(){
//ArrayIndexOutOfBoundsException
// int[] arr = new int[10];
// System.out.println(arr[10]);
//StringIndexOutOfBoundsException
String str = "abc";
System.out.println(str.charAt(3));
}
//NullPointerException
@Test
public void test1(){
// int[] arr = null;
// System.out.println(arr[3]);
String str = "abc";
str = null;
System.out.println(str.charAt(0));
}
}
package com.atguigu.java1;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.junit.Test;
/*
* 一、异常的处理:抓抛模型
*
* 过程一:"抛":程序在正常执行的过程中,一旦出现异常,就会在异常代码处生成一个对应异常类的对象。
* 并将此对象抛出。
* 一旦抛出对象以后,其后的代码就不再执行。
*
* 关于异常对象的产生:① 系统自动生成的异常对象
* ② 手动的生成一个异常对象,并抛出(throw)
*
* 过程二:"抓":可以理解为异常的处理方式:① try-catch-finally ② throws
*
*
* 二、try-catch-finally的使用
*
* try{
* //可能出现异常的代码
*
* }catch(异常类型1 变量名1){
* //处理异常的方式1
* }catch(异常类型2 变量名2){
* //处理异常的方式2
* }catch(异常类型3 变量名3){
* //处理异常的方式3
* }
* ....
* finally{
* //一定会执行的代码
* }
*
* 说明:
* 1. finally是可选的。
* 2. 使用try将可能出现异常代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,根据此对象
* 的类型,去catch中进行匹配
* 3. 一旦try中的异常对象匹配到某一个catch时,就进入catch中进行异常的处理。一旦处理完成,就跳出当前的
* try-catch结构(在没有写finally的情况)。继续执行其后的代码
* 4. catch中的异常类型如果没有子父类关系,则谁声明在上,谁声明在下无所谓。
* catch中的异常类型如果满足子父类关系,则要求子类一定声明在父类的上面。否则,报错
* 5. 常用的异常对象处理的方式: ① String getMessage() ② printStackTrace()
* 6. 在try结构中声明的变量,再出了try结构以后,就不能再被调用
* 7. try-catch-finally结构可以嵌套
*
* 体会1:使用try-catch-finally处理编译时异常,是得程序在编译时就不再报错,但是运行时仍可能报错。
* 相当于我们使用try-catch-finally将一个编译时可能出现的异常,延迟到运行时出现。
*
* 体会2:开发中,由于运行时异常比较常见,所以我们通常就不针对运行时异常编写try-catch-finally了。
* 针对于编译时异常,我们说一定要考虑异常的处理。
*/
public class ExceptionTest1 {
@Test
public void test2(){
try{
File file = new File("hello.txt");
FileInputStream fis = new FileInputStream(file);
int data = fis.read();
while(data != -1){
System.out.print((char)data);
data = fis.read();
}
fis.close();
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
@Test
public void test1(){
String str = "123";
str = "abc";
int num = 0;
try{
num = Integer.parseInt(str);
System.out.println("hello-----1");
}catch(NumberFormatException e){
// System.out.println("出现数值转换异常了,不要着急....");
//String getMessage():
// System.out.println(e.getMessage());
//printStackTrace():
e.printStackTrace();
}catch(NullPointerException e){
System.out.println("出现空指针异常了,不要着急....");
}catch(Exception e){
System.out.println("出现异常了,不要着急....");
}
System.out.println(num);
System.out.println("hello-----2");
}
}
package com.atguigu.java1;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
* 异常处理的方式二:throws + 异常类型
*
* 1. "throws + 异常类型"写在方法的声明处。指明此方法执行时,可能会抛出的异常类型。
* 一旦当方法体执行时,出现异常,仍会在异常代码处生成一个异常类的对象,此对象满足throws后异常
* 类型时,就会被抛出。异常代码后续的代码,就不再执行!
*
* 2. 体会:try-catch-finally:真正的将异常给处理掉了。
* throws的方式只是将异常抛给了方法的调用者。 并没有真正将异常处理掉。
*
* 3. 开发中如何选择使用try-catch-finally 还是使用throws?
* 3.1 如果父类中被重写的方法没有throws方式处理异常,则子类重写的方法也不能使用throws,意味着如果
* 子类重写的方法中有异常,必须使用try-catch-finally方式处理。
* 3.2 执行的方法a中,先后又调用了另外的几个方法,这几个方法是递进关系执行的。我们建议这几个方法使用throws
* 的方式进行处理。而执行的方法a可以考虑使用try-catch-finally方式进行处理。
*
*/
public class ExceptionTest2 {
public static void main(String[] args){
try{
method2();
}catch(IOException e){
e.printStackTrace();
}
// method3();
}
public static void method3(){
try {
method2();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void method2() throws IOException{
method1();
}
public static void method1() throws FileNotFoundException,IOException{
File file = new File("hello1.txt");
FileInputStream fis = new FileInputStream(file);
int data = fis.read();
while(data != -1){
System.out.print((char)data);
data = fis.read();
}
fis.close();
System.out.println("hahaha!");
}
}
package com.atguigu.java1;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.junit.Test;
/*
* try-catch-finally中finally的使用:
*
*
* 1.finally是可选的
*
* 2.finally中声明的是一定会被执行的代码。即使catch中又出现异常了,try中有return语句,catch中有
* return语句等情况。
*
* 3.像数据库连接、输入输出流、网络编程Socket等资源,JVM是不能自动的回收的,我们需要自己手动的进行资源的
* 释放。此时的资源释放,就需要声明在finally中。
*
*
*
*/
public class FinallyTest {
@Test
public void test2(){
FileInputStream fis = null;
try {
File file = new File("hello1.txt");
fis = new FileInputStream(file);
int data = fis.read();
while(data != -1){
System.out.print((char)data);
data = fis.read();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(fis != null)
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test
public void testMethod(){
int num = method();
System.out.println(num);
}
public int method(){
try{
int[] arr = new int[10];
System.out.println(arr[10]);
return 1;
}catch(ArrayIndexOutOfBoundsException e){
e.printStackTrace();
return 2;
}finally{
System.out.println("我一定会被执行");
return 3;
}
}
@Test
public void test1(){
try{
int a = 10;
int b = 0;
System.out.println(a / b);
}catch(ArithmeticException e){
e.printStackTrace();
// int[] arr = new int[10];
// System.out.println(arr[10]);
}catch(Exception e){
e.printStackTrace();
}
// System.out.println("我好帅啊!!!~~");
finally{
System.out.println("我好帅啊~~");
}
}
}
package com.atguigu.java1;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
* 方法重写的规则之一:
* 子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型
*
*
*/
public class OverrideTest {
public static void main(String[] args) {
OverrideTest test = new OverrideTest();
test.display(new SubClass());
}
public void display(SuperClass s){
try {
s.method();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class SuperClass{
public void method() throws IOException{
}
}
class SubClass extends SuperClass{
public void method()throws FileNotFoundException{
}
}
package com.atguigu.java2;
/*
* 如何自定义异常类?
* 1. 继承于现有的异常结构:RuntimeException 、Exception
* 2. 提供全局常量:serialVersionUID
* 3. 提供重载的构造器
*
*/
public class MyException extends Exception{
static final long serialVersionUID = -7034897193246939L;
public MyException(){
}
public MyException(String msg){
super(msg);
}
}
package com.atguigu.java2;
public class StudentTest {
public static void main(String[] args) {
try {
Student s = new Student();
s.regist(-1001);
System.out.println(s);
} catch (Exception e) {
// e.printStackTrace();
System.out.println(e.getMessage());
}
}
}
class Student{
private int id;
public void regist(int id) throws Exception {
if(id > 0){
this.id = id;
}else{
// System.out.println("您输入的数据非法!");
//手动抛出异常对象
// throw new RuntimeException("您输入的数据非法!");
// throw new Exception("您输入的数据非法!");
throw new MyException("不能输入负数");
//错误的
// throw new String("不能输入负数");
}
}
@Override
public String toString() {
return "Student [id=" + id + "]";
}
}
package com.atguigu.java2;
public class ReturnExceptionDemo {
static void methodA() {
try {
System.out.println("进入方法A");
throw new RuntimeException("制造异常");
} finally {
System.out.println("用A方法的finally");
}
}
static void methodB() {
try {
System.out.println("进入方法B");
return;
} finally {
System.out.println("调用B方法的finally");
}
}
public static void main(String[] args) {
try {
methodA();
} catch (Exception e) {
System.out.println(e.getMessage());
}
methodB();
}
}
java下册:Java高级教程
第一章:线程的创建与实现
package atguigu.java;
/**
* 测试Thread中的常用方法:
* 1. start():启动当前线程;调用当前线程的run()
* 2. run(): 通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中
* 3. currentThread():静态方法,返回执行当前代码的线程
* 4. getName():获取当前线程的名字
* 5. setName():设置当前线程的名字
* 6. yield():释放当前cpu的执行权
* 7. join():在线程a中调用线程b的join(),此时线程a就进入阻塞状态,直到线程b完全执行完以后,线程a才
* 结束阻塞状态。
* 8. stop():已过时。当执行此方法时,强制结束当前线程。
* 9. sleep(long millitime):让当前线程“睡眠”指定的millitime毫秒。在指定的millitime毫秒时间内,当前
* 线程是阻塞状态。
* 10. isAlive():判断当前线程是否存活
*
*
* 线程的优先级:
* 1.
* MAX_PRIORITY:10
* MIN _PRIORITY:1
* NORM_PRIORITY:5 -->默认优先级
* 2.如何获取和设置当前线程的优先级:
* getPriority():获取线程的优先级
* setPriority(int p):设置线程的优先级
*
* 说明:高优先级的线程要抢占低优先级线程cpu的执行权。但是只是从概率上讲,高优先级的线程高概率的情况下
* 被执行。并不意味着只有当高优先级的线程执行完以后,低优先级的线程才执行。
*
*
* @author shkstart
* @create 2019-02-13 下午 2:26
*/
class HelloThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if(i % 2 == 0){
// try {
// sleep(10);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
System.out.println(Thread.currentThread().getName() + ":" + Thread.currentThread().getPriority() + ":" + i);
}
// if(i % 20 == 0){
// yield();
// }
}
}
public HelloThread(String name){
super(name);
}
}
public class ThreadMethodTest {
public static void main(String[] args) {
HelloThread h1 = new HelloThread("Thread:1");
// h1.setName("线程一");
//设置分线程的优先级
h1.setPriority(Thread.MAX_PRIORITY);
h1.start();
//给主线程命名
Thread.currentThread().setName("主线程");
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
for (int i = 0; i < 100; i++) {
if(i % 2 == 0){
System.out.println(Thread.currentThread().getName() + ":" + Thread.currentThread().getPriority() + ":" + i);
}
// if(i == 20){
// try {
// h1.join();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
}
// System.out.println(h1.isAlive());
}
}
package atguigu.java;
/**
* 多线程的创建,方式一:继承于Thread类
* 1. 创建一个继承于Thread类的子类
* 2. 重写Thread类的run() --> 将此线程执行的操作声明在run()中
* 3. 创建Thread类的子类的对象
* 4. 通过此对象调用start()
* <p>
* 例子:遍历100以内的所有的偶数
*
* @author shkstart
* @create 2019-02-13 上午 11:46
*/
//1. 创建一个继承于Thread类的子类
class MyThread extends Thread {
//2. 重写Thread类的run()
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if(i % 2 == 0){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
}
public class ThreadTest {
public static void main(String[] args) {
//3. 创建Thread类的子类的对象
MyThread t1 = new MyThread();
//4.通过此对象调用start():①启动当前线程 ② 调用当前线程的run()
t1.start();
//问题一:我们不能通过直接调用run()的方式启动线程。
// t1.run();
//问题二:再启动一个线程,遍历100以内的偶数。不可以还让已经start()的线程去执行。会报IllegalThreadStateException
// t1.start();
//我们需要重新创建一个线程的对象
MyThread t2 = new MyThread();
t2.start();
//如下操作仍然是在main线程中执行的。
for (int i = 0; i < 100; i++) {
if(i % 2 == 0){
System.out.println(Thread.currentThread().getName() + ":" + i + "***********main()************");
}
}
}
}
package atguigu.java;
/**
* 创建多线程的方式二:实现Runnable接口
* 1. 创建一个实现了Runnable接口的类
* 2. 实现类去实现Runnable中的抽象方法:run()
* 3. 创建实现类的对象
* 4. 将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
* 5. 通过Thread类的对象调用start()
*
*
* 比较创建线程的两种方式。
* 开发中:优先选择:实现Runnable接口的方式
* 原因:1. 实现的方式没有类的单继承性的局限性
* 2. 实现的方式更适合来处理多个线程有共享数据的情况。
*
* 联系:public class Thread implements Runnable
* 相同点:两种方式都需要重写run(),将线程要执行的逻辑声明在run()中。
*
* @author shkstart
* @create 2019-02-13 下午 4:34
*/
//1. 创建一个实现了Runnable接口的类
class MThread implements Runnable{
//2. 实现类去实现Runnable中的抽象方法:run()
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if(i % 2 == 0){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
}
public class ThreadTest1 {
public static void main(String[] args) {
//3. 创建实现类的对象
MThread mThread = new MThread();
//4. 将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
Thread t1 = new Thread(mThread);
t1.setName("线程1");
//5. 通过Thread类的对象调用start():① 启动线程 ②调用当前线程的run()-->调用了Runnable类型的target的run()
t1.start();
//再启动一个线程,遍历100以内的偶数
Thread t2 = new Thread(mThread);
t2.setName("线程2");
t2.start();
}
}
package atguigu.java;
/**
*
* 例子:创建三个窗口卖票,总票数为100张.使用继承Thread类的方式
*
* 存在线程的安全问题,待解决。
*
* @author shkstart
* @create 2019-02-13 下午 4:20
*/
class Window extends Thread{
private static int ticket = 100;
@Override
public void run() {
while(true){
if(ticket > 0){
System.out.println(getName() + ":卖票,票号为:" + ticket);
ticket--;
}else{
break;
}
}
}
}
public class WindowTest {
public static void main(String[] args) {
Window t1 = new Window();
Window t2 = new Window();
Window t3 = new Window();
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
package atguigu.java;
/**
* 例子:创建三个窗口卖票,总票数为100张.使用实现Runnable接口的方式
* 存在线程的安全问题,待解决。
*
* @author shkstart
* @create 2019-02-13 下午 4:47
*/
class Window1 implements Runnable{
private int ticket = 100;
@Override
public void run() {
while(true){
if(ticket > 0){
System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
ticket--;
}else{
break;
}
}
}
}
public class WindowTest1 {
public static void main(String[] args) {
Window1 w = new Window1();
Thread t1 = new Thread(w);
Thread t2 = new Thread(w);
Thread t3 = new Thread(w);
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
package atguigu.java;
public class HelloWorld {
static int num = 10;
public static final int NUMBER = 1;
public static void main(String[] args) {
System.out.println(123);
System.out.println(123);
System.out.println("HelloWorld.main");
System.out.println("args = [" + args + "]");
System.out.println("num = " + num);
}
}
package atguigu.exer;
/**
* 练习:创建两个分线程,其中一个线程遍历100以内的偶数,另一个线程遍历100以内的奇数
*
*
* @author shkstart
* @create 2019-02-13 下午 2:16
*/
public class ThreadDemo {
public static void main(String[] args) {
// MyThread1 m1 = new MyThread1();
// MyThread2 m2 = new MyThread2();
//
// m1.start();
// m2.start();
//创建Thread类的匿名子类的方式
new Thread(){
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if(i % 2 == 0){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
}.start();
new Thread(){
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if(i % 2 != 0){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
}.start();
}
}
class MyThread1 extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if(i % 2 == 0){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
}
class MyThread2 extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if(i % 2 != 0){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
}
package com.atguigu.java;
/**
* 例子:创建三个窗口卖票,总票数为100张.使用实现Runnable接口的方式
*
* 1.问题:卖票过程中,出现了重票、错票 -->出现了线程的安全问题
* 2.问题出现的原因:当某个线程操作车票的过程中,尚未操作完成时,其他线程参与进来,也操作车票。
* 3.如何解决:当一个线程a在操作ticket的时候,其他线程不能参与进来。直到线程a操作完ticket时,其他
* 线程才可以开始操作ticket。这种情况即使线程a出现了阻塞,也不能被改变。
*
*
* 4.在Java中,我们通过同步机制,来解决线程的安全问题。
*
* 方式一:同步代码块
*
* synchronized(同步监视器){
* //需要被同步的代码
*
* }
* 说明:1.操作共享数据的代码,即为需要被同步的代码。 -->不能包含代码多了,也不能包含代码少了。
* 2.共享数据:多个线程共同操作的变量。比如:ticket就是共享数据。
* 3.同步监视器,俗称:锁。任何一个类的对象,都可以充当锁。
* 要求:多个线程必须要共用同一把锁。
*
* 补充:在实现Runnable接口创建多线程的方式中,我们可以考虑使用this充当同步监视器。
* 方式二:同步方法。
* 如果操作共享数据的代码完整的声明在一个方法中,我们不妨将此方法声明同步的。
*
*
* 5.同步的方式,解决了线程的安全问题。---好处
* 操作同步代码时,只能有一个线程参与,其他线程等待。相当于是一个单线程的过程,效率低。 ---局限性
*
* @author shkstart
* @create 2019-02-13 下午 4:47
*/
class Window1 implements Runnable{
private int ticket = 100;
// Object obj = new Object();
// Dog dog = new Dog();
@Override
public void run() {
// Object obj = new Object();
while(true){
synchronized (this){//此时的this:唯一的Window1的对象 //方式二:synchronized (dog) {
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
ticket--;
} else {
break;
}
}
}
}
}
public class WindowTest1 {
public static void main(String[] args) {
Window1 w = new Window1();
Thread t1 = new Thread(w);
Thread t2 = new Thread(w);
Thread t3 = new Thread(w);
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
class Dog{
}
package com.atguigu.java;
/**
* @author shkstart
* @create 2019-02-15 上午 11:15
*/
/**
* 使用同步代码块解决继承Thread类的方式的线程安全问题
*
* 例子:创建三个窗口卖票,总票数为100张.使用继承Thread类的方式
*
* 说明:在继承Thread类创建多线程的方式中,慎用this充当同步监视器,考虑使用当前类充当同步监视器。
*
* @author shkstart
* @create 2019-02-13 下午 4:20
*/
class Window2 extends Thread{
private static int ticket = 100;
private static Object obj = new Object();
@Override
public void run() {
while(true){
//正确的
// synchronized (obj){
synchronized (Window2.class){//Class clazz = Window2.class,Window2.class只会加载一次
//错误的方式:this代表着t1,t2,t3三个对象
// synchronized (this){
if(ticket > 0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName() + ":卖票,票号为:" + ticket);
ticket--;
}else{
break;
}
}
}
}
}
public class WindowTest2 {
public static void main(String[] args) {
Window2 t1 = new Window2();
Window2 t2 = new Window2();
Window2 t3 = new Window2();
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
package com.atguigu.java;
/**
* 使用同步方法解决实现Runnable接口的线程安全问题
*
*
* 关于同步方法的总结:
* 1. 同步方法仍然涉及到同步监视器,只是不需要我们显式的声明。
* 2. 非静态的同步方法,同步监视器是:this
* 静态的同步方法,同步监视器是:当前类本身
*
* @author shkstart
* @create 2019-02-15 上午 11:35
*/
class Window3 implements Runnable {
private int ticket = 100;
@Override
public void run() {
while (true) {
show();
}
}
private synchronized void show(){//同步监视器:this
//synchronized (this){
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
ticket--;
}
//}
}
}
public class WindowTest3 {
public static void main(String[] args) {
Window3 w = new Window3();
Thread t1 = new Thread(w);
Thread t2 = new Thread(w);
Thread t3 = new Thread(w);
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
package com.atguigu.java;
/**
* 使用同步方法处理继承Thread类的方式中的线程安全问题
*
* @author shkstart
* @create 2019-02-15 上午 11:43
*/
class Window4 extends Thread {
private static int ticket = 100;
@Override
public void run() {
while (true) {
show();
}
}
private static synchronized void show(){//同步监视器:Window4.class
//private synchronized void show(){ //同步监视器:t1,t2,t3。此种解决方式是错误的
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
ticket--;
}
}
}
public class WindowTest4 {
public static void main(String[] args) {
Window4 t1 = new Window4();
Window4 t2 = new Window4();
Window4 t3 = new Window4();
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
package com.atguigu.java1;
/**
* 使用同步机制将单例模式中的懒汉式改写为线程安全的
*
* @author shkstart
* @create 2019-02-15 下午 2:50
*/
public class BankTest {
}
class Bank{
private Bank(){}
private static Bank instance = null;
public static Bank getInstance(){
//方式一:效率稍差
// synchronized (Bank.class) {
// if(instance == null){
//
// instance = new Bank();
// }
// return instance;
// }
//方式二:效率更高
if(instance == null){
synchronized (Bank.class) {
if(instance == null){
instance = new Bank();
}
}
}
return instance;
}
}
package com.atguigu.java1;
//死锁的演示
class A {
public synchronized void foo(B b) { //同步监视器:A类的对象:a
System.out.println("当前线程名: " + Thread.currentThread().getName()
+ " 进入了A实例的foo方法"); // ①
// try {
// Thread.sleep(200);
// } catch (InterruptedException ex) {
// ex.printStackTrace();
// }
System.out.println("当前线程名: " + Thread.currentThread().getName()
+ " 企图调用B实例的last方法"); // ③
b.last();
}
public synchronized void last() {//同步监视器:A类的对象:a
System.out.println("进入了A类的last方法内部");
}
}
class B {
public synchronized void bar(A a) {//同步监视器:b
System.out.println("当前线程名: " + Thread.currentThread().getName()
+ " 进入了B实例的bar方法"); // ②
// try {
// Thread.sleep(200);
// } catch (InterruptedException ex) {
// ex.printStackTrace();
// }
System.out.println("当前线程名: " + Thread.currentThread().getName()
+ " 企图调用A实例的last方法"); // ④
a.last();
}
public synchronized void last() {//同步监视器:b
System.out.println("进入了B类的last方法内部");
}
}
public class DeadLock implements Runnable {
A a = new A();
B b = new B();
public void init() {
Thread.currentThread().setName("主线程");
// 调用a对象的foo方法
a.foo(b);
System.out.println("进入了主线程之后");
}
public void run() {
Thread.currentThread().setName("副线程");
// 调用b对象的bar方法
b.bar(a);
System.out.println("进入了副线程之后");
}
public static void main(String[] args) {
DeadLock dl = new DeadLock();
new Thread(dl).start();
dl.init();
}
}
package com.atguigu.java1;
import java.util.concurrent.locks.ReentrantLock;
/**
* 解决线程安全问题的方式三:Lock锁 --- JDK5.0新增
*
* 1. 面试题:synchronized 与 Lock的异同?
* 相同:二者都可以解决线程安全问题
* 不同:synchronized机制在执行完相应的同步代码以后,自动的释放同步监视器
* Lock需要手动的启动同步(lock()),同时结束同步也需要手动的实现(unlock())
*
* 2.优先使用顺序:
* Lock 同步代码块(已经进入了方法体,分配了相应资源) 同步方法(在方法体之外)
*
*
* 面试题:如何解决线程安全问题?有几种方式
* @author shkstart
* @create 2019-02-15 下午 3:38
*/
class Window implements Runnable{
private int ticket = 100;
//1.实例化ReentrantLock
private ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while(true){
try{
//2.调用锁定方法lock()
lock.lock();
if(ticket > 0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":售票,票号为:" + ticket);
ticket--;
}else{
break;
}
}finally {
//3.调用解锁方法:unlock()
lock.unlock();
}
}
}
}
public class LockTest {
public static void main(String[] args) {
Window w = new Window();
Thread t1 = new Thread(w);
Thread t2 = new Thread(w);
Thread t3 = new Thread(w);
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
package com.atguigu.java1;
/**
* 演示线程的死锁问题
*
* 1.死锁的理解:不同的线程分别占用对方需要的同步资源不放弃,
* 都在等待对方放弃自己需要的同步资源,就形成了线程的死锁
*
* 2.说明:
* 1)出现死锁后,不会出现异常,不会出现提示,只是所有的线程都处于阻塞状态,无法继续
* 2)我们使用同步时,要避免出现死锁。
*
* @author shkstart
* @create 2019-02-15 下午 3:20
*/
public class ThreadTest {
public static void main(String[] args) {
StringBuffer s1 = new StringBuffer();
StringBuffer s2 = new StringBuffer();
new Thread(){
@Override
public void run() {
synchronized (s1){
s1.append("a");
s2.append("1");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (s2){
s1.append("b");
s2.append("2");
System.out.println(s1);
System.out.println(s2);
}
}
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
synchronized (s2){
s1.append("c");
s2.append("3");