1.JAVA简介
1.1JDK,JREMJVM
Jvm:Java Virtual Machine Java虚拟机
Jre:Java Runtime Environment Java运行环境
Jdk:Java Development Kit Java 开发环境
Jdk Jre Jvm关系(从JAVA11版本之后不会再单独提供JDK了)
1.2安装JDK
选择Oracle官网:https://www.oracle.com/index.html
注意安装路径不能含有中文或者空格
- win+R (打开cmd)
- 输入bin目录路径+java-version,检验能否显示JAVA版本
1.3配置环境变量
电脑>属性>高级系统设置>环境变量>系统变量path>添加变量(到JDK bin的路径)
1.4第一份码源
- 方法中带有static的方法不从属于任何对象
- 方法中的每行代码都需以英文分号(;)结尾
在这里插入图片描述
记事本打开>cmd后输入notepad
1.4.1在cmd中运行java程序
- 编写java源文件
- 运行java源文件
- 运行java字节码
-
在记事本中编写程序保存
-
打开cmd 输入源文件根目录 eg: d:
-
输入:javac+空格+源文件名.java eg:javac Hello.java 得到类文件(源文件名字打到一半可以用Tab键补齐)
-
输入:java+空格+类名(不是类文件名) eg:java A
1.5常见问题-中文乱码
在记事本中含有中文编写的源码在javac中输出后为什么是乱码?
答:是因为二者使用编码不同,记事本中源文件编码使用UTF-8 javac中编码使用的是GBK
1.更换源文件编码
如何解决中文乱码问题?(思想:让二者编码保持一直,向左看齐,或者向右看齐)
2.更换javac编码
1.6注释
单行注释: //人民有信仰
多行注释: /*国家有力量 */
文档注释:/** 民族有希望 */
1.7为何要字节码
优点:减少了编译成本,增加了灵活性
缺点:降低了一部分性能
1.8开发工具和实用工具
开发者工具IDE((IDE Integrated Development Environment))
实用工具
Fluent(微软商店)
2.开发命令行程序
2.1输入输出
输入:使用者告诉程序要操作的数据
输出:程序向使用者展示执行的结果
输入输出源有多种:比如app,网页,终端程序
3.JAVA基础
3.1标识符和关键字
关键字:
Java所有组成的部分都需要名字。类名,变量名以及方法名都被称为标识符
标识符注意点
- 所有的标识符都应以大小写字母,美元符($)或者下划线开始(_)
- 首字母之后可以是大小写字母,美元符($),下划线(_)或者数字的任何组合
- 不能使用关键字作为变量名或者方法名
- 标识符是大小写敏感的
- 长度没有限制
- 中文或者其他语言的文字的变量名能够通过编译,但不建议使用
- Java 9中,单下划线_不能作为变量名
合法的标识符举例:AS568,$_565,
不合法标识符举例:7asH,A&232
3.2数据类型
强类型语言(Java)
要求变量的使用要严格符合规定,所有的变量都必须先定义后才能使用(提高了安全性,但降低了速度)
Java的数据类型分为俩大类
基本类型(primitive type)
引用类型(reference type)
浮点类型:float,double
- 与整数类型相似,也有固定表数范围和字段长度,不受具体OS的影响
- Java的浮点型常量默认为double型,声明float型常量,须后加’f’或’F’
- 单精度float精度是7位有效数字,双精度double精度位16位有效数字
布尔类型:boolean
- boolean类型适用于逻辑运算,一般用于程序流程控制:
- if条件控制语句
- while循环控制语句
- do-while循环控制语句
- for循环控制语句
- boolean类型数据只允许取值true和false,无null
- 不可以0或非0整数代替false和true,这点和C语言不同
//八大基本数据类型
//整数
int num1=10;//最常用
byte num2=20;
short num3=30;
long num4=40L;//long类型要在后面加个L
//小数 //浮点数
float num5=50.1F;//float后面要加F
double num6=3.123456;
//字符
char name='B';char name5='国'; //char字符类型用单引号''
//字符串,String不是关键字,是类
String name7="托尔";
//布尔值
boolean flag=true;
boolean flag1=false;
//Ctrl+B查看类详细情况
什么是字节
- bit(位):是计算及内部存储的最小单位
- byte(字节):是计算机中数据处理的基本单位,习惯上用大写B来表示
- 1B=8bit
- 字符:指计算机中实用的字母,数字和符号
3.3数据类型拓展
3.3.1整数拓展
//整数拓展 进制 二进制0b 十进制 八进制0 十六进制0x
int i = 10;
int i2 = 010;
int i3 = 0b10;
int i4 = 0x10; //16进制常用0-9 A-F表示 其中A-F表示为10-15的数字
3.3.2浮点数拓展
银行业务使用浮点数类型操作会怎么样?
//浮点数拓展? 银行业务怎么表示? 钱
float _1 = 0.01f;
double A777 = 0.1 / 10;
System.out.println(_1 == A777);
System.out.println(_1);
System.out.println(A777);
float $5 = 77777777775623f;
double _xiaowang = $5 + 1;
第一组俩个变量的数值都相等,但返回的结果是false
第二组可以看出俩个变量的数值不相等,但结果确返回了true
结论:浮点数表示的字长是有限的,会存在舍入误差 的情况,只会得到一个大约数(即接近但不等于)
- 所以最好完全避免使用浮点数进行比较
- 银行业务可以使用BigDecimal(数学工具类)表示
3.3.3字符拓展
//字符拓展?
//===========================================
System.out.println("============================================");
char c1 = 'A';
char c2 = '中';
System.out.println(c1);
System.out.println((int) c1);//强制转换
System.out.println(c2);
System.out.println((int) c2);//强制转换
//所有字符本质都是数字
//编码 Unicode 有一个编码表:97=a 65=A 2字节 0-65536 早些年用的 Excel 2*16=65536
//u0000 uffff区间范围
//转义字符
// \t 制表符
// \n 换行
System.out.println("Hello\tWorld");
System.out.println("Hello\nWorld");
对象,内存分析
String sa = new String("hello world");
String sb = new String("hello world");//original 是String后在括号中打双引号自己生成的
System.out.println(sa == sb);
String sc = "hello world";
String sd = "hello world";
System.out.println(sc == sd);
3.3.4布尔值拓展
boolean flag=true;
if(flag==true){}
if(flag){}//二者完全相同 第一种是新手写法 第二种是老手写法
//Less is more! 代码要精简
3.4类型转换
3.4.1强制换换,自动转换
- 由于Java是强类型语言,所以进行有些运算的时候,需要强制转换
低------------------------------------------------------------------>高
byte,short,char->int->long->float->double
- 运算中,不同类型先转化为同一类,在进行计算
- 强制类转换
int i=128;
byte b= (byte) i;// 内存溢出(超出数据类型的取值范围)
//强制类型转换 格式:(类型)变量名 由高到低
- 自动类转换
byte z=123;
int _7=z;
System.out.println(z);
System.out.println(_7);
注意点:
- 不能对boolean进行转换
- 高容量转换为低容量时,需要强制转换(格式:(类型)变量名),低容量转换为高容量时,则自动转换
- 转换的时候可能存在内存溢出,或者精度问题
- 不能把对象类型转换为不相干的类型
char c='a';
int d=c+1;
System.out.println(d);
System.out.println((char)d);
3.4.2内存溢出问题及解决
//操作比较大的数的时候,注意溢出问题
int money=10_0000_0000; //JDK7新特性,数字之间可以用下划线分割
int year=20;
int total1=money*year;
long total2=money*year;
long total3=money*(long)year;
System.out.println(total1);//-1474836480 计算的时候已经溢出了
System.out.println(total2);//-1474836480 计算之前就已经溢出了
System.out.println(total3);//先把一个数转换高级类型,可以解决溢出问题
//eg:在类型转换中,后面跟的字母要写大写,避免小写 L 和 l
- JDK7 新特性,数字之间可以用下划线’_'来分割
- 如果俩个低容量的数据运算后超出取值范围,可以先把一个低容量类型转变为高容量类型,即可解决溢出问题
- 在类型转换中,后面跟的字母要大写,避免小写 eg:小写的l看起来像数字1
3.5变量
- 变量:就是可以变化的量
- Java是一种强类型语言,每个变量必须声明其类型
- Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域
type varName [=value] [{,varName[=value]}];
//数据类型 变量名 = 值;可以使用逗号隔开来声明多个同类型变量
注意事项:
- 每个变量都必须有类型,类型可以是基本类型,也可以是引用类型
- 变量名必须是合法的标识符
- 变量声明是一条完整的语句,所以每一个声明后面都必须以分号结束
//int a,b,c
//int a=1,b=2,c=3; 不提倡把定义变量写在一行,程序要注重可读性
//举例定义一些变量
int a=7;
double pai=3.1415926;
String namen="Wang xuebin";
char A='B';
不提倡把定义变量写在一行,保证程序的可读性
3.5.1变量作用域
类变量,实例变量,局部变量
public class Demo0601 {
//类变量 static
static double salary=2500;
//实例变量:从属于对象:如果不自行初始化,这个类型的默认值为 0或0.0
//布尔值:默认是false
//除了基本类型,其余默认值都是null
String name;
int age;
//属性:变量
//main方法
public static void main(String[] args) {
//局部变量:必须声明和初始化,作用在括号内
//eg:
int i=10;
System.out.println(i);
//变量类型 变量名字=new com.kuang.base.Demo0601();
Demo0601 demo0601 = new Demo0601();
System.out.println(demo0601.age);
System.out.println(demo0601.name);
System.out.println(salary);
}
- 局部变量:必须声明和初始化,作用在方法内
- 实例变量:在类以内方法以外,从属于对象。如果不自行初始化,这个类型的默认值为0或0.0
- 布尔值:布尔值做实例变量时,默认值是false
- 做实例变量时,除了基本类型,其余的默认值都是null
- 类变量:通常又被称为静态变量
3.5.2常量
- 常量(Constant):初始化(initalize)后不能在改变值!不会变动的值
- 所谓常量可以理解成一种特殊的变量,它的值被设定后,在程序运行过程中不允许被改变
final 常量名 = 值;
final double PI = 3.14; //用final关键字
- 常量名一般使用大写字符
//修饰符不分先后顺序 变量类型前面的都是修饰符
final static double PI=3.14;//等同于 static final double PI=3.14;
public static void main(String[] args) {
System.out.println(PI);
}
3.5.3变量的命名规范
- 所有的变量名,方法名,类名:见名知意
- 类成员变量:首字母小写和驼峰原则:monthSalary 除了第一个单词以外,后面的字母首字母大写
- 局部变量:首字母小写和驼峰原则
- 常量:大写字母(单词长中间可以加下划线):MAX_MIN
- 类名:首字母大写和驼峰原则:Man,Good
- 方法名:首字母小写和驼峰原则:run(),runMan()
3.6运算符
Java语言支持如下运算符
- 算数运算符:+,-,*,/,%,++,–
- 赋值运算符:=
- 关系运算符:>,<,>=,<=,==,!=,instanceof
- ==(等于) !=(不等于)
- 逻辑运算符:&&,||,!(与,或,非)
了解即可
- 位运算符:&,|,^,~,>>,<<,>>>(了解!!!)
- 条件运算符:?:
- 扩展赋值运算符:+=,-=,*=,/=
3.6.1二元运算机制
int a=10;
int b=15;
int c=20;
int d=25;
System.out.println(a+b);
System.out.println(a-b);
System.out.println(a*d);
System.out.println(a/c); //要注意结果范围
System.out.println(a/(double)c);
System.out.println(a/(float)c);
long a=1234567;
int b=123;
short c=10;
byte d=7;
System.out.println(a+b+c+d);//long类型
System.out.println(b+c+d);//int类型
System.out.println((String) (c+d));//int类型 结果类型为最高容量级 cast:转换
3.6.2关系运算符
//关系运算符返回的结果:正确 错误 布尔值形式
int a=10;
int b=20;
int c=21;
System.out.println(c%a);//取余数,在java里称之为 模运算 模运算 模运算
System.out.println(a>b);
System.out.println(a<b);
System.out.println(a==b);
System.out.println(a!=b);
3.6.3自增,自减
//++ -- 自增 自减 一元运算符
int a=3;
int b=a++; //++和=不相邻 先赋值在自增
int c=++a; //++和=相邻 先自增再赋值
System.out.println(a);
System.out.println(b);
System.out.println(c); //a++等同于a+1
- b=a++
- 先执行b=a 在执行a=a+1
- b=++a
- 先执行a=a+1,在执行b=a
3.6.4幂运算
//幂运算 在java中没有如下形式 2^3或2*2*2 很多运算,我们会使用一些工具类来操作
double pow = Math.pow(2, 3);//alt+回车键 pow 幂运算单词 ctrl+b查看源码
double pow1 = Math.pow(6, 8);
- 执行幂运算用到数学工具类Math pow(m幂运算的单词)
3.6.5逻辑运算符,位运算符
逻辑运算符
//与(and) 或(or) 非(取反)
boolean a=true;
boolean b=false;
System.out.println("a && b:"+(a&&b));//与运算俩变量都为真,结果输出ture
System.out.println("a || b:"+(a||b));//或运算一变量为真,则结果为ture
System.out.println("!(a && b):"+(!(a&&b)));//非运算,如果为真则输出假;反之结果为假则输出真
短路运算
int c=5;
boolean d=(c<4)&&(c++<4);//在与运算中先运行的结果为false 则后续不执行 如下:
System.out.println(d);
System.out.println(c);//若继续执行 则C结果输出应该为6
- d的输出结果一定为false,但c<4在前,输出结果会为 false 4,c++<4不会执行
- 若c++<4在前,则先执行该项得出c=6,然后判断结果为假,输出false 6
位运算
A = 0011 1100
B = 0000 1101
----------------------------------------------------
A&B =0000 1100 1和1相对应结果为1,其余都为0
A|B =0011 1101 0和0相对应结果为0,其余都为1
A^B =0011 0001 异或 俩位相同结果为0,不同为1
~B 1111 0010 取反 原0取1,原1取0
常见面试题 问2*8如何运行最快?
2*8 =2*2*2*2
<< 左移= *2
>> 右移= /2
0000 0000 0
0000 0001 1
0000 0010 2
0000 0100 4
0000 1000 8
0001 0000 16
0010 0000 32
0100 0000 64
1000 0000 128
*/
System.out.println(2<<6); //结果等于128
<< >> (X)=把二进制的1向左,向右移动几位。
3.6.6三元运算符及小结
扩展赋值运算符
//扩展赋值运算符
int a=10;
int b=20;
a+=b; //a = a+b
a-=b; //a = a-b
//字符串连接符 + String:""
System.out.println(""+a+b); //结果为1020 变为String下的字符 连接起来
System.out.println(a+b+""); //结果为30 因为先运算的a+b
//+有用来表示输出的作用
//X ? Y : Z
//如果x==true,则结果为y,否则结果为z
//三元运算符
int score=60;
String type = score > 60 ? "及格" +1: "不及格"; //必须掌握 开发中常用 多加练习
System.out.println(type);
运算符的优先级
3.7包机制
包的本质就是文件夹
- 为了更好地组织类,Java提供了包机制,用于区别于类名的命名空间
- 包语句的语法格式为:
- package pack1[.pack2[.pack3…]]
- 一般利用公司域名倒置作为包名
- 为了能够使用某一个包的成员,我们需要在Java程序中明确的导入包,使用"import"语句可以完成此功能
- import package[.package2…].(classname|*);
3.8JavaDoc生成文档
/**
* @author Kuangshen
* @version 1.0
* @since 1.8
*/
/**
*
* @param name
* @return
* @throws Exception
*/
public String test(String name) throws Exception {
return name;
}
// 通过命令行 javacdoc Java文件
//作业:学会查找使用IDEA生产JavacDoc文档! 面向百度编程!
JavaDoc生成文档
得到结果:
4.Java流程控制
4.1控制流程01:用户交互Scanner
-
之前学习的基本语法中我们并没有实现程序和人的交互,但是Java给我们提供了这样一个工具类,我们可以获取用户的输入。java.util.Scanner是Java5的新特征,我们可以通过Scanner类来获取用户的输入
-
基本语法
Scanner s = new Scanner(System.in);
-
通过Scanner类的next()与nextLine()方法获取输入的字符串,在读取前我们一般需要使用hasNext()与hasNextLine判断是否还有输入的数据
//创建一个扫描对象,用于接受键盘数据
Scanner scanner = new Scanner(System.in);
System.out.println("使用next方式接收:");
//判断用户有没有输入字符串
if(scanner.hasNext()==true){
//使用next方式接收
String str = scanner.next();
System.out.println("输出的内容为:"+str);
}
//凡是属于IO流的类如果不关闭会一直占用资源,要养成好习惯用完就关掉
scanner.close();
// 从键盘接收数据
Scanner scanner = new Scanner(System.in);
System.out.println("使用nextLine方式接收:");
//判断是否还有输入
if (scanner.hasNextLine()==true){
String str =scanner.nextLine();
System.out.println("输出的内容为:"+str);
}
scanner.close();
结论
next():
- 一定要读取到有效字符后才可以输入
- 对输入有效字符之前遇到的空白,next()方法会自动将其去掉
- 只有输入有效的字符后才将其后面输入的空白作为分隔符或者结束符
- next()不能得到带有空格的字符串
nextLine():
- 以Enter为结束符,也就是说nextLine()方法返回的是输入回车之前的所有字符
- 可以获得空白
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入数据:");
String str = scanner.nextLine();
System.out.println("输出的内容为:"+str);
scanner.close();
}
4.2Scanner进阶使用
小数和整数在Scanner中的使用
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//从键盘接收数据
int i = 0;
float f = 0.0f;
System.out.println("请输入整数:");
if(scanner.hasNextInt()){
i = scanner.nextInt();
System.out.println("整数数据:"+ i);
}
else {
System.out.println("输出的不是整数数据!");
}
System.out.println("请输入小数:");
if(scanner.hasNextFloat()){
f = scanner.nextFloat();
System.out.println("小数数据:"+ f);
}
else {
System.out.println("输出的不是小数数据!");
}
public static void main(String[] args) {
//我们可以输入多个数字,并求其总和与平均数,每输入一个数字用回车确认,通过输入非数字来结束输入并输出执行结果
Scanner scanner = new Scanner(System.in);
//和
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(m+"个数的和为"+sum);
System.out.println(m+"个数的平均值是"+(sum/m));
scanner.close();
4.3顺序结构
顺序结构
-
JAVA的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行
-
顺序结构是最简单的算法结构
- 语句与语句之间,框与框之间是按从上到下的顺序进行的,它是由若干个依次执行的处理步骤组成的,它是任何一个算法都离不开的一种基本算法结构
即在没有任何干预的情况下,由上到下输出结果
4.4选择结构
4.4.1if单选泽结构
-
很多时候需要去判断一个东西是否可行,然后我们才去执行,这样的一个过程在程序中用if语句来表示
-
语法
-
if(布尔值表达式){
//如果布尔值表达式为true将执行的语句
}
-
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s = scanner.nextLine();
System.out.println("请输入内容");
//equals:判断字符串是否相等
if(s.equals("Hello")){
System.out.println(s);
}
System.out.println("END");
scanner.close();
}
4.4.2if双选择结构
if(条件表达式){
执行代码块1;
}else{
执行代码块2;
}
public class IfDemo02 {
public static void main(String[] args) {
System.out.println("请输入成绩");
Scanner scanner = new Scanner(System.in);
int score = scanner.nextInt();
//考试大于60就是及格,小于60就是不及格
if (score>60){
System.out.println("成绩合格");
}
else{
System.out.println("成绩不合格");
}
scanner.close();
}
4.4.3if多选择结构
if-else-if语句
if(条件表达式1){
//如果布尔表达式1的值为true执行代码块1;
}else if(条件表达式2){
//如果布尔表达式2的值为true执行代码块2;
}
......
else{
//如果以上布尔值都不为true执行代码块n;
}
public static void main(String[] args) {
System.out.println("请输入成绩");
Scanner scanner = new Scanner(System.in);
int score = scanner.nextInt();
if (score == 100) {
System.out.println("成绩合格");
} else if (80<=score && score<100){
System.out.println("成绩优秀");
}else if (score<80 && score>=60){
System.out.println("成绩很差");
}else if (score>=0 && score<60){
System.out.println("不及格");
}
else {
System.out.println("完蛋了");
}
scanner.close();
}
- 一个if语句至多有一个else语句,且只能在所有else if语句之后
- 一旦其中一个else if 语句检测为true,则其它的else if和else语句将被跳过直接输出结果
嵌套的if结构
4.5Switch选择结构
-
多选择结构还有一个实现方式就是switch case语句
-
switch case 语句判断一个变量与一系列值中某个值是否相等,每一个值被称为一个分支
-
switch语句中的变量类型可以是:
- byte,short,int或者char
- 从Java SE7开始,switch支持字符串String类型了
- 同时case标签必须为字符串常量或字面量
switch(表达式){
case 常量1:
语句1;
break;//可选
case 常量2:
语句2;
break; //可选
case 常量N:
语句N;
break; //可选
default:
语句;
break; //可选
}
public static void main(String[] args) {
char grade = 'B';
//case:具有穿透性 //switch:是匹配具体的一个值
switch (grade){
case 'A':
System.out.println("成绩为优秀");
break;
case 'B':
System.out.println("成绩为良");
case 'C':
System.out.println("成绩为不及格");
default:
System.out.println("再接再厉");
}
}
- case具有穿透性
public static void main(String[] args) {
String name = "秦疆";
//case:具有穿透性 //switch:是匹配具体的一个值
switch (name){
case "秦疆":
System.out.println("秦疆");
break;
case "狂神":
System.out.println("狂神");
default:
System.out.println("不知道你谁啊");
}
}
- JDK7的新特性,表达式结果可以是字符串
- 字符的本质还是数字
- 反编译 java—class(字节码文件)----反编译
4.6While循环结构详解
4.6.1while循环
-
while循环是最基本的循环
-
只要布尔值表达式为true,就会一直执行下去(死循环),正常的业务中应该尽量避免死循环
-
大多数情况会让循环停止下来的,需要一个让表达式失效的方式来结束循环
-
少部分情况需要循环一直执行,比如服务器的监听
-
表达式
-
while(布尔表达式){ }
-
while循环 输出0~100
public static void main(String[] args) {
int i = 0;
while (i<100){
i++;
System.out.println(i);
}
}
当while循环为true的时候 死循环
public static void main(String[] args) {
while (true){
//
//
//...
}
}
- 用于等待客户连接,定时检查…
public static void main(String[] args) {
//计算1+2+3+...100?
int i = 0;
int sum = 0;
while (i<100){
i=i+1;
sum=sum+i;
}
System.out.println(sum);
}
public static void main(String[] args) {
//计算1+2+3+...100?
int i = 0;
int sum = 0;
while (i<100){
i=i+1;
sum=sum+i;
}
System.out.println(sum);
}
4.6.2Dowhile循环
-
do…While和While的区别
- while先判断后执行,dowhile是先执行后判断
- Do…while总是保证循环会被至少执行一次!这是它们的主要差别
表达式:
do{ //代码语句 }while(布尔值表达式);
public static void main(String[] args) { int a =0; double sum=0; do { a++; sum=sum+a; }while(a<50); System.out.println("总和为="+sum); }
while和do…while区别
public static void main(String[] args) { int a =0; while (a<0){ a++; System.out.println(a); } System.out.println("==================="); do { a++; System.out.println(a); }while(a<0); }
4.7For循环(重点)
-
for循环可以使结构变得更加简单
-
for循环语句是支持迭代的一种通用结构,是最有效,最灵活的循环结构
-
for循环执行的次数在执行前就是确定的,语法格式:
-
for(初始化;布尔表达式;更新){ //代码语句 }
-
int i =0;
int sum=0;
int sum1=0;
while (i<50){
i++;
sum+=i;
System.out.println(sum);
}
System.out.println("====================================");
for ( int a=0; a< 50; a++) {
sum1+=a;
System.out.println(sum1);
}
//死循环
for( ; ;i++){
}
}
4.7.1例:计算100以内奇数的和和偶数的和
- oddsum奇数 evensum偶数
- 100.for回车可以直接生成 for(int i = 1;i<100;i++)
public static void main(String[] args) {
int oddsum=0;
int evensum=0;
for (int i = 0; i < 100; i++) {
if ( i%2 == 0){
evensum+=i;
}else{
oddsum+=i;
}
}
System.out.println("偶数的和为="+evensum);
System.out.println("奇数的和为="+oddsum);
}
4.7.2输出0~1000内被5整除的数,每行输出三个
public static void main(String[] args) {
//输出0~1000内被5整除的数,每行输出三个
for (int i = 0; i <= 1000; i++) {
if (i%5 == 0){
System.out.print(i+"\t");
}
if (i%15 == 0) {
System.out.println();
}
}
}
4.7.3打印9*9乘法表
public static void main(String[] args) {
for (int i = 1; i <=9; i++) {
for (int j = 1; j <=i; j++) {
System.out.print(j+"*"+i+"="+(j*i)+"\t");
}
System.out.println();
}
}
4.7.4增强for循环
-
Java5引入了一种主要用于数组集合的增强for循环
-
Java增强for循环语法格式如下:
-
for(声明语句:表达式){ //代码句子 }
-
-
声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配,其作用域限定在循环语块,其值与此时数组元素的值相等
-
表达式:表达式是要访问数组名,或者返回值为数组的方法
public class ForDemo05 {
public static void main(String[] args) {
int[] number={10,20,30,40,50};
for(int i=0;i<5;i++){ //第一种
System.out.println(number[i]);
}
System.out.println("========================");
for (int y:number){ //第二种
System.out.println(y);
}
}
4.8break,continue,goto
4.8.1break
- break在任何循环语句的主体部分,均可用break控制循环的流程。break用于强制退出循环,不执行循环过程中剩余的语句。(也可以在switch语句中使用)
public static void main(String[] args) {
int i =0;
while (i<100){
i++;
System.out.println(i);
if (i==30){
break;
}
}
}
4.8.2continue
- continue语句用在循环语句体中,用于终止某次循环的过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定
public class Continue {
public static void main(String[] args) {
int i =0;
while (i<100){
i++;
if (i%10==0){
System.out.println();
continue;
}
System.out.print(i);
}
}
4.8.3goto关键字(了解即可)
4.9打印三角形即Debug
public static void main(String[] args) {
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();
}
}
5.方法
5.1什么是方法
- Java方法是语句的集合,它们在一起执行一个功能
- 方法是解决一类问题的步骤的有序组合
- 方法包含于类或对象之中
- 方法在程序中被创建,在其他地方被引用
- 设计方法的原则:方法的本意是功能块,就是实现某个功能语句块的集合,设计方法最好保持其原子性,就是一个方法只完成一个功能,这样有利于我们后期的扩展
- 方法的命名规则:方法名:首字母小写和驼峰原则:run(),runMan()
public static void main(String[] args) {
// int sum = add(1, 2);
// System.out.println(sum);
test();
}
//加法 加一个static 让它成为类方法
public static int add(int a,int b){
return a+b;
}
//方法:
public static void test(){
for (int i = 0; i <= 1000; i++) {
if (i % 5 == 0) {
System.out.print(i + "\t");
}
if (i % 15 == 0) {
System.out.println();
}
}
}
5.2方法的定义和调用
-
Java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段,一般情况下,定义一个犯非法包含以下语法
-
方法包含一个方法头和方法体,下面是一个方法的所有部分
-
修饰符:是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型
-
返回值类型:可能会返回值,returnValueType是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值,在这种情况下,returnValueType是关键字void.
-
方法名:是方法的实际名称,方法名和参数表共同构成方法名
-
参数类型:参数像是一个占位符。当方法被调用时,传递值给参数,这个值被称为实参或者变量,参数列表是指方法的参数类型,顺序和参数的个数。参数是可选的,方法可以不包含任何参数
- 形式参数:在方法被调用时用于接受外界输入的数据
- 实参:调用方法时实际传给参数的数据
-
方法体:方法体包含具体的语句,定义该方法功能
-
修饰符 返回值类型 方法名(参数类型 参数名){ ... 方法体 ... return 返回值; }
-
-
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; //return有终止方法的作用
}
if (num1>num2){
result=num1;
}else{
result=num2;
}
return result;
}
public static int max(double num1,double num2){
int result=0;
if (num1==num2) {
System.out.println(num1 == num2);
return 0; //return有终止方法的作用
}
if (num1>num2){
result=(int)num1;//方法的重载
}else{
result=(int)num2;
}
return result;
}
- return写在方法最下面,定义一个变量输出结果,最后返回return result即可
- return除了有返回结果的功能还有终止方法的功能
方法的调用
-
调用方法:对象名,方法名(实参列表)
-
Java支持俩种调用方法的方式,根据方法是否返回值来选择。
-
当方法返回一个值的时候,方法调用通常被当做一个值,例如
-
int larager = max(20,60);
-
-
如果方法返回值是void,方法调用一定是一条语句
-
System.out.println("Hello,kuangshen!");
-
-
拓展了解:值传递和引用传递
5.3方法的重载(重点)
- 重载就是在一个类中,有相同的函数名称,但形参不同的函数
- 方法重载的规则:
- 方法名称必须相同。
- 参数列表必须不同(个数不同,或类型不同,参数排列顺序不同等)
- 方法的返回类型可以相同也可以不同(下面代码中的int和double)
- 仅仅返回类型不同不足以成为方法的重载
- 实现理论:
- 方法名称相同时,编译器会根据调用方法的参数个数,参数类型等去逐个匹配,已选择对应的方法,如果匹配失败,则编译器报错
public static void main(String[] args) {
double larage = max(10, 20);
System.out.println(larage);
}
//比大小
public static int max(int num1,int num2){
int result=0;
if (num1==num2) {
System.out.println(num1 == num2);
return 0; //return有终止方法的作用
}
if (num1>num2){
result=num1;
}else{
result=num2;
}
return result;
}
public static int max(double num1,double num2){
int result=0;
if (num1==num2) {
System.out.println(num1 == num2);
return 0; //return有终止方法的作用
}
if (num1>num2){
result=(int)num1;//方法的重载
}else{
result=(int)num2;
}
return result;
}
5.4命令行传参
public static void main(String[] args) {
//args.length 数组长度
for(int i=0;i<args.length;i++){
System.out.println("args["+i+"]"+args[i]);
}
}
- 路径下+".java"生成class文件
- cd …/退回到src 再重新输入到当前文件路径下
5.5可变参数
- JDK1.5开始,Java支持传递同类型的可变参数给一个方法
- 在方法声明中,在指定参数类型后加一个省略号(…)
- 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数,任何普通的参数必须在它之前声明
public static void main(String[] args) {
Demo04 demo04 = new Demo04();//ail+回车自动补全
demo04.test(x:1,...i:2,34,56);
}
public void test(int x,int...i){ //int x必须放在int...i前面
System.out.println(i[0]);
System.out.println(i[1]);
System.out.println(i[2]);
}
5.6递归(最重点,面试笔试)
- 递归就是:A方法调用A方法!自己调用自己
- 利用递归可以用简单的程序来解决一些复杂的问题。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归只需要少量的程序就可描述出阶梯过程所需的多次重复计算,大大的减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无线集合。
- 递归结构包括俩个部分:
- 递归头:什么时候不用调用自身的方法。如果没有头,将陷入死循环
- 递归体:什么时候需要调用自身方法
public static void main(String[] args) {
//5!5*4*3*2*1 阶乘
System.out.println(a(5));
}
public static int a(int n){
if ( n==1 ){
return 1;
}else{
return n*a(n-1);
}
}
6.数组
6.1数组
- 数组是相同类型数据的有序集合
- 数组描述的是相同类型若干个数据,按照一定的先后次序排列组合而成
- 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们
6.2数组的声明和创建
-
首先必须声明数组变量,才能在程序中使用数组,下面是声明数组变量的语法:
dateType[] arrayRefVar; //首选的方法 dateType arrayRefVar[]; //效果相同,但不是首选方法
-
Java语言使用new操作符来创建数组,语法如下:
dataType[] arrayRefVar = new dataType[arraySize];
-
数组元素是通过索引访问的,数组索引从开始
-
获取数组长度:
- arrayslength
public class ArrayDemo01 {
//变量的类型 变量的名字 = 变量的值;
//数组类型
public static void main(String[] args) {
int[] nums;//建议使用这一种数组声明方式 1.声明一个数组
nums=new int[10]; //这里面可以存放10个int类型的数据 2开辟一块空间,创建一个数组
int[] nums2 = new int[5];
//3给数组元素中赋值
nums2[0]=10;
nums2[1]=9;
nums2[2]=8;
nums2[3]=7;
nums2[4]=6;
//计算所有元素的和
int sum=0;
//获取数组的长度:arrarys.length
for(int i=0;i< nums2.length;i++){
sum=sum+nums2[i];
}
System.out.println("总和为:"+sum);
}
6.3三种初始化及内存分析
6.3.1内存分析
6.3.2三种初始化
静态初始化
int[] a = {1,2,3};
Man[] mans = {new Man(1,1),new Man(2,3)};
动态初始化
int[] a = new int[2];
a[0] = 1;
a[1] = 2;
数组的默认初始化
- 数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。
public static void main(String[] args) {
//静态初始化:创建+赋值
int[] a={2,3,4,7,9};
System.out.println(a[3]);
//动态初始化:包含默认初始化
int[] b=new int[10];
}
6.4下标越界及小节
数组的四个基本特点
-
长度是确定的。数组一旦被创建,它的大小就是不可改变的
-
其元素必须是相同类型,不允许出现混合类型
-
数组中的元素可以是任何数据类型,包括基本类型和引用类型
-
数组变量是引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量
数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其它对象类型
数组对象本身是在堆中的
数组边界
-
下标的合法区间:[0,length-1],如果越界就会报错
int[] a =new int[2]; System.out.println(a[2]);
-
ArrayIndexOutOfBoundsException():数组下标越界异常
-
小结
- 数组是相同数据类型(数据类型可以为任意类型)的有序集合
- 数组也是对象。数组元素相当于对象的成员变量
- 数组长度的确定是不可改变的,如果越界,则报:ArrayIndexOutOfBounds
int[] a ={1,2,3,4,5,6,7,8};
for (int i = 0; i <=a.length; i++) {
System.out.println(a[i]);
6.5数组的使用
- 普通for循环
- For-Each循环
- 数组作方法入参
- 数组作返回值
基础使用 for循环
public static void main(String[] args) {
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 = 0; i <arrays.length ; i++) {
max=arrays[i];
}
System.out.println("MAX="+max);
}
array.for自动生成增强for循环数组
public static void main(String[] args) {
int[] arrays = {1,2,3,4,5};
//JDK1.5没有下标
for (int array : arrays) {
System.out.println(array);
}
}
打印数组元素
public static void main(String[] args) {
int[] arrays = {1, 2, 3, 4, 5};
printArray(arrays);
}
//打印数组元素
public static void printArray(int[] arrays){
for (int i = 0; i <arrays.length ; i++) {
System.out.print(arrays[i]+" ");
}
}
反转数组 reverse(反转)
public static void main(String[] args) {
int[] arrays = {1, 2, 3, 4, 5};
int[] reverse = reverse(arrays);
printArray(reverse);
}
//反转数组 reverse反转
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;
6.6二维数组
多维数组
-
多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组
-
二维数组
-
int a[][] = new int[2][5];
-
-
以上二维数组a可以看成一个俩行五列的数组
public static void main(String[] args) {
int[][] array = {{1,2},{3,4},{5,6},{7,8}};
for (int i = 0; i <array.length ; i++) {
for (int j = 0; j <array[i].length ; j++) {
System.out.println(array[i][j]);
}
}
}
6.7Arrays类详解
- 数组的工具类java.util.Arrays
- 由于数组对象本身并没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本操作
- 查看JDK帮助文档
- Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而“不用”使用对象来调用(注意:是“不用”而不是“不能”)
- 具有以下常用功能:
- 给数组赋值:通过fill方法
- 对数组排序:通过sort方法,按升序
- 比较数组:通过equals方法比较数组中元素是否相等
- 查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找操作
打印数组/对数组进行排序
public static void main(String[] args) {
int[] a ={1,2,88,56,986,8745,12,8};
//打印数组元素 Arrays.toString
System.out.println(Arrays.toString(a));
//对数组进行排序
Arrays.sort(a);
System.out.println(Arrays.toString(a));
}
数组填充
//数组填充
Arrays.fill(a,0);
System.out.println(Arrays.toString(a));
6.8冒泡排序(必须知道)
- 冒泡排序是八大排序中最出名的算法之一
- 俩层循环,外层冒泡数,里层依次比较,江湖中人人皆知
- 我们看到嵌套循环,应该立马得出这个算法的时间复杂度为O(n2)
public class ArrayDemo07 {
public static void main(String[] args) {
int[] a={1,4,5,6,72,2,2,2,25};
int[] sort = sort(a);//调用完我们自己写的排序方法以后,返回一个排序后的数组
System.out.println(Arrays.toString(sort));
}
//冒泡排序
//1.比较数组中,俩个相邻的元素,如果第一个数比第二个数大,我们就交换他们的位置
//2.每一次比较,都会产生出一个最大,或者最小的数字
//3.下一轮则可以少一次排序
//4.依次循环,直到结束
public static int[] sort(int[] array){
int temp=0;
//外层循环,判断我们这个要走多少次;
for (int i = 0; i < array.length-1 ; i++) {
//内层循环,比价判断俩个数,如果第一个数,比第二个数大,则交换位置
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;
}
}
}
return array;
}
优化后的
public class ArrayDemo07 {
public static void main(String[] args) {
int[] a={1,4,5,6,72,2,2,2,25};
int[] sort = sort(a);//调用完我们自己写的排序方法以后,返回一个排序后的数组
System.out.println(Arrays.toString(sort));
}
//冒泡排序
//1.比较数组中,俩个相邻的元素,如果第一个数比第二个数大,我们就交换他们的位置
//2.每一次比较,都会产生出一个最大,或者最小的数字
//3.下一轮则可以少一次排序
//4.依次循环,直到结束
public static int[] sort(int[] array){
int temp=0;
//外层循环,判断我们这个要走多少次;
for (int i = 0; i < array.length-1 ; i++) {
boolean flag = false; //通过flase标识位减少没有意义的比较
//内层循环,比价判断俩个数,如果第一个数,比第二个数大,则交换位置
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;
}
}
if (flag==false){
break;
}
}
return array;
}
6.9稀疏数组
- 当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组。
- 稀疏数组的处理方式是:
- 记录数组一共有几行几列,有多少个不同值
- 把具有不同值的元素和行列及值记录在一个小规模中,从而缩小程序的规模
- 如下图左边是原始数组,右边是稀疏数组
7.面向对象编程
7.1什么是面向对象
面向对象&面向过程
- 面向过程思想
- 步骤清晰简单,第一步做什么,第二部做什么
- 面对过程适合处理一些较为简单的问题
- 面向对象思想
- 物以类聚,分类 的思维模式,思考首先会解决问题需要哪些分类,然后对这些分类进行单独的思考。最后,才对某个分类下的细节进行面向过程的思索。
- 面向对象适合处理复杂的问题,适合处理需要多人协作的问题!
- 对于描述复杂的事物,为了从宏观上把握,从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到了微观操作,仍需要面向过程的思路去处理
什么是现象对象
- 面向对象编程(Object-Oriented Programming,OOP)
- 面向对象编程的本质就是:==以类的方式组织代码,以对象的组织(封装)数据
- 抽象:(把像的地方抽取出来)
- 三大特性:
- 封装
- 继承
- 多态
- 从认识论考虑,是现有对象后有类。对象,是具体事物。类,是抽象的,是对对象的抽象
- 从代码运行角度考虑是有类后有对象,类是对象的模板。
7.2回顾方法及加深
-
方法的定义
-
修饰符
-
返回值类型
//Demo01 类 public class Deom01 { //main方法 public static void main(String[] args) { } /* 修饰符 返回值类型 方法名(...){ //方法体 return 返回值; } */ public String sayHello(){ return "Hellow world"; } public int max(int a,int b){ return a>b ? a:b; //三元运算符 }
-
break:跳出switch,结束循环和return的区别
//结束方法,返回一个结果 public String sayHello(){ return "Hellow world"; } public void A77(){ return ; }
-
方法名:注意规范就OK 见名知意原则
-
参数列表:(参数类型,参数名)…
-
异常抛出:疑问,后面讲解
-
7.3回顾方法的调用
静态方法下调用
非静态方法调用
静态类调用非静态类(报错)
值传递和引用传递
public class Demo05 {
//值传递
public static void main(String[] args) {
int a=1;
System.out.println(a);// 1
Demo05.change(a);
System.out.println(a);// 1
}
//返回值为空
public static void change(int a){
a=10;
}
public class Demo06 {
public static void main(String[] args) {
Perosn perosn = new Perosn();
System.out.println(perosn.name);//null
Demo06.change(perosn);
System.out.println(perosn.name);//秦疆
}
public static void change(Perosn perosn){
//perosn是一个对象:指向的--->Perosn perosn = new Perosn();这是一个具体的人
perosn.name ="秦疆";
}
}
//定义了一个Perosn类,有一个属性:name
class Perosn{
String name;
}
7.4类与对象的关系
-
类是一种抽象的数据类型,它是对某一事物整体描述/定义/,但是并不能代表某一个具体事物
- 动物,植物,手机,电脑…
- Person类,Pet类,Car类等,这些类都是用来描述/定义某一类具体事物应该具备的特点和行为
-
对象是抽象概念的具体实例
- 张三就是一个具体实例,张三家里的旺财就是狗的一个具体实例
- 能够体现出特点,展现出功能的是具体的实例,而不是一个抽象的概念
-
创建对象与初始化
- 使用new关键字创建对象
- 使用new关键字创建对象的时候,除了分配内存空间之外,还会给创建好的对象,进行默认的初始化以及对类中构造器的调用
一个项目里只能有一个main方法
构造器
//java-calss
public class Person {
//一个类即是什么都不写,它也会存在一个方法
//显示的定义构造器
String name;
//alt+insert快捷键生成有参无参
//实例化初始值
//1.使用new关键字,必须要有构造器
public Person() {
this.name = "秦疆";
}
//有参构造:一旦定义了有参构造,无参构造必须显示定义
public Person(String name){
this.name= name;
}
}
/* public static void main(String[] args) {
//new 实例化了一个对象
Person person = new Person("kuangshen");
System.out.println(person.name);//qinjiang
}
构造器:
1.和类名相同
2.没有返回值
作用:
1.new本质在调用构造方法
2.初始化对象的值
注意点:
1.定义有参构造之后,如果想使用无参构造,显示的定义的一个无参构造
Alt+Insert
this.当前类 = 传进来的参数的值
*/
7.5创建对象内存分析
7.6类与对象小结
-
类与对象
- 类是一个模板:抽象,对象是一个具体的实例
-
方法
- 定义,调用!
-
对应的引用
- 引用类型:基本引用类型:基本类型(8)
- 对象是通过引用来操作的:栈—>堆
-
属性:字段Field 成员变量
默认初始化
- 数字:0 0.0
- char:u000
- boolean:false
- 引用:null
修饰符 属性类型 属性名 = 属性值!
-
对象的创建和使用
- 必须使用new关键字创造对象,构造器 person kuangshen = new Person();
- 对象的属性 kuangshen.name
- 对象的方法 kuangshen.sleep()
-
类:
- 静态的属性 属性
- 动态的行为 方法
7.7封装
- 该露的露,该藏的藏
- 程序设计要追求高内聚,低耦合, 高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:紧暴露少量的方法给外部使用
- 封装(数据的隐藏)
- 通常,应该进制直接访问一个对象中数据的实际表示,而应该通过操作接口来访问,这称为信息隐藏。
- 居记住一句话:属性私有,get/set
- 提高程序安全性,保护数据
- 隐藏代码的实现细节
- 统一接口
- 系统可维护增加了
7.8 继承
-
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模
-
extends 的意思是“扩展”。子类是父类的阔爱还在那
-
JAVA中类只有单继承,没有多继承!
-
继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖,组合。聚合等
-
继承关系的俩个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。
-
子类和父类之间,从意义上讲应该具有“is a”的关系
在JAVA中,所有的类,都默认直接或者间接继承object
7.9Super详解(重点)
super注意点:
- super调用父类的构造方法,必须在构造方法的第一个
- super必须只能出现在子类的方法或者构造方法中!
- super和this不能同时调用构造方法!
VS this:
代表的对象不同:
this:本身调用者这个对象
super:代表父类对象的应用
前提:
this:没有继承也可以使用
super:只能在继承条件下才可以使用
构造方法:
this();本类 的构造
super():父类的构造!
7.10方法的重写
去掉static
总结
- 重写:需要有继承关系,子类重写父类的方法
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大,但不能缩小:public>Protected>Default>private
- 抛出的异常:范围,可以缩小,但不能扩大:ClassNotFoundException(大)
- 重写,子类的方法和父类必须一致,方法体不同!
- 为什么要重写:
- 父类的功能,子类不一定需要,或者不一定满足
- Alt+Insert:override
7.11什么是多态
多态
- 即统一方法可以根据发送对象的不同而采用多种不同的行为方式
- 一个对象的实际类型是确定的,但可以指向引用的类型有很多(父类,有关系的类)
- 多态存在的条件
- 有继承关系
- 子类重写父类方法
- 父类引用指向子类对象
- 注意:多态是方法的多态,属性没有多态性
- instanceof 类型转换
多态注意事项
- 多态是方法的多态,属性没有多态
- 父类和子类,有联系 类型转换异常! ClassCastException
- 存在条件:继承关系,方法需要重写,父类引用指向子类对象! Father f1 = new Son();
- static 方法,属于类,它不属于实例
- final 常量
- private方法
7.12instanceof和类型转换
- 父类引用指向子类的对象
- 把子类转换为父类,向上转型:
- 把父类转换为子类,向下转型:强制转换
- 方便方法的调用,减少重复的代码!简洁
抽象:封装,继承,多态
- 子类转换为父类,可能会丢失原有的一些方法
7.13 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);
}
7.13.1 static方法和普通方法调用对比
- Static方法可以直接调用甚至可以不加类名
- 普通方法需要 new.类().方法()
7.13.2 静态代码块
- 静态代码块只执行一次,且优先执行
- 匿名代码块可以用来赋值一些初值
7.13.3 静态导入包
7.14抽象类
- abstract 修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类
- 抽象类中可以没有抽象方法,但是抽象方法的类一定要声明为抽象类
- 抽象类,不能使用new关键字来创建对象,它是用来让子类继承的
- 抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。
- 子类继承抽象类,那么就必须要实现抽象类没有的抽象方法,否则该子类也要声明为抽象类
抽象类的所有方法,继承了它的子类,都要去替他实现
- 抽象类特点:
- 不能new这个抽象类,只能靠子类去实现它:约束!
- 抽象类中可以写普通的方法
- 抽象类方法必须在抽象类中
- 抽象的抽象约束
- 思考?抽象类存在构造器吗
- 抽象类存在的意义: 抽象出来,提高开发效率
7.15接口(重点)
- 普通类:只有具体实现
- 抽象类:具体实现和规范(抽象方法)都有!
- 接口:只有规范!自己无法写方法专业的约束!约束和实现的分离:面向接口编程
- 接口就是规范,定义的是一组规则,体现了现实世界中"如果你是…则必须能…"思想
- 接口的本质是契约 ,就像我们人间的法律一样。制定好后大家都遵守
- OO的精髓,是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计模式都只针对具备了抽象能力的语言(比如C++,java,c#等),就是因为设计模式所研究的,实际上就是如何合理的去抽象
interface定义接口类 implements实现接收
//interface 定义的关键字,接口都需要有实现类
public interface UserService {
//接口中的所有定义其实都是抽象的public abstract
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
接收:
作用:
- 约束
- 定义一些方法,让不同的人实现~10—>1
- public abstract
- public static final
- 接口不能被实例化,接口中没有构造方法
- implements可以实现多个接口
- 必须要重写接口中的方法
7.16内部类
-
内部类就是在一个类的内部在定义一个类,比如A类中定义一个B类。那么B类相对于A类来说就被称为内部类,而A类相对B类来说就是外部类了
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
局部内部类
匿名内部类
8异常
什么是异常
- 指程序运行中出现的不期而至的各种状况,如,找不到文件,网络连接失败,非法参数等
- 异常发生在程序运行期间,它影响了正常的程序执行运行
简单分类
- 三种异常
- 检查性异常:最具代表性的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在的文件时,一个异常就发生了。在编译时不能被简单的忽略
- 运行时异常:运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以再编译时被忽略
- 错误ERROR:错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略的。例如,当栈溢出时,一个错误就发生了,他们在编译也检查不到
异常体系结构
- JAVA把异常当做对象处理,并定义了一个基类java.long.Throwable作为所有异常类的超类
- 在Java API中已经定义了许多异常类,这些异常分为俩大类,错误Error和 exception
8.1 Error
- Error类对象由Java虚拟机生成并抛出,大多数错误代码编写者所执行的操作无关
- Java虚拟机运行错误(Virtual MachineError )当JVM不再有继续执行操作所需的内存资源时,将出现OutMemoryError .这些异常发生时,Java虚拟机(JVM),一般会选择线程终止。
- 还有发生在虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError),链接错误(LinkageError).这些错误是不可查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况
8.2 Execption
-
Exception
- 在Exception分支中有一个重要的子类RuntimeException(运行时异常)
- ArraylndexOutOfBoundsException(数组下标越界)
- NullPointerException(空指针异常)
- ArithmeticException(算术异常)
- MissingResourceException(丢失资源)
- ClassNotFoundException(找不到类)等异常,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。
-
-
这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生;
-
Error和Exception的区别: Error通常是灾难性的致命的错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机(JVM)一般会选择终止线程;Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常。
8.3捕获和抛出异常
异常处理机制
- 捕获异常
- 抛出异常
- 异常处理五个关键字:
- try,catch,finally,throw,throws
快捷键自动生成Ctrl+alt+t(截图错误)
手动结束程序 System.exit
主动抛出异常 throw
主动抛出异常throws
8.4自定义异常及经验小节
实验应用中的经验总结
-
处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理
-
在多重catch块后面,可以加一个catch (Exception)来处理可能会被遗漏的异常
-
对于不确定的代码,也可以加上try-catch,处理潜在的异常
-
尽量去处理异常,切忌只是简单地调用printStackTrace()去打印输出
-
具体如何处理异常,要根据不同的业务需求和异常类型去决定
-
尽量添加finally语句块去释放占用的资源IO~Scanner