Java入门
01.Java 帝国的诞生
02.Java 特性和优势
03.Java 三大版本
04.JDK JRE JVM
05.安装开发环境
06.HelloWorld 详解
07.编译型和解释型
08.使用IDEA开发
Java基础
01.注释
- 注释不会被执行!
- 书写注释是一个非常好的习惯!!!
- 平时写代码一定要注意规范!!
Java中的注释有三种:
- 单行注释
- 多行注释
- 文档注释
具体操作代码如下:
public class HelloWorld {
public static void main (String[] args){
//单行注释:只能注释一行文字
//输出一个HelloWorld!
//多行注释:可以注释一段文字 /* 注释内容 */
/*
多行注释
多行注释
多行注释
*/
//JavaDoc:文档注释 /** */
/**
* @Description HelloWorld
* @Author 阿清
*/
//有趣的代码注释(百度即可)
/*
_(\_/)
,((((^`\
(((( (6 \
,((((( , \
,,,_ ,((((( /"._ ,`,
((((\\ ,... ,(((( / `-.-'
))) ;' `"'"'""(((( (
((( / ((( \
)) | |
(( | . ' |
)) \ _ ' `t ,.')
( | y;- -,-""'"-.\ \/
) / ./ ) / `\ \
|./ ( ( / /'
|| \\ //'|
|| \\ _//'||
|| )) |_/ ||
\_\ |_/ ||
`'" \_\
`'"
*/
/***
* ░░░░░░░░░░░░░░░░░░░░░░░░▄░░
* ░░░░░░░░░▐█░░░░░░░░░░░▄▀▒▌░
* ░░░░░░░░▐▀▒█░░░░░░░░▄▀▒▒▒▐
* ░░░░░░░▐▄▀▒▒▀▀▀▀▄▄▄▀▒▒▒▒▒▐
* ░░░░░▄▄▀▒░▒▒▒▒▒▒▒▒▒█▒▒▄█▒▐
* ░░░▄▀▒▒▒░░░▒▒▒░░░▒▒▒▀██▀▒▌
* ░░▐▒▒▒▄▄▒▒▒▒░░░▒▒▒▒▒▒▒▀▄▒▒
* ░░▌░░▌█▀▒▒▒▒▒▄▀█▄▒▒▒▒▒▒▒█▒▐
* ░▐░░░▒▒▒▒▒▒▒▒▌██▀▒▒░░░▒▒▒▀▄
* ░▌░▒▄██▄▒▒▒▒▒▒▒▒▒░░░░░░▒▒▒▒
* ▀▒▀▐▄█▄█▌▄░▀▒▒░░░░░░░░░░▒▒▒
* 单身狗就这样默默地看着你,一句话也不说。
*/
System.out.println("HelloWorld!!");
}
}
02.标识符和关键字
关键字
- Java 所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。
标识符注意点
- 所有的标识符都应该以字母(A-Z或者a-z)、美元符($)或者下划线(_)开始。
- 首字母之后可以是字母(A-Z或者a-z)、美元符($)、下划线(_)或数字的任何字符组合。
- 不能使用关键字作为变量名或者方法名。
- 标识符是大小写敏感的。
- 合法标识符举例:age、$salary、_value、__1_value
- 非法标识符举例:123abc、-salary、#abc
- 可以使用中文命名,但一般不建议这样去使用,也不建议是用拼音,很Low。
public static void main(String[] args) {
String 王者荣耀="荣耀王者";
Ststem.out.println(王者荣耀);
}
03.数据类型讲解
强类型语言
- 强类型语言是一种强制类型定义的语言,一旦某一个变量被定义类型,如果不经过强制转换,则它永远就是该数据类型了,强类型语言包括Java、.net 、Python、C++等语言。
- ==要求变量的使用要严格符合规定,所有变量都必须先定义后才能使用。==
弱类型语言
- 弱类型语言是一种弱类型定义的语言,某一个变量被定义类型,该变量可以根据环境变化自动进行转换,不需要经过显性强制转换。弱类型语言包括vb 、PHP、javascript等语言。
Java的数据类型分为两大类
- 基本数据类型(primitive type)
- 引用数据类型(reference type)
//八大基本数据类型
//整数
int num1 = 10;//最常用的数据类型
byte num2 = 20;
short num3 = 30;
long num4 = 30L;//Long类型要在数字后面加个L,用于区分
//小数:浮点数
float num5 = 17.4F;//Float类型要在数字后面加个F,用于区分
double num6 = 3.141592653589793238462643;
//字符
char name = '清';
/*
字符串,String是类,不是关键字
String namea = "阿清";
*/
//布尔值
boolean flag = true;
boolean flaga = false;
拓展:什么是字节?
- 位(bit):是计算机 内部数据 存储的最小单位,11001100是一个八位二进制数。
- 字节(byte):是计算机中 数据处理 的最基本单位,习惯上用大写字母B来表示。
- 1B(byte,字节)= 8 bit(位)
- 字符:是指计算机中使用的字母、数字、字和符号。
- 1 bit 表示 1 位
- 1 byte 表示一个字节 1 B = 8 b
- 1024 B = 1 KB
- 1024 KB = 1 M
- 1024 M = 1 G
- 1024 G = 1 TB
04.数据类型扩展及面试题讲解
整数拓展
//整数拓展: 进制 二进制0b 十进制 八进制0 十六进制0x
int i1 = 10;// 10
int i2 = 010;// 8 八进制0
int i3 = 0x10;// 16 十六进制0x 0~9 A~F
浮点数拓展
//浮点数拓展:银行业务怎么表示?钱
//BigDecimal 数学工具类
//float 有限 离散 舍入误差 大约 接近但不等于
//double
//最好完全使用浮点数进行比较
float f = 0.1f;//0.1
double d = 1.0/10;//0.1
System.out.println(f==d);//false
float f1 = 1231233123f;
float f2 = f1 + 1;
System.out.println(f1==f2);//true
字符拓展
//字符拓展
char c1 = 'a';
char c2 = '中';
System.out.println(c1);//a
System.out.println((int)c1);//97 强制转换
System.out.println(c2);//中
System.out.println((int)c2);//20013 强制转换
//所有字符的本质还是数字
//编码 Unicode 表:(97 = a 65 = A) 2字节 0 ~ 65536 Excel 2的16次方 = 65536
// U0000 ~ UFFFF
char c3 = '\u0061';
System.out.println(c3);//a
转义字符
//转义字符
// \t 制表符
// \n 换行
// ...
思考
String s1 = new String(original:"hello world");
String s2 = new String(original:"hello world");
System.out.println(s1==s2);//false
String s3 = "hello world";
String s4 = "hello world";
System.out.println(s3==s4);//true
//对象 从内存分析
布尔值拓展
//布尔值拓展
boolean flag = true;
if(flag==true){}//新手
if(flag){}//老手
//Less is More! 代码要精简易读!
05.类型转换
- 由于 Java 是强类型语言,所以在进行有些运算的时候,需要用到类型转换。
- 低--------------------------------------------------->高
byte,short,char->int->long->float->double - 运算中,不同类型的数据先转换为同一类型,然后进行运算。
- 转换类型分为强制转换和自动转换。
强制转换和自动转换
//强制转换 (类型)变量名 高-->低
int i = 128;//输出结果为128
byte b = (byte)i;//输出结果为-128 内存溢出
//自动转换 低-->高
/*
注意点:
1.不能对布尔值进行转换
2.不能把对象类型转换为不相干的类型
3.在把高容量转换到低容量的时候,强制转换
4.转换的时候可能存在内存溢出,或者精度问题!
*/
System.out.println((int)23.7);//23
System.out.println((int)-45.89f);//-45
char c = 'a';
int d = c + 1;
System.out.println(d);//98
System.out.println((char)d);//b
//操作比较大的数的时候,注意溢出问题
//JDK7新特性,数字之间可以用下划线分割,下划线不会被输出
int money = 10_0000_0000;//1000000000
int years = 20;
int total1 = money*years;
System.out.println(total1);//-1474836480,计算的时候溢出了
long total2 = money*years;
System.out.println(total2);//-1474836480,默认是int转换之前已经存在问题了
long total3 = money*((long)years);
System.out.println(total3);//20000000000,先把一个数转换为long
06.变量、常量、作用域
变量
-
变量是什么:就是可以变化的量!
-
Java 是一种强类型语言,每个变量都必须声明其类型。
-
Java 变量是程序中最基础的存储单元,其要素包括变量名,变量类型和作用域。
type varName [=value] [{,varName[=value]}]; //数据类型 变量名 = 值;可以用逗号隔开来声明多个同类型变量。
例子:
//int a,b,c;
//int a = 1,b = 2,c = 3;//程序可读性
String name = "清";
char x = 'X';
double pi = 3.14;
- 注意事项:
- 每个变量都有类型,类型可以是基本类型,也可以是引用类型。
- 变量名必须是合法的标识符。
- 变量声明是一条完整的语句,因此每一个声明都必须以分号结束。
变量作用域
- 类变量
- 实例变量
- 局部变量
public class Demo{
//类变量 static
static double salary = 2500;
//属性:变量
//实例变量:从属于对象;
//如果不自行初始化,这个类型的默认值为0 0.0
//布尔值:默认值是false
//除了基本类型,其余的默认值都是null;
String name;
int age;
// main方法
public static void main(String[] args){
//局部变量;必须声明和初始化值
int i = 8;
System.out.println(i);
//变量类型 变量名字 = new 类名();
Demo demo = new Demo();
System.out.println(demo.name);//null
System.out.println(demo.age);//0
//类变量 static
System.out.println(salary);
}
}
常量
-
常量(Constant):初始化(initialize)后不能在改变值!不会变动的值。
-
所谓常量可以理解为一种特殊的变量,它的值被设定后,在程序运行过程中不允许被改变。
// final 常量名 = 值; final double PI = 3.14; static final double PI = 3.14;//数据类型前面的关键字均为修饰符不存在先后顺序
-
常量名一般使用大写字符。
变量的命名规范
- 所有的变量、方法、类名:见名知意
- 类成员变量:首字母小写和驼峰原则(monthSalary 除了第一个单词外,后面的单词首字母大写)
- 局部变量:首字母小写和驼峰原则
- 常量:大写字母和下划线:MAX_VALUE
- 类名:首字母大写和驼峰原则:Man,GoodMan
- 方法名:首字母小写和驼峰原则:run(),runRun()
07.基本运算符
- Java语言支持如下运算符
- 算数运算符:+ , - , * , / ,% ,++ ,–
- 赋值运算符:==
- 关系运算符:> , < , >= , <= , == , != , instanceof
- 逻辑运算符:&&,|| ,!
- 位运算符:& ,| ,^ , ~ , >> , << , >>> (了解!!!)
- 条件运算符: ? :
- 扩展赋值运算符:+= ,-= ,*= ,/=
//二元运算符
int a = 10;
int b = 20;
System.out.println(a+b);//30
System.out.println(a-b);//10
System.out.println(a*b);//200
System.out.println(a/b);//0
System.out.println(a/(double)b);//0.5
long a = 123123123123123L;
int b =123;
short c = 10;
byte d = 8;
System.out.println(a+b+c+d);//123123123123264 Long
System.out.println(b+c+d);//141 Int
System.out.println(c+d);//18 Int
//关系运算符返回的结果: 正确,错误 布尔值
int a = 10;
int b = 21;
System.out.println(a>b);//false
System.out.println(a<b);//true
System.out.println(a==b);//false
System.out.println(a!=b);//true
//取余,模运算
System.out.println(b%a);// b/a 21 / 10 = 2 ... 1
08.自增自减运算符、初识Math类
自增自减运算符
// ++ -- 自增 自减 一元运算
int a = 3;
int b = a++;//执行完这行代码后,先给b赋值,在自增
// a++ a = a + 1
System.out.println(a);//4
int c = ++a;//执行完这行代码前,先自增,再给c赋值
// ++a a = a + 1
System.out.println(a);//5
System.out.println(b);//3
System.out.println(c);//5
int a = 3;
int b = a--;//执行完这行代码后,先给b赋值,在自减
// a-- a = a - 1
System.out.println(a);//2
int c = --a;//执行完这行代码前,先自减,再给c赋值
// --a a = a - 1
System.out.println(a);//1
System.out.println(b);//3
System.out.println(c);//1
Math类
//幂运算 2^3 2*2*2 = 8 很多运算,我们都会使用一些工具类来操作!
double pow = Math.pow(2,3);
System.out.println(pow);//8.0
09.逻辑运算符、位运算符
逻辑运算符
//逻辑运算符
//与(and)或(or)非(取反)
boolean a = true;
boolean b = false;
System.out.println("a && b : "+(a&&b));//输出结果为:a && b : false 逻辑与运算:两个变量都为真,结果才是true
System.out.println("a || b : "+(a||b));//输出结果为:a || b : true 逻辑或运算:两个变量有一个为真,则结果才是true
System.out.println("!(a && b) : "+!(a&&b));//输出结果为:!(a && b) : true 如果是真,则变为假,如果是假,则变为真
//短路运算
int c = 5;
boolean d = (c<4)&&(c++<4);
System.out.println(d);//false
System.out.println(c);//5
位运算符
/*
A = 0011 1100
B = 0000 1101
A&B = 0000 1100 //相对应位有0,则结果为0,否则为1
A|B = 0011 1101 // 相对应位有1,则结果为1,否则为0
A^B = 0011 0001 //相同为0,不同为1
~B = 1111 0010
*/
/*
2 * 8 = 16 2*2*2*2
效率极高
左移 << *2
右移 >> /2
0000 0000 0
0000 0001 1
0000 0010 2
0000 0011 3
0000 0100 4
0000 1000 8
0001 0000 16
*/
System.out.println(2<<3);//16
10.三元运算符、扩展运算符
三元运算符
// x ? y : z
//如果x==true,则结果为y,反之结果为z
int score = 80;
String type = score < 60 ? "不及格" : "及格";
System.out.println(type);//及格
扩展赋值运算符
int a = 10;
int b = 20;
/*
a += b;// a = a + b
a -= b;// a = a - b
a *= b;// a = a * b
a /= b;// a = a / b
*/
//字符串连接符 + , String
System.out.println(""+a+b);//1020
System.out.println(a+b+"");//30
11.包机制
- 为了更好地组织类,Java提供了包机制,用于区别类名的命名空间。
- 包语句的语法格式为:
package pkg1[.pkg2[.pkg3...]];
- 一般利用公司域名倒置作为包名
- 为了能够使用某一包的成员,我们需要在 Java 程序中明确导入该包。使用“ import ”语句可完成此功能。
import package1[.package2...].(classname|*);
12.JavaDoc 生成文档
- JavaDoc 命令是用来生成自己的API文档的。
- 参数信息
- @author 作者名
- @version 版本号
- @since 指明需要最早使用的 jdk 版本
- @param 参数名
- @return 返回值情况
- @throws 异常跑出情况
package com.Qing.base;
/**
*@auther Qing
*@version 1.0
*@since 1.8
*/
public class Doc{
String name;
/**
*@auther Qing
*@param name
*@return
*@throws Exception
*/
public String test(String name) throws Exception{
return name;
}
}
- 命令行 javadoc 参数 Java 文件
- 使用 IDEA 生成 JavaDoc 文档
Java流程控制
01.用户交互 Scanner
Scanner 对象
-
Java 给我们提供了这样一个工具类,我们可以获取用户的输入。Java.util.Scanner 是 Java 5 的新特性,我们可以通过 Scanner 类来获取用户的输入。
-
基本语法:
Scanner s = new Scanner(System.in);
-
通过 Scanner 类的 next() 与 nextLine() 方法获取输入的字符串,在读取前我们一般需要使用 hasNext() 与 hasNextLine() 判断是否还有输入的数据。
-
next(); 和 nextLine(); 的区别:
- next():
- 一定要读取到有效字符后才可以结束输入。
- 对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。
- 只有输入有效字符之后才将其后面输入的空白作为分隔符或者结束符。
- next() 不能得到带有空格的字符串。
- nextLine():
- 以 Enter 为结束符,也就是说 nextLine() 方法返回的是输入回车之前的所有字符。
- 可以获得空白。
- next():
next();
//创建一个扫描器对象,用于接收键盘数据
Scanner scanner = new Scanner(System.in);
System.out.println("使用next方法接收:");
//判断用户是否输入字符串
if(scanner.hasNext()){
//使用next方式接收
String str = scanner.next();//程序会等待用户输入完毕
System.out.println("输出的内容为:"+str);
}
//凡是属于IO流的类如果不关闭会一直占用资源,要养成好习惯用完就关掉
scanner.close();
nextLine();
//创建一个扫描器对象,用于接收键盘数据
Scanner scanner = new Scanner(System.in);
System.out.println("使用nextLine方法接收:");
//判断用户是否输入字符串
if(scanner.hasNextLine()){
//使用next方式接收
String str = scanner.nextLine();//程序会等待用户输入完毕
System.out.println("输出的内容为:"+str);
}
//凡是属于IO流的类如果不关闭会一直占用资源,要养成好习惯用完就关掉
scanner.close();
简:
//创建一个扫描器对象,用于接收键盘数据
Scanner scanner = new Scanner(System.in);
System.out.println("请输入数据:");
//使用next方式接收
String str = scanner.nextLine();//程序会等待用户输入完毕
System.out.println("输出的内容为:"+str);
//凡是属于IO流的类如果不关闭会一直占用资源,要养成好习惯用完就关掉
scanner.close();
02.Scanner 进阶使用
Scanner scanner = new Scanner(System.in);
//从键盘接收数据
int i = 0;
float f = 0.0f;
//如果...那么...
if(scanner.hasNextInt()){
i = scanner.nextInt();
System.out.println("整数数据:"+ i);
}else{
System.out.println("输入的不是整数数据!");
}
//如果...那么...
if(scanner.hasNextFloat()){
f = scanner.nextFloat();
System.out.println("小数数据:"+ f);
}else{
System.out.println("输入的不是小数数据!");
}
scanner.close();
实例:我们可以输入多个数字,并求其总和与平均数,每输入一个数字用回车确认,通过输入非数字来结束输入并输出执行结果。
Scanner scanner = new Scanner(System.in);
System.out.println("请输入多个数据,每输入一个数字用回车确认:");
//和
double sum = 0;
//计算输入了多少个数字
int m = 0;
//通过循环判断是否还有输入,并在里面对每一次进行求和和统计
while(scanner.hasNextDouble()){
double x = scanner.nextDouble();
m = m + 1;//m++
sum = sum + x;
System.out.println("你输入了第"+m+"个数据,然后当前结果sum="+sum);
}
System.out.println("个数的和为" + sum);
System.out.println("个数的平均值是" + (sum /m));
scanner.close();
03.顺序结构
-
JAVA 的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行。
-
顺序结构是最简单的算法结构。
-
语句与语句之间,框与框之间是按从上到下的顺序进行的,它是由若干个依次执行的处理步骤组成的,它是任何一个算法都离不开的一种基本算法结构。
04.if 选择结构
if 单选择结构
- 判断一个东西是否可行,然后才去执行,这样的一个过程在程序中用 if 语句来表示。
- 语法:
if(布尔表达式){ //如果布尔表达式为true将执行的语句 }
例子:
Scanner scanner = new Scanner(System.in);
System.out.println("请输入内容:");
String s = scanner.nextLine();
//equals:判断字符串是否相等
if (s.equals("Hello")){
System.out.println(s);
}
System.out.println("End");
scanner.close();
if 双选择结构
- 需要有两个判断,需要 if - else 双选择结构。
- 语法:
if(布尔表达式){ //如果布尔表达式的值为true将执行的语句 }else{ //如果布尔表达式的值为false将执行的语句 }
例子:
//考试分数大于60就是及格,小于60就是不及格。
Scanner scanner = new Scanner(System.in);
System.out.println("请输入成绩:");
int score = scanner.nextInt();
if (score>60){
System.out.println("及格");
}else{
System.out.println("不及格");
}
scanner.close();
if 多选择结构
- 存在区间多级判断,需要一个多选择结构来处理这类问题。
- 语法:
if(布尔表达式 1 ){ //如果布尔表达式 1 的值为true执行代码 }else if(布尔表达式 2 ){ //如果布尔表达式 2 的值为true执行代码 }else if(布尔表达式 3 ){ //如果布尔表达式 3 的值为true执行代码 }else{ //如果以上布尔表达式的值都不为true执行代码 }
实例:
Scanner scanner = new Scanner(System.in);
System.out.println("请输入成绩:");
int score = scanner.nextInt();
if (score==100){
System.out.println("恭喜满分!");
}else if(score<100 && score>=90){
System.out.println("A级");
}else if(score<90 && score>=80){
System.out.println("B级");
}else if(score<80 && score>=70){
System.out.println("C级");
}else if(score<70 && score>=60){
System.out.println("D级");
}else if(score<60 && score>=0){
System.out.println("不及格");
}else{
System.out.println("成绩不合法!");
}
scanner.close();
注意点:
- if 语句至多有一个 else 语句, else 语句在所有 else if 语句之后。
- if 语句可以有若干个 else if 语句,它们必须在 else 语句之前。
- 一旦其中一个 else if 语句检测为 true ,其他的 else if 以及 else 语句都将跳过执行。
嵌套的 if 结构
-
使用嵌套的 if … else 语句是合法的。也就是说你可以在另一个 if 或 else if 语句中使用 if 或者 else if 语句。你可以像 if 语句一样嵌套 else if … else。
-
语法:
if(布尔表达式 1){ //如果布尔表达式 1 的值为 true 执行代码 if(布尔表达式 2){ //如果布尔表达式 2 的值为 true 执行代码 } }
05.switch选择结构
- 多选择结构还有一个实现方式就是 switch case 语句。
- switch case 语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。
- 语法:
switch(expression){
case value:
//语句
break;//可选
case value:
//语句
break;//可选
//你可以拥有任意数量的 case 语句
default://可选
//语句
}
- switch 语句中的变量类型可以是:
- byte、short、int 或者 char。
- 从 Java SE 7 开始。
- switch 支持字符串 String 类型了。
- 同时 case 标签必须为字符串常量或字面量。
例子:
//case 穿透 //switch 匹配一个具体的值
char grade = 'C';
switch(grade){
case 'A':
System.out.println("优秀");
break;
case 'B':
System.out.println("良好");
break;
case 'C':
System.out.println("中等");
break;
case 'D':
System.out.println("及格");
break;
case 'E':
System.out.println("挂科");
break;
default:
System.out.println("未知等级");
}
//JDK 7 的新特性,表达式结果可以是字符串!!!
//字符的本质还是数字
//反编译 java --- class(字节码文件)---反编译(IDEA)
String name = "北北";
switch (name){
case "北北":
System.out.println("北北");
break;
case "阿清":
System.out.println("阿清");
break;
default:
System.out.println("识别失败!");
}
06.while循环
- while 是最基本的循环,它的结构为:
while(布尔表达式){ //循环内容 }
- 只要布尔表达式为 true ,循环就会一直执行下去。
- 我们大多数情况是会让循环停下来的,我们需要一个让表达式失效的方式来结束循环。
- 少部分情况需要循环一直执行,比如服务器的请求响应监听等。
- 循环条件一直为 true 就会造成无限循环【死循环】,我们正常的业务编程中应该尽量避免死循环。死循环会影响程序性能或者造成程序卡死崩溃!
例子:计算1+2+3+…+100=?
int i = 0;
int sum = 0;
while(i<=100){
sum = sum + i;
i++;
}
System.out.println(sum);//5050
死循环
while(true){
//等待客户端连接
//定时检查
//......
}
07. do while循环
- 对于 while 语句而言,如果不满足条件,则不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次。
- do … while 循环和 while 循环相似,不同的是,do…while 循环至少会执行一次。
do{ //代码语句 }while(布尔表达式);
- while 和 do-while 的区别:
- while 先判断后执行。do-while 先执行后判断!
- do … while 总是保证循环体会被至少执行一次!这是他们的主要区别。
例子:
int i = 0;
int sum = 0;
do{
sum = sum + i;
i++;
}while(i<=100);
System.out.println(sum);//5050
int a = 0;
while (a<0){
System.out.println(a);
a++;
}
System.out.println("==============");
do{
System.out.println(a);
a++;
}while(a<0);
//输出结果
//==============
//0
08.for循环
-
for 循环会使一些循环结构变得更加简单。
-
for 循环语句是支持迭代的一种通用结构,是最有效、最灵活的循环结构。
-
for 循环执行的次数是在执行前就确定的。
-
语法格式如下:
for(初始化;布尔表达式;更新){ //代码语句 }
对比:
int a = 1;//初始化条件
while(a<=100){//条件判断
System.out.println(a);//循环体
a++;//迭代
}
System.out.println("while 循环结束!");
//初始化//条件判断//迭代
for(int i = 1;i<=100;i++){
System.out.println(i);
}
System.out.println("for 循环结束!");
死循环
for(;;){
//等待客户端连接
//定时检查
//......
}
关于 for 循环有以下几点说明:
- 最先执行初始化步骤。可以声明一种类型,但可初始化一个或多个循环控制变量,也可以是空语句。
- 然后,检测布尔表达式的值。如果为 true ,循环体被执行;反之为 false ,循环终止,开始执行循环体后面的语句。
- 执行一次循环后,更新循环控制变量(迭代因子控制循环变量的增减)。
- 再次检测布尔表达式。循环执行上面的过程。
实例一:计算 0 到 100 之间的奇数的和与偶数的和
int oddSum = 0;
int evenSum = 0;
for(int i = 0;i<100;i++){
if(i%2!=0){//奇数
oddSum+=i;
}else{//偶数
evenSum+=i;
}
}
System.out.println("奇数的和"+oddSum);
System.out.println("偶数的和"+evenSum);
实例二:用 while 或 for 循环输出1-1000之间能被5整除的数,并且每行输出3个
for(int i = 0;i<=1000;i++){
if(i%5==0){
System.out.println(i+"\t");
}
if(i%(5*3)==0){
System.out.println();
//System.out.print("\n");
}
//println 输出完会换行
//print 输出完不会换行
}
09.打印九九乘法表
//1.首先打印第一列
//2.把固定的1再用一个循环包起来
//3.去掉重复项,j<=i
//4.调整样式
for(int i = 1;i <= 9;i++){
for(int j = 1; j <= i;j++){
System.out.print(i+"*"+j+"="+(i*j)+"\t");
}
System.out.println();
}
10.增强for循环
-
Java 5 引入了一种主要用于数组或集合的增强型 for 循环。
-
Java 增强 for 循环语法格式如下:
for (声明语句:表达式){ //代码语句 }
-
声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环句块,其值与此时数组元素的值相等。
-
表达式:表达式是要访问的数组名,或者是返回值为数组的方法。
例子:
int [] numbers = {10,20,30,40,50};
for(int i = 0; i<5;i++){
System.out.println(numbers[i]);
}
System.out.println("=================");
//遍历数组的元素
for (int x:numbers){
System.out.println(x);
}
//输出结果
//10
//20
//30
//40
//50
//=================
//10
//20
//30
//40
//50
11.break、continue、goto
- break 在任何循环语句的主体部分,均可用 break 控制循环的流程。break 用于强行退出循环,不执行循环中剩余的语句。( break 语句也在 switch 语句中使用)
- continue 语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。
- 关于 goto 关键字
- goto 关键字在很早就在程序设计语言中出现。尽管 goto 仍是 Java 的一个保留字,但并未在语言中得到正式使用;Java没有 goto 。然而,在 break 和 continue 这两个关键字的身上,我们仍然能看出一些 goto 的影子—带标签的 break 和 continue 。
- "标签"是指后面跟一个冒号的标识符,例如:label :
- 对 Java 来说唯一用到标签的地方是在循环语句之前。而在循环之前设置标签的唯一理由是:我们希望在其中嵌套另一个循环,由于 break 和 continue 关键字通常只中断当前循环,但若随同标签使用,它们就会中断到存在标签的地方。
例子:打印101-150之间所有的质数
//不建议使用!!
outer:for(int i = 101;i<150;i++){
for(int j = 2;j<i/2;j++){
if(i % j == 0){
continue outer;
}
}
System.out.print(i+" ");
//101 103 107 109 113 127 131 137 139 149
}
12.打印三角形及Debug
实例一:打印三角形 五行
/*
*
***
*****
*******
*********
*/
for(int i = 1; i <= 5;i++){
for(int j = 5;j >= i;j--){
System.out.print(" ");
}
for(int j = 1;j <= i;j++){
System.out.print("*");
}
for(int j = 1;j < i;j++){
System.out.print("*");
}
System.out.println();
}
Java方法
01.什么是方法?
-
Java 方法是语句的集合,它们在一起执行一个功能。
-方法是解决一类问题的步骤的有序组合
方法包含于类或对象中
方法在程序中被创建,在其他地方被引用 -
设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块的集合。我们设计方法的时候,最好保持方法的原子性,就是一个方法只能完成一个功能,这样利于我们后期扩展。
02.方法的定义和调用
方法的定义
- Java 的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段,一般情况下,定义一个方法包含以下语法:
- 方法包含一个方法头和一个方法体。 下面是一个方法的所有部分:
- 修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
- 返回值类型:方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字 void。
- 方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
- 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
- 形式参数:在方法被调用时用于接收外界输入的数据。
- 实参:调用方法时事迹传给方法的数据。
- 方法体:方法体包含具体的语句,定义该方法的功能。
例子:
public static void main(String[] args){
//实际参数:实际调用传递给他的参数
int sum = add.(1,2);
System.out.println(sum);
}
//形式参数,用来定义作用的
public static int add(int a,int b){
return a+b;
}
方法调用
-
调用方法:对象名.方法名(实参列表)
-
Java 支持两种调用方法的方式,根据方法是否返回值来选择。
-
当方法返回一个值的时候,方法调用通常被当做一个值。例如:
int larger = max(30,40);
-
如果方法返回值是 void ,方法调用一定是一条语句。
System.out.println("Hello,AQing!");
例子:
public static void main(String[] args){
int max = max(10,20);
System.out.println(max);
}
//比大小
public static int max(int num1,int num2){
int result = 0;
if(num1==num2){
System.out.println("num1==num2");
return 0;//终止方法
}
if(num1>num2){
result = num1;
}else{
result = num2;
}
return result;
}
03.方法的重载
- 重载就是在一个类中,有相同的函数名称,但形参不同的函数。
- 方法的重载的规则:
- 方法名称必须相同。
- 参数列表必须不同(个数不同或类型不同、参数排列顺序不同等)。
- 方法的返回类型可以相同也可以不相同。
- 仅仅返回类型不同不足以成为方法的重载。
- 实践理论:
- 方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错。
04.命令行传递参数
- 有时候你希望运行一个程序时候在传递给它消息。这要靠传递命令行参数给 main () 函数实现。
public class CommandLine{
public static void main(String[] args){
for(int i = 0;i<args.length;i++){
System.out.println("args["+i+"]:"+args[i]);
}
}
}
05.可变参数
- JDK 1.5 开始,Java支持传递同类型的可变参数给一个方法。
- 在方法声明中,在指定参数类型后加一个省略号(…)。
- 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
例子:
public static void printMax(double...numbers){
if(numbers.length == 0){
System.out.println("No argument passed");
return;
}
double result = numbers[0];
//排序
for(int i = 1;i<numbers.length;i++){
if(numbers[i]>result){
return = numbers[i];
}
}
System.out.println("The max value is"+result);
}
06.递归讲解
- A 方法调用 B 方法。我们很容易理解!
- 递归就是:A 方法调用 A 方法!就是自己调用自己
- 利用递归可以用简单的程序来解决一些复杂的问题。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归的策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。
- 递归结构包括两个部分:
- 递归头:什么时候不用自身方法。如果没有头,将陷入死循环。
- 递归体:什么时候需要调用自身方法。
例子:
- 不建议使用!!
public static int f(int n){
if(n==1){
return 1;
}else{
return n*f(n-1);
}
}
Java数组
01.什么是数组
数组的定义
- 数组是相同类型数据的有序集合。
- 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。
- 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问他们。
02.数组的声明和创建
-
首先必须声明数组变量,才能在程序中使用数组。
-
下面是声明数组变量的语法:
dataType [] arrayRefVar;//首选的方法 //或 dataType arrayRefVar[];//效果相同,但不是首选方法
-
Java 语言使用 new 操作符来创建数组,语法如下:
dataType[] arrayRefVar = new dataType[arraySize];
-
数组的元素是通过索引访问的,数组索引从 0 开始。
-
获取数组长度:
arrays.length
例子:
//变量的类型 变量的名字 = 变量的值
int[]nums;//声明一个数组
nums = new int[10];//创建一个数组
//声明和创建
//int[] nums = new int[10];
//给数组元素赋值
nums[0] = 1;
nums[1] = 2;
nums[2] = 3;
nums[3] = 4;
nums[4] = 5;
nums[5] = 6;
nums[6] = 7;
nums[7] = 8;
nums[8] = 9;
nums[9] = 10;
System.out.println(nums[0]);//1
System.out.println(nums[9]);//10
//若不给nums[9]赋值,int 默认输出结果为 0
//计算所有元素的和
int sum = 0;
//获取数组长度:arrays.length
for(int i = 0;i < nums.length; i++){
sum = sum + nums[i];
}
System.out.println("总和为:"+sum);//总和为:55
03.三种初始化和内存分析
三种初始化
-
静态初始化
//静态初始化:创建 + 赋值 int [] a = {1,2,3}; Man[] mans = {new Man(1,1),new Man(2,2)};//引用数组
-
动态初始化
//动态初始化:包含默认初始化 int[] a = new int[2]; a[0]=1; a[1]=2;
-
数组的默认初始化
- 数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐藏初始化。
内存分析
- Java 内存分析:
04.下标越界及小结
数组的四个基本特点
- 其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
- 其元素必须是相同类型,不允许出现混合类型。
- 数组中的元素可以是任何数据类型,包括基本数据类型和引用类型。
- 数组变量属于引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java 中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。
数组边界
-
下标的合法区间:[0,length-1],如果越界就会报错;
public static void main(String[] args){ int[] a = new int[2]; System.out.println(a[2]); }
-
ArrayIndexOutOfBoundsException:数组下标越界异常!
小结:
- 数组是相同数据类型(数据类型可以为任意类型)的有序集合。
- 数组也是对象。数组元素相当于对象的成员变量。
- 数组长度的确定的,不可变的。如果越界,则报:ArrayIndexOutOfBounds
05.数组的使用
- 普通的 For 循环
int[] arrays = {1,2,3,4,5};
//打印全部的数组元素
for(int i = 0;i < arrays.length;i++){
System.out.println(arrays[i]);
}
System.out.println("==================");
//计算所有元素的和
int sum = 0;
for(int i = 0;i < arrays.length;i++){
sum += arrays[i];
}
System.out.println("sum="+sum);
System.out.println("==================");
//查找最大元素
int max = arrays[0];
for(int i = 1;i < arrays.length;i++){
max = arrays[i];
}
System.out.println("max="+max);
/*
运行结果:
1
2
3
4
5
==================
sum=15
==================
max=5
*/
- For-Each 循环
//JDK 1.5,没有下标
int[] arrays = {1,2,3,4,5};
for(int array:arrays){
System.out.println(array);
}
/*
运行结果:
1
2
3
4
5
*/
- 数组作方法入参
public static void main(String[] args){
int[] arrays = {1,2,3,4,5};
printArray(arrays);//1 2 3 4 5
}
//打印数组元素
public static void printArray(int[] arrays){
for(int i = 0;i < arrays.length;i++){
System.out.print(arrays[i]+" ");//1 2 3 4 5
}
}
- 数组作返回值
public static void main(String[] args){
int[] arrays = {1,2,3,4,5};
int[] reverse = reverse(arrays);
printArray(reverse);//5 4 3 2 1
}
public static int[] reverse(int[] arrays){
int[] result = new int[arrays.length];
//反转的操作
for(int i = 0,j = result.length-1;i < arrays.length;i++,j--){
result[j] = arrays[i];
}
return result;
}
//打印数组元素
public static void printArray(int[] arrays){
for(int i = 0;i < arrays.length;i++){
System.out.print(arrays[i]+" ");
}
}
06.二维数组
多维数组
- 多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。
- 二维数组:
int a[][] = new int[2][5];
- 解析:以上二维数组 a 可以看成一个两行五列的数组。
例子:
//[4][2]
/*
1,2 array[0]
2,3 array[1]
3,4 array[2]
4,5 array[3]
*/
int[][] array = {{1,2},{2,3},{3,4},{4,5}};
System.out.pintln(array[2][0]);//3
System.out.pintln(array[2][1]);//4
System.out.pintln(array.length);//4
System.out.pintln(array[0].length);//2
for(int i = 0;i < array.length;i++){
for(int j = 0;j < array[i].length;i++){
System.out.pintln(array[i][j]);
}
}
07.Arrays类讲解
- 数组的工具类 java.util.Arrays
- 由于数组对象本身并没有什么方法可以供我们调用,但 API 中提供了一个工具类 Arrays 供我们使用,从而可以对数据对象进行一些基本的操作。
- ==查看 JDK 帮助文档
- Arrays 类中的方法都是 static 修饰的静态方法,在使用的时候可以直接使用类名进行调用,而“不用”使用对象来调用(注意:是“不用”而不是“不能”)
- 具有以下常用功能:
- 给数组赋值:通过 fill 方法。
- 对数组排序:通过 sort 方法,按升序。
- 比较数组:通过 equals 方法比较数组中元素值是否相等。
- 查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作。
例子:
public static void main(String[] args){
int[] a = {1,2,3,4,9090,31231,543,21,3,23};
System.out.pintln(a);//[I@4554617c
//打印数组元素 Arrays.toString
System.out.pintln(Arrays.toString(a));//[1, 2, 3, 4, 9090, 31231, 543, 21, 3, 23]
pringtArray(a);//[1, 2, 3, 4, 9090, 31231, 543, 21, 3, 23]
Arrays.sort(a);//数组进行排序:升序
System.out.pintln(Arrays.toString(a));//[1, 2, 3, 3, 4, 21, 23, 543, 9090, 31231]
}
public static void printArray(int[] a){
for(int i = 0;i < a.length;i++){
if(i==0){
System.out.pintln("[");
}
if(i==a.length-1){
System.out.pintln(a[i]+"]");
}else{
System.out.pintln(a[i]+", ");
}
}
}
08.冒泡排序
- 冒泡排序无疑是最出名的排序算法之一,总共有八大排序。
- 冒泡的代码还是相当简单的,两层循环,外层冒泡轮数,里层依次比较,江湖中人尽皆知。
- 这个算法的时间复杂度为O(n2)。
/*
冒泡排序:
1、比较数组中,两个相邻的元素,如果第一个数比第二个数大,我们就交换他们的位置
2、每一次比较,都会产生出一个最大,或者最小的数字
3、下一轮则可以少一次排序!
4、依次循环,直到结束!
*/
public static void main(String[] args){
int[] a = {1,4,5,6,72,2,2,2,25,6,7};
int[] sort = sort(a);//调用完我们的自己写的排序方法以后,返回一个排序后的数组
System.out.println(Arrays.toString(sort)); //[72, 25, 7, 6, 6, 5, 4, 2, 2, 2, 1]
}
public static void sort(int[] array){
//临时变量
int temp = 0;
//外层循环,判断我们这个要走多少次;
for(int i = 0;i < array.length-1;i++){
boolean flag = false;//通过 flag 标识位减少没有意义的比较
//内层循环,比价判断两个数,如果第一个数,比第二个数大,则交换位置
for(int j = 0;j < array.length-1-i;j++){
if(array[j+1]>array[j]){
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
flag = true;
}
}
if(flag==false){
break;
}
}
}
09.稀疏数组
- 需求:编写五子棋游戏中,有存盘退出和续上盘的功能。
- 分析问题:因为该二维数组的很多默认值为 0 ,因此记录了很多没有意义的数据。
- 解决:稀疏数组
稀疏数组的介绍
- 当一个数组中大部分元素为 0 ,或者为同一值的数组时,可以使用稀疏数组来保存该数组。
- 稀疏数组的处理方式是:
- 记录数组一共有几行几列,有多少个不同值
- 把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模
public static void main(String[] args){
//1、创建一个二维数组 11 * 11 0:没有棋子,1:黑棋,2:白棋
int[][] array1 = new int[11][11];
array1[1][2] = 1;
array1[2][3] = 2;
//输出原始的数组
System.out.println("输出原始的数组");
for(int[] ints : array1){
for(int anInt : ints){
System.out.print(anInt+"\t");
}
System.out.println();
}
//转换为稀疏数组保存
//获取有效值的个数
int sum = 0;
for (int i = 0; i < 11; i++){
for(int j = 0;j < 11; j++){
if(array1[i][j]!=0){
sum++;
}
}
}
System.out.println("有效值的个数:"+sum);
//2、创建一个稀疏数组的数组
int[][] array2 = new int[sum+1][3];
array2[0][0] = 11;
array2[0][1] = 11;
array2[0][2] = sum;
//遍历二维数组,将非零的值,存放稀疏数组中
int count = 0;
for(int i = 0;i < array1.length;i++){
for(int j = 0;j < array1[i].length;j++){
if(array1[i][j]!=0){
count++;
array2[count][0] = i;
array2[count][1] = j;
array2[count][2] = array1[i][j];
}
}
}
//输出稀疏数组
System.out.println("稀疏数组");
for(int i = 0;i < array2.length;i++){
System.out.println(array2[i][0]+"\t"
+array2[i][1]+"\t"
+array2[i][2]+"\t");
}
System.out.println("还原");
//1、读取稀疏数组
int[][] array3 = new int[array2[0][0]][array2[0][1]];
//2、给其中的元素还原它的值
for(int i = 1;i < array2.length;i++){
array3[array2[i][0][array2[i][1]] = array2[i][2];
}
//3、打印
System.out.println("输出还原的数组");
for(int[] ints : array3){
for(int anInt : ints){
System.out.print(anInt+"\t");
}
System.out.println();
}
}
面向对象
01.什么是面向对象
面向过程 & 面向对象
- 面向过程思想
- -步骤清晰简单,第一步做什么,第二步做什么…
- 面向过程适合处理一些较为简单的问题
- 面向对象思想
- 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
- 面向对象适合处理负责的问题,适合处理需要多人协作的问题!
- 对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。
什么是面向对象
- 面向对象编程(Object-Oriented Programming,OOP)
- 面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据。
- 抽象
- 三大特性:
- 封装
- 继承
- 多态
- 从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象
- 从代码运行角度考虑是先有类后有对象。类是对象的模板。
02.回顾方法的定义
- 方法的定义
- 修饰符
- 返回类型
- break :跳出 switch ,结束循环 和 return 的区别
- 方法名:注意规范 见名知意
- 参数列表:(参数类型,参数名)…
- 异常抛出:疑问,后面讲解
//Demo01 类
public class Demo01{
//main 方法
public static void main(String[] args){
}
/*
修饰符 返回值类型 方法名(...){
//方法体
return 返回值;
}
*/
//return:结束方法,返回一个结果!
public String sayHello(){
return"hello,word";
}
public void print(){
return;
}
public int max(int a,int b){
return a > b ? a : b;//三元运算符!
}
//数组下标越界:Arrayindexoutofbounds
public void readFile(String file) throws IOException{
}
}
03.回顾方法的调用
- 方法的调用:递归
- 静态方法
- 非静态方法
- 形参和实参
- 值传递和引用传递
- this 关键字
//学生类
public class Student{
//静态方法
public static void say(){
System.out.println("学生说话了");
}
}
public class Demo02{
public static void main(String[] args){
Student.say();//学生说话了
}
}
//学生类
public class Student{
//非静态方法
public void say(){
System.out.println("学生说话了");
}
}
public class Demo02{
public static void main(String[] args){
//实例化这个类 new
//对象类型 对象名 = 对象值
Student student = new Student();
student.say();
}
//和类一起加载的
public static void a(){
//b();
}
//类实例化 之后才存在
public void b(){
}
}
public class Demo03{
public static void main(String[] args){
//实际参数和形式参数的类型要对应!
int add = Demo03.add(1,2);
System.out.println(add);
}
public static int add(int a,int b){
return a+b;
}
}
//值传递
public class Demo04{
public static void main(String[] args){
int i = 1;
System.out.println(a);//1
Demo04.change(a);
System.out.println(a);//1
}
//返回值为空
public static void change(int a){
a = 10;
}
}
//引用传递:对象,本质还是值传递
public class Demo05{
public static void main(String[] args){
Person person = new Person();
System.out.println(person.name);//null
Demo05.change(person);
System.out.println(person.name);//阿清
}
public static void change(Person person){
//person 是一个对象:指向的--->Person person = new Person();这是一个具体的人,可以改变属性!
person.name = "阿清";
}
}
//定义了一个Person类,有一个属性:name
class Person{
String name;//null
}
04.类与对象的创建
类与对象的关系
- 类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物。
- 动物、植物、手机、电脑…
- Person 类、Pet 类、Car 类等,这些类都是用来描述/定义某些具体的事物应该具备的特点和行为
- 对象是抽象概念的具体实例
- 张三就是人的一个具体实例,张三家里的旺财就是狗的一个具体实例。
- 能够体现出特点,展现出功能的是具体的实例,而不是一个抽象的概念。
创建与初始化对象
- 使用 new 关键字创建对象
- 使用 new 关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
//学生类
public class Student{
//属性:字段
String name;//默认值为 null
int age;//默认值为 0
//方法
public void study(){
System.out.println(this.name+"学生在学习");
}
}
//一个项目应该只存在一个 main 方法
public class Application{
public static void main(String[] args){
//类:抽象的,实例化
//类实例化后会返回一个自己的对象!
//student 对象就是一个 Student 类得到具体实例!
Student xiaoming = new Student();
Student xiaohong = new Student();
xiaoming.name = "小明";
xiaoming.age = 18;
System.out.println(xiaoming.name);//小明
System.out.println(xiaoming.age);//18
System.out.println(xiaohong.name);//null
System.out.println(xiaohong.age);//0
}
}
05.构造器详解
- 类中的构造器也称为构造方法,是在进行创建对象的时候必须调用的。并且构造器有以下两个特点:
- 1、必须和类的名字相同
- 2、必须没有返回类型,也不能写 void
- 构造器必须要掌握
public class Person{
//一个类即使什么都不写,它也会存在一个方法
//显示的定义构造器
String name;
//实例化初始值
//1、使用 new 关键字,本质是在调用构造器
//2、用来初始化值
//无参构造(默认的)
public Person(){
this.name = "阿清";
}
//有参构造:一旦定义了有参构造,无参就必须显示定义
public Person(String name){
this.name = name;
}
// Alt + Insert 会生成构造器
}
//一个项目应该只存在一个 main 方法
public class Application{
public static void main(String[] args){
//类:抽象的,实例化
//类实例化后会返回一个自己的对象!
//new 实例化了一个对象
Person person = new Person();
System.out.println(person.name);//阿清
Person person = new Person("北北");
System.out.println(person.name);//北北
}
}
/*
构造器:
1、和类名相同
2、没有返回值
作用:
1、new 本质在调用构造方法
2、初始化对象的值
注意点:
1、定义有参构造之后,如果想使用无参构造,显示的定义一个无参的构造
Alt + Insert 会生成构造器
*/
06.创建对象内存分析
07.简单小结与对象
/*
1、类与对象
类是一个模板:抽象,对象是一个具体的实例
2、方法
定义、调用!
3、对应的引用
引用类型: 基本类型(8)
对象是通过引用来操作的:栈--->堆
4、属性:字段 Field 成员变量
默认初始化:
数字:0 0.0
char:u0000
boolean:false
引用:null
修饰符 属性类型 属性名 = 属性值!
5、对象的创建和使用
- 必须使用 new 关键字创建对象,构造器 Person person = new Person();
- 对象的属性 person.name
- 对象的方法 person.sleep()
6、类;
静态的属性 属性
动态的行为 方法
封装、继承、多态
*/
08.封装详解
- 该露的露,该藏的藏
- 我们程序设计要追求==“高内聚,低耦合”==。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。
- 封装(数据的隐藏)
- 通常,应禁止直接访问一个对象中数据的实际表示,而通过操作接口来访问,这称为信息隐藏。
- 属性私有,get/set
public class Student{
//属性私有
private String name;//名字
private int id;//学号
private char sex;//性别
private int age;
//提供一些可以操作这个属性的方法!
//提供一些 public 的 get、set 方法
//get 获得这个数据
public String getName(){
return this.name;
}
//set 给这个数据设置值
public void setName(String name){
this.name = name;
}
// Alt + Insert 快捷键
public int getId(){
return id;
}
public void setId(int id){
this.id = id;
}
public char getSex(){
return sex;
}
public void setSex(char sex){
this.sex = sex;
}
public int getAge(){
return age;
}
public void setAge(int age){
if(age >120 || age <0){
age = 3;
}else{
this.age = age;
}
}
}
/*
1、提高程序的安全性,保护数据
2、隐藏代码的细节
3、统一接口
4、系统可维护性增加了
*/
public class Application{
public static void main(String[] args){
Student s1 = new Student();
s1.setName("阿清");
System.out.println(s1.getName());//阿清
s1.setAge(999);//不合法
System.out.println(s1.getAge());//3
}
}
09.什么是继承
- 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
- extands 的意思是“扩展”。子类是父类的扩展。
- JAVA 中类只有单继承,没有多继承!
- 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
- 继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字 extends 来表示。
- 子类和父类之间,从意义上讲应该具有“ is a ”的关系。
- object 类
- super
- 方法重写
//在 Java 中,所有的类,都默认直接或间接继承 Object
//Person 人:父类
public class Person{
public int money = 10_0000_0000;
public void say(){
System.out.println("说了一句话");
}
}
//学生 is 人:派生类,子类
//子类继承了父类,就会拥有父类的全部方法!
public class Student extends Person{
// Ctrl + H
}
public class Application{
public static void main(String[] args){
Student student = new Student();
student.say();//说了一句话
System.out.println(student.money);//1000000000
}
}
10.Super 详解
//在 Java 中,所有的类,都默认直接或间接继承 Object
//Person 人:父类
public class Person/*extends Object*/{
public Person(){
System.out.println("Person无参执行了");
}
protected String name = "aqing";
//私有的东西无法被继承!
public void print(){
System.out.println("Person");
}
}
//学生 is 人:派生类,子类
//子类继承了父类,就会拥有父类的全部方法!
public class Student extends Person{
public Student(){
//隐藏代码:调用了父类的无参构造
super();//调用父类的构造器,必须要在子类构造器的第一行
System.out.println("Student无参执行了");
}
protected String name = "beibei";
public void test{
System.out.println(name);//北北
System.out.println(this.name);//beibei
System.out.println(super.name);//aqing
}
public void print(){
System.out.println("Student");
}
public void test1{
print();//Student
this.print();//Student
super.print();//Person
}
}
public class Application{
public static void main(String[] args){
Student student = new Student();
student.test("北北");
student.test1();
}
}
-
supper 注意点:
- super 调用父类的构造方法,必须在构造方法的第一个
- super 必须只能出现在子类的方法或者构造方法中!
- super 和 this 不能同时调用构造方法!
-
Vs this:
- 代表的对象不同:
- this:本身调用这个对象
- super:代表父类对象的应用
- 前提:
- this:没有继承也可以用
- super:只能在继承条件下才能使用
- 构造方法:
- this();本类的构造!
- super();父类的构造!
- 代表的对象不同:
11.方法重写
//继承
public class A extends B{
public static void test(){
System.out.println("A=>test()");
}
}
//重写都是方法的重写,和属性无关
public class B{
public static void test(){
System.out.println("B=>test()");
}
}
public class Application{
//静态的方法和非静态的方法区别很大!
public static void main(String[] args){
//静态方法:方法的调用只和左边,定义的数据类型有关!
//非静态:重写
A a = new A();
a.test();// A
//父类的引用指向了子类
B b = new A();//子类重写了父类的方法
b.test();// B
}
}
- 重写:需要有继承关系,子类重写父类的方法!
- 1、方法名必须相同
- 2、参数列表列表必须相同
- 3、修饰符:范围可以扩大但不能缩小:public>protected>default>private
- 4、抛出的异常:范围可以被缩小但不能扩大:ClassNotFoundException(小)–>Exception(大)
- 重写,子类的方法和父类必须要一致:方法体不同
- 为什么要重写?
- 父类的功能,子类不一定要需要,或者不一定满足!
- Alt + Insert:override
12.什么是多态
- 动态编译:类型:可拓展性
- 即同一方法可以根据发送对象的不同而采取多种不同的行为方式。
- 一个对象的实际类型是确定的,但可以指向对象的引用类型有很多。
- 多态存在的条件:
- 有继承关系
- 子类重写父类方法
- 父类引用指向子类对象
- 注意:多态是方法的多态,属性没有多态性。
public class Student extends Person{
@Override
public static run(){
System.out.println("son");
}
public static eat(){
System.out.println("eat");
}
}
public class Person{
public static run(){
System.out.println("run");
}
}
public class Application{
public void out(){
System.out.println("这是外部类的方法");
}
// 一个对象的实际类型是确定的
// new Student();
// new Person();
// 可以指向的引用类型就不确定了:父类的引用指向子类
// Student 能调用的方法都是自己的或者继承父类的!
Student s1 = new Student();
// Person 父类型,可以指向子类,但是不能调用子类独有的方法
Person s2 = new Student();
Object s3 = new Student();
// 对象能执行哪些方法,主要看对象左边的类型和右边关系不大
s2.run();// run // son // 子类重写了父类的方法,执行子类的方法
s1.run();// son
s1.eat();// eat
s2.eat();// 报错 // 可以通过转换((Student)s2).eat();
}
}
- 多态注意事项:
- 1、多态是方法的多态,属性没有多态
- 2、父类和子类,有联系 类型转换异常!ClassCastException!
- 3、存在条件:继承关系,方法需要重写,父类的引用指向子类对象!Father f1 = new Son();
- 不能重写的方法:
- 1、static 方法,属于类,它不属于实例
- 2、final 常量
- 3、private 方法
13.instance of 和类型转换
- instance of (类型转换) 引用类型,判断一个对象是什么类型,是否存在父子关系~
public class Student extends Person{
public void go(){
System.out.println("go");
}
}
public class Teacher extends Person{
public static run(){
System.out.println("run");
}
}
public class Person{
public static run(){
System.out.println("run");
}
}
public class Application{
public static void main(String[] args){
// 类型之间的转换:父 子
// 子类转换为父类可能会丢失自己本来的一些方法!
// 高 低
Person student = new Student();
// student 将这个对象转换为 Student 类型,我们就可以使用 Student 类型的方法了!
Student student = (Student) obj;
student.go();
// 等于上面两句话((Student)obj).go();
// Object > Person > Teacher
// Object > Person > Student
// System.out.println(x instanceof y);//能不能编译通过!
Object object = new Student();
System.out.println(object instanceof Student);// true
System.out.println(object instanceof Person);// true
System.out.println(object instanceof Object);// true
System.out.println(object instanceof Teacher);// False
System.out.println(object instanceof String);// False
Person person = new Student();
System.out.println(person instanceof Student);// true
System.out.println(person instanceof Person);// true
System.out.println(person instanceof Object);// true
System.out.println(person instanceof Teacher);// False
// System.out.println(person instanceof String);// 编译报错!
Student student = new Student();
System.out.println(student instanceof Student);// true
System.out.println(student instanceof Person);// true
System.out.println(student instanceof Object);// true
// System.out.println(student instanceof Teacher);// 编译报错!
// System.out.println(student instanceof String);// 编译报错!
}
}
- 注意事项:
1、父类引用指向子类的对象
2、把子类转换为父类,向上转型;
3、把父类转换为子类,向下转型;强制转换
4、方便方法的调用,减少重复的代码,简洁
14.static 关键字详解
//static
public class Student {
private static int age;// 静态的变量
private double score;// 非静态的变量
public static void main(String[] args){
Student s1 = new Student();
System.out.println(Student.age);
//System.out.println(Student.score);
System.out.println(s1.age);
System.out.println(s1.score);
}
}
public class Person{
// 2:赋初始值
{
System.out.println("匿名代码块");//代码块(匿名代码块)
}
// 1:只执行一次
static{
System.out.println("静态代码块");//静态代码块
}
// 3
public Person(){
System.out.println("构造方法");
}
public static void main(String[] args){
Person person1 = new Person();
public static void main(String[] args){
Person person2 = new Person();
}
/*
运行结果:
静态代码块
匿名代码块
构造方法
==================
匿名代码块
构造方法
*/
}
package com.oop.demo01;
// 静态导入包
import static java.lang.Math.random;
import static java.lang.Math.PI;
public class Test{
public static void main(String[] args){
System.out.println(random());
System.out.println(PI);
}
}
15.抽象类
- abstract 修饰符可以用来修饰方法也可以用来修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。
- 抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。
- 抽象类,不能使用 new 关键字来创造对象,它是用来让子类继承的。
- 抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。
- 子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。
// abstract 抽象类:类 extends:单继承(接口可以多继承)
public abstract class Action{
// 约束!有人帮我们实现
// abstract 抽象方法,只有方法的名字,没有方法的实现!
public abstract void doSomething();
//1、不能 new 这个抽象类,只能靠子类去实现它:约束!
//2、抽象类中可以写普通方法
//3、抽象方法必须写在抽象类中
// 抽象的抽象:约束
}
// 抽象类的所有方法,继承了它的子类,都必须要实现它的方法,除非
public class A extends Action{
@Override
public void doSomething(){
}
}
思考:抽象类不能 new ,存在构造器吗?存在的意义?
16.接口的定义与实现
-
普通类:只有具体实现
-
抽象类:具体实现和规范(抽象方法)都有!
-
接口:只有规范!自己无法写方法!专业的约束!约束和现实分离:面向接口编程~
-
接口就是规范,定义的是一组规则,体现了现实世界中“如果你是…则必须能…”的思想。如果你是天使,则必须能飞。如果你是汽车,则必须能开。如果你是好人,则必须干掉坏人;如果你是坏人,则必须欺负好人。
-
接口的本质是契约,就像我们人间的法律一样,制定好后大家都要遵守。
-
oo的精髓,是对对象的抽象,最能体现这一点的就是接口。
声明类的关键字是 class,声明接口的关键字是 interface。
// 抽象的思维
// interface 定义的关键字,接口都需要有实现类
public interface UserService{
// 常量 public static final
public static final int age = 99;
// 接口中的所有定义的方法其实都是抽象的 public abstract
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
public interface TimeService{
void timer();
}
// 抽象类:extends~
// 类 可以实现接口 implements 接口
// 实现了接口的类,就需要重写接口中的方法~
// 多继承~利用接口实现多继承!
public class UserServiceImpl implement UserService,TimeService{
@Override
public void add(String name){
}
@Override
public void delete(String name){
}
@Override
public void update(String name){
}
@Override
public void query(String name){
}
@Override
public void timer(){
}
}
- 作用:
1、约束
2、定义一些方法,让不同的人实现!10 ~ 1
3、public abstract
4、public static final
5、接口不能被实例化!接口中没有构造方法!
6、implements 可以实现多个接口
7、必须重写接口中的方法!
17.N 种内部类
- 内部类就是在一个类的内部定义了一个类,比如,A 类中定义了一个 B 类,那么 B 类相对 A 类来说就称为内部类,而 A 类相对 B 类来说就是外部类了。
public class Outer{
private int id = 10;
public void out(){
System.out.println("这是外部类的方法");
}
public class Inner{
public void in(){
System.out.println("这是内部类的方法");
}
//获得外部类的私有属性!
public void getID(){
System.out.println(id);
}
}
}
public class Application{
public static void main(String[] args){
// new
Outer outer = new Outer();
// 通过这个外部类来实例化内部类!
Outer.Inner inner = outer.new Inner();
inner.getID();//10
}
}
异常
什么是异常?
- 实际工作中,遇到的情况不可能是非常完美的。
- 软件程序在运行过程中,非常可能遇到刚刚提到的这些异常问题,我们叫异常,英文是:Exception,意思是例外。这些,例外情况,或者叫异常,怎么让我们写的程序做出合理的处理。而不至于程序崩溃。
- 异常指程序运行中出现的不期而至的各种状况,如:文件找不到、网络连接失败,非法参数等。
- 异常发生在程序运行期间,它影响了正常的程序执行流程。
简单分类
- 三种类型的异常:
- 检查型异常:最具代表的检查型异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
- 运行时异常:运行时异常是可能被程序员避免的异常。与检查型异常相反,运行时异常可以在编译时忽略。
- 错误 ERROR :错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,他们在编译也检查不到的。
异常体系结构
- Java 把异常当作对象来处理,并定义一个基类 java.lang.Throwable 作为所有异常的超类。
- 在 Java API 中已经定义了许多异常类,这些异常类分为两大类,错误 Error 和异常 Exception 。
01.Error和Exception
Error
- Error 类对象由 Java 虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关。
- Java 虚拟机运行错误(Virtual MachineError),当 JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。这些异常发生时,Java 虚拟机(JVM)一般会选择线程终止。
- 还有发生在虚拟机试图执行应用时,如类定义错误