JAVA基础学习笔记(狂神说)

狂神说java,听课笔记,手打可能有误,欢迎补充和指正

一、坚持!!!多写多练!

二、下载安装JDK

1.下载

官网(建议JDK8版本),同意协议,下载电脑对应版本即可(可能需要注册账号,注册即可)。

2.安装

第一步:双击安装。
第二步:更改下载位置,建议不在C盘,但是此目录需记住!!!配置环境时还要用,其余下一步即可。
第三步:等待安装完成点击关闭即可,然后开始配置环境变量:
1.我的电脑(右键)-属性-高级系统设置-环境变量-在系统变量处添加变量,变量名:JAVA_HOME,变量值:刚刚的路径-确定。
2.配置path,还是刚刚系统变量的位置,找到path双击打开,新建输入"%JAVA_HOME%bin"(不包括",其中%%表示引用,即引用刚刚新建的变量,bin为下载的JDK中的一个文件)、"%JAVA_HOME%\jre\bin"(同理,代表引用jre的bin,若下载的非JDK8,则找到对应文件目录即可)-确定。
第四步:检查安装是否成功,window+R输入cmd,输入java -version回车,若显示java版本,则正确安装。
(第五步:建议下载notepad++,百度官网下载安装即可,其相当于一个记事本)

3.卸载

第一步:我的电脑-属性-高级系统设置-环境变量-JAVA_HOME中的地址,复制到我的电脑中,找到对应的JDK文件,连包删除,删除后删除此环境变量,以及path中和JAVA_HOME相关的目录一并删除,然后确定即可。
第二步:window+R输入cmd,输入java -version回车,若显示不是内部命令则表示卸载成功。

三、简单的程序

1.新建文件夹,存放代码
2.新建一个后缀.java的文件,不显示后缀的,在菜单-查看-勾选查看文件扩展名即可。
3.打开新建的文件,选择编辑,建议使用notepad++。
4.输入:

public class Hello{
	public static void main(String [] args){
		System.out.print("Hello,World!");//也可以是println(比print多的是一个换行)
	}
}

5.保存后,在该java文件所在地址栏前输入cmd ,然后回车,输入javac Hello.java回车即可,若没有错误则表示编译正确,注意此处的Hello表示文件名,而文件名应该和包含main的类名一致!
6.然后输入java Hello回车,若无错误应该在屏幕上显示“Hello,World!”,至此第一个java程序完成。

四、下载安装idea,及java基本知识

1.可以直接点击新建项目选择java,命名后finish即可,在src中新建一个class开始编写,也可以先新建一个package然后再往里面新建class。
2.更专业的可以:新建项目,选择一个空的项目,选择项目,在菜单栏选择file,new一个module,选择java,命名即可,其余和第一项一样可以正常编写了。此外需要注意因为是空项目所以需要管理项目结构,可以在菜单-file-project structure找到,点开后选择project,将SDK改为自己的java版本,下面的项目语言等级也应该改为相同的版本,点击应用。其中应该注意,一个项目中应该只存在一个main方法最为规范合理。
3.注释:编写过程中建议多加注释。
单行注释://;
多行注释:/星号星号/;
文档注释:和多行注释一样不过每行开头需要加一个*(包括首行)。
文档注释的区别在于可以有一定功能,可以加一些参数,和Javadoc联合使用。
4.标识符:不能是关键字,所有的标识符需要以字母、美元符或下划线开头,后接字母、数字、美元符或下划线。(大小写敏感)
5.关键字:abstract;assert;boolean;break;byte;case;catch;char;class;const;continue;default;do;double;else;enum;extends;final;finally;float;for;goto;if;implements;import;instanceof;int;interface;long;native;new;package;private;protected;public;return;strictfp;short;static;super;switch;synchronized;this;throw;throws;transient;try;void;volatile;while.
在这里插入图片描述
6.数据类型:java是一种强类型语言,变量使用要严格符合规定,变量需要先定义后使用,分为基本类型和引用类型。

基本类型:
1.数值类型:***JDK的新特新:数字之间可以用下滑线分割,而且不会被输出***。

①整数类型:byte,占1个字节;short,占2个字节;int,占4个字节;long,占8个字节;(此处区别C语言)。
*特别的,*对于long类型有:long num=30L(此处也可以用小写,但是和1太像,不建议用);
*特别的,*对于整数类型进制,二进制0b,八进制0,十六进制0x。
②浮点类型:float,占4个字节;double,占8个字节。
*特别的,*对于float类型有:float num=30.1F;
*特别的,*对于浮点数类型舍入误差,存在接近但不等于,最好完全避免浮点数比较!,而使用bigdecimal类(数学工具类)进行比较。
③字符(指计算机中使用的字母、数字、字和符号)类型:char,占2个字节(1字节=8位(bit),是计算机数据处理的基本单位,习惯上用B表示)。包括转义字符,如:制表符等。
*特别的,*需要区别字符串,String不是关键字,是一个类;
*特别的,*对于字符类型,可以输出汉字(java使用Unicode编码例如:’\u0061’=‘a’),还可以进行强制类型转化,所有的字符本质还是数字
2.Boolean类型:boolean,占1位,只有true或false。
*特别的,*对于Boolean类型,使用if进行判断时,当需要true时可以不带‘==true’。

引用类型:
1.类
2.接口
3.数组(会在后面详细说明)

7.类型转换:运算中,不同类型的数据先转化为同一类型,然后进行运算。
(由低到高:byte,short,char->int->long->float->double其中浮点类型一定高于整数类型,这样从低到高的转换样不会内存溢出)
强制转换(由高到低):(类型)变量名;
自动类型转换(由低到高):正常赋值就行。
特别的,对于类型转换,不能对布尔值进行转换不能把对象类型转换为不相干的类型在把高容量转换到低容量的时候,需要强制转换转换的时候可能出现内存溢出或者精度问题计算时以注意先把一个数变为需要的小数或者对应更高级的类型
8.变量
1.变量是可以变化的量,代表着内存中的一块空间。java中的每个变量都需要声明其类型。java变量是程序中最基本的存储单元,其要素包括:变量名、变量类型和作用域。
2.格式:数据类型 变量名=值;//可以使用逗号隔开来声明多个同类型变量。
3.每个变量都有类型,类型可以是基本类型,也可以是引用类型。
4.变量名必须是合法的标识符。
5.变量声明是一条完整的语句,因此每一条声明都必须以分号结束。
6.变量有三种作用域:
①类变量:定义在类里面,需要加一个static,从属于类,不必new可以直接使用。
②实例变量:和类变量很像,但是不需要static,从属于对象,可以不必初始化,但如若不初始化,会变成这个类型的默认值(特别的
Boolean的默认值是false
,数字默认为0,char默认为u0000,引用的默认值是null)。
③局部变量:定义在方法里面,必须声明和初始化值,仅在被定义处的大括号内中有用,当然如果是static的大括号内,可以适用范围不同。
7.变量的命名规范:
①所有的变量、方法、类名:见名知意。
②类成员变量:首字母小写和驼峰原则。(即:除了第一个单词外,后面的单词首字母大写)
③局部变量:首字母小写和驼峰原则。
④常量:大写字母和下划线。
⑤类名:首字母大写和驼峰原则。
⑥方法名:首字母小写和驼峰原则。
9.常量
1.初始化后不能再改变的值。
2.常量名一般使用大写字母。
3.常量的定义需要使用关键字:final(和static一样是修饰符,不区分先后顺序)。
10.运算符:(优先级最好还是用()较为清晰)
1.算术运算符:+,-,星号,/,%,++,–(a++先取值后加一,++a先加一后取值)
2.赋值运算符:=
3.关系运算符:>,<,>=,<=,==,!=instanceof
4.逻辑运算符:&&,||,!(有短路运算,可以不算后面)
5.位运算符:&,|,^,~,>>,<<(1位相当于乘以2),>>>
6.条件运算符:?:(三元运算符?前为真去:前值,反之取:后值)
7.扩展赋值运算符:+=,-=,星号=,/=
8.字符串连接符:+(只要两侧之一出现String类型,则将其后面的其他操作数转化为String类型)
11.包机制:为了更好地组织类,java提供了包机制,用于区别类名的命名空间,包的本质就是文件夹。
1.一般利用公司域名倒置作为包名(其中一个.会新建一层包)。
2.有了包后,在包内的每一个类的代码,前需要加上所属包名(路径),且必须在第一行。格式:package 包的路径。
3.为了可以使用某一个包的成员,我们需要在java程序中明确导入该包,使用"import"语句即可完成此功能,可以具体写出需要导入哪个类,也可以直接使用星号代表导入这个包下全部的类。(按住alt+enter提示错误信息时可以自动帮忙加上,但是注意package也应该在第一行,但是导入的包和现在正在使用的类名不能相同,否则会报错,提示该类已经被定义过了)此处建议查看阿里巴巴开发手册
12.JavaDoc:javadoc命令是用来生成自己的API文档的,将注释信息生成一个帮助文档,可以加在类上,也可以加在方法上。
1.其中可以包括:
@author 作者名
@version 版本名
@since 指明需要最早使用的JDK版本
@ param 参数名
@return 返回值情况
@throw 异常抛出情况
2.可以选中类,右键,可以看到show in explorer,点击后在地址栏前输入cmd,输入javadoc -encoding UTF-8 -charset UTF-8 Java文件(其中的参数是为了不显示乱码)回车后显示成功生成,则回到原文件夹,下找到新生成的文件夹内的index.html,打开就是自己的帮助文档。
3.也可以在idea内生成帮助文档。

五、java流程控制

1.为了实现人机交互,java5的java.util.Scanner可以通过Scanner类来获取用户的输入
1.基本语法:Scanner s=new Scanner(System.in);
2.通过Scanner类的next()与nextLine()方法获取输入的字符串,在读取前我们一般需要使用hasNext()与hasNextLine()判断是否还有输入的数据。

	//创建一个扫描器对象,用于接收键盘数据
	Scanner scanner=new Scanner(System.in);
	//判断用户有没有输入字符串
	if(scanner.hasNext()){//也可以是NextLine,查看是否还有下一行,Next可以通过空格等截断。
		//使用next方法接收
		String str=scanner.next();//也可以是NextLine
		System.out.println("输出的内容为"+str);
	}
	//凡是属于IO流的类如果不关闭会一直占用资源,需要养成良好的习惯,用完就关掉
	scanner.close();
3.next():
	1.一定要读取到有效字符后才可以结束输入。
	2.对输入有效字符之前遇到的空白,next()方法会自动将其去掉。
	3.只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
	4.next()不能得到带有空格的字符串。
4.nextLine():
	1.以回车键作为结束符,也就是说nextline()方法返回的是输入回车之前的所有字符。
	2.可以获得空白。
5.其他用法:还可以有scanner.hasNextInt()用于检查是否还有下一个整数,scanner.hasNextFloat()用于检查是否还有下一个小数等。(可以通过Ctrl和鼠标右键进入类中,然后点击右下侧的structure查看结构)

2.java的结构
1.顺序结构:没有特别指明一般都是一条一条往下执行。
2.if结构:成立才执行if后语句,需要注意if和else的匹配,(else和最近未匹配的if结合)。包括if单选择结构;if-else双选择结构;if-else if-else多个选择结构;if-else嵌套结构,在if中嵌套if。
3.switch-case多选择结构,用于判断一个变量与一系列值中的某一个值是否相等,每个值称为一个分支,因为case的穿透现象,一般需要配合break和default使用。特别的,switch中的变量类型可以是byte/short/int/char/String(因为字符的本质还是数字,此处是通过hashCode比较的),case标签必须是字符串常量或字面量。
(补充:java—class(字节码文件)----反编译(IDEA)。反编译步骤:方法一:找到项目结构(project structure),找到项目编译之后输出的路径(project compiler output),打开对应的路径,找到对应的文件,然后在idea的左侧的项目中打开存放对应.java文件的路径,将需要反编译的文件复制进去,在idea中打开即可看到反编译的文件;方法二:在idea,项目结构->modules->add content root->选择out目录->ok->apply,即可查看class文件)
4.循环结构:while结构;do-while结构(至少执行一次);for循环*(输入100.for回车直接生成一个0-<100的for结构;fori回车;for的三个部分都可以为空)*;增强型for循环。少部分需要一直执行,大部分需要有个出口

//增强for循环主要用于数组或集合
//其中增强for循环的格式如下:
for(声明语句::表达式)
//声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配,其作用域限定在循环语句块,其值与此时数组元素的值相等。
//表达式:表达式是要访问的数组名,或者是返回值为数组的方法。
//也就是会遍历表达式中的数组或集合,将其每一个值赋值给声明语句中的变量
{
	//代码句子
}
//例子:number是一个数组
for(int x:number){//遍历数组的元素
	System.out.println(x);
}
5.break用于强行退出循环,不执行循环中剩余的语句;continue用于在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。
~~goto关键字:java中保留了goto关键字,**但java中没有goto**,我们可以在break和continue后加上标签(标签时指后面跟着一个冒号的标识符),在java中唯一用到标签的地方是在循环语句之前,而在循环语句之前设置标签的唯一理由是:我们希望在其中嵌套另一个循环,由于break和continue关键字通常只中断当前循环,但若随同标签使用,它们就会中断到存在标签的地方继续执行。~~ 
6.绿色的三角后面的小蟑螂是debug,和DevC++差不多,先打断点后debug。

六、java的方法

1.java方法:是语句的集合,他们在一起执行一个功能。方法是解决一类问题的步骤的有序组合;方法包含于类或对象中;方法在程序中被创建,在其他地方被引用。最好保持方法的原子性
2.方法的定义:类似于其他语言的函数,是一段用来完成特定功能的代码片段。
1.修饰符:可选,确定访问类型。如:public(公共的,可以被子类继承)、protected(保护的)、default(默认的)、private(私有的,类的属性一般是私有的)、static(类的方法)。
2.返回值类型。
3.方法名:方法的实例名称,与参数表一起构成方法签名
4.参数类型:类似占位符,指明方法的参数类型、顺序、个数。其中形式参数:在方法被调用时用于接收外界输入的数据;实参:调用方法时实际传给方法的数据。 特别的java只有值传递,没有引用传递
5.方法体:return 提供返回值或者终止方法。
3.方法的调用:调用方法:对象名.方法名(实参列表)。当方法返回一个值的时候,方法调用通常被当作一个值;方法返回的值是void时,方法调用是一条语句。
4.方法的重载:就是在一个类中,有相同的函数名称,但是形参不同的函数。
方法重载的规则:
1.方法名称必须相同。
2.参数列表必须不同,个数不同、类型不同、排列顺序不同等。
3.方法返回值类型可以相同也可以不同。
4.仅仅返回值不同不足以成为方法的重载。
5.命令行传参:当需要在运行一个程序时再给它传递消息,这就要靠传递命令行参数给main()函数实现。
*(然后在idea左下的Terminal里按命令行形式编译执行,注意当是包下的时候,想要执行则必须回退到src目录下输入全部路径执行)*可以在命令行执行时的文件名称后面,空格后输入需要传递的参数。
6.可变参数:java支持传递同类型的可变参数给一个方法。
1.在方法的声明中,在指定参数类型后面加一个省略号(…)。
2.在一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数都需要在它之前声明。

public void test(int... i){
//调用时可以传递一串数字,当然因为其本质还是数组,也可以传递一个数组,但类型一定。
	System.out.println(i);
} 

7.递归:就是方法自己调用自己。(用栈实现,故仅建议在基数较小时使用)
递归包含两部分:
1.递归头:什么时候不调用自身方法,如果没有头,将陷入死循环。(边界条件)
2.递归体:什么时候需要调用自身方法。

七、java数组

1.什么是数组:数组是相同类型的数据的有序集合。描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成,其中每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们。
2.数组的声明创建:数组必须先声明后使用,数组有两种声明方式:
1.dataType[] arrayRefVar;(推荐方法)
2.dataType arrayRefVar[];
3.JAVA语言使用new操作符来创建数组,dataType[] arrayRefVar=new dataType[arraySize];
4.数组元素是通过索引访问的,数组索引从0开始。
5.获取数组长度的方法:arrays.length。
6.数组的边界是:[0,length-1],适合使用增强型for循环。
7.声明时数组并不存在,只有创建的时候存在。
8.数组可以作为方法的参数,也可以作为返回值例如:int[],(在方法内需要先new一片空间)。
3.数组的特点
4.内存分析
1.堆(创建-实际空间):存放new的对象和数组,可以被所有的线程共享,不会存放别的对象引用。
2.栈(声明-名称):存放基本变量类型(会包含这个基本变量的具体数值)以及引用对象的变量(会存放这个引用在堆里面的具体地址)。
3.方法区:可以被所有线程共享,包含了所有的class和static变量。
5.三种初始化
1.静态初始化:在声明时直接赋值。

int[] a={1,2,3,4};
People[] peoples={new People(),new People()};
2.动态初始化:就是先声明创建,之后再赋值,包含了数组的默认初始化。
3.数组的默认初始化:数组时引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。

6.基本特点
1.其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
2.其元素必须是相同类型,不允许出现混合类型。
3.数组中的元素可以是任何数据类型,包括基本类型和引用类型。
4.数组变量属于引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,java中对象时在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。
7.多维数组:可以看做是数组的数组,如:二维数组的每一个元素都是一个一维数组。

int[][] array={{1,2},{2,3},{3,4},{4,5}};//分别代表array[0],array[1],array[2],array[3]
//其中array.length=4;array[0].length=2。

8.Array类:数组的工具类java.util.Arrays,其中的方法都有static修饰,可以直接使用类名进行调用,不必使用对象来调用。可以通过查看JDK帮助手册学习使用。
常用功能:
1.对数组赋值:通过fill方法。
2.对数组排序:通过sort方法,按升序。(共八种,详见其他博客)
3.比较数组:通过equals方法比较数组元素值是否相等。
4.查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作。
9.稀疏数组:对于大部分元素为0或者为同一值的数组,可以由稀疏矩阵来保存。
稀疏矩阵的处理方法:
1.记录数组一共有几行几列,有多少个不同值。
2.把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模。
在这里插入图片描述

八、面向对象编程(OOP:Object-Oriented Programming)

1.定义:描述复杂的事务,从宏观上整体分析,需要面向对象的思路,具体到微观操作还是面向过程的思路。
1.面向过程思想:C语言,步骤清晰,适合处理一些较为简单的问题。
2.面向对象思想:Java语言,物以类聚,分类的思维模式,适合处理复杂的需要多人协作的问题。首先思考解决问题需要哪些分类,然后对这些分类进行单独思考。最后对某个分类下的细节进行面向对象的思索。
3.面向对象的本质就是:以类的方式组织代码,以对象的组织(封装)数据。
4.三大特性:封装,继承,多态。
5.认识论的角度考虑先有对象后有类,对象是具体的事物;类似对对象的抽象,是一种抽象的数据定义,是对某一类事物整体的描述/定义,不是具体的事务;
6.代码运行的角度先有类后有对象,类似对象的模板。
2.方法的深入理解
1.方法在类里,只有一个main方法,用于启动,return用于结束方法,返回一个结果。
2.方法调用:
1.静态方法:加static修饰,可以由类名.方法名()(属性也是)调用。
2.非静态方法:没有static修饰,必须经过实例化new一个对象后通过对象调用,对象名.方法名()(方法和属性(对象名.属性名)都是这样调用)。
3.形参和实参:两者的类型应该对应。
4.值传递和引用传递:java都是值传递,但是对象是引用传递,当然本质还是值传递,因为对象是一个指向,指向一个具体的实例。
5.this关键字:当前的对象或类。
3.加static后只能调用也有static的方法,因为static的方法和类一起加载,不加的在实例化的时候才存在。
3.类与对象
1.类:抽象的,需要被实例化,包含静态的属性(字段/成员变量)和动态的方法。
2.类实例化new后会返回一个自己的对象,该返回的对象就是类的具体实例。
3.通过new出来的对象,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类构造器的调用
4.类的构造器也称为构造方法,是在创建对象时必须要调用的。
1.必须和类的名字相同。
2.必须没有返回类型,也不能写void。
3.不写则默认生成(无参,赋值为默认值),故一个类即使什么都不写,它也会有一个方法。
4.也可以显式生成,一旦显式定义了就不再有默认的无参的了,需要显式定义。其中的this.表示当前类。
5.作用:使用new关键字,本质是调用构造器;一般用来初始化值;
6.快捷键:Alt+insert,选择constructor,选择OK即可直接生成一个(一般有属性则是有参的,选择select no可以生成无参的构造方法)。
7.内存分析:
在这里插入图片描述
其中的方法区也属于堆,一般存放创建出来的对象。栈里面都是方法和一些变量的引用(对象是通过引用来调用的,引用指向了堆(中的地址))。
4.封装:提高程序安全性,隐藏代码实现细节,统一接口,提高系统可维护性。
1.高内聚低耦合。
2.属性私有,get/set。
3.快捷键:Alt+insert->选择getset->选择哪个属性需要getset即可。
5.继承:本质是对某一批类的抽象,从而实现对现实世界更好地建模。
1.java中只有单继承没有多继承,一个儿子只能有一个父亲,但是可以间接继承。
2.extend,扩展,继承是类与类之间的关系,此外还有依赖、组合、聚合等。
3.继承关系的两个类,一个是子类(派生类)一个是父类(基类)。
4.子类继承父类,就拥有了父类的全部public方法,私有的东西无法被继承
5.快捷键:在类里面,Ctrl+H,打开继承树。
6.在java中,所有的类,都直接或者间接继承Object类。
7.super代表父类对象的引用this代表当前的(本身调用者这个对象)(下图中name代表形式参数),因此容易理解this没有继承也能够使用,super只能出现在有继承关系的子类的方法或构造方法中。
在这里插入图片描述
在这里插入图片描述
上图中,当把父类的public变为private,则不可通过super.print()调用。
8.构造顺序:先执行父类的构造函数,后执行子类的构造函数。在子类的构造函数中会默认先调用父类的构造函数,即:super()。可以显式写出,但是必须是在子类中的第一句代码(若子类想通过this()调用自己的构造函数也需要在第一句,和super会有冲突!故super和this不能同时调用构造方法),且若是隐式的调用,默认调用父类无参构造,但是父类不一定有无参构造,因此在写代码时建议均加上一个无参构造函数,保证安全性。
6.方法的重写:首先区别于方法的重载:重载是本类的,重写需要有继承是父子类之间的子类重写父类!但是重写都是方法的重写,和属性无关。
1.重写的修饰符范围只能扩大或不变,不能缩小(关系:public>protected>default>private),且不能加上static,加上static后是静态方法,方法的调用只和左边有关,定义的数据类型有关,例如:B a=new A();其中A继承B,故B的引用可以指向A,若此时B和A内有同名的静态方法,则调用哪个里面的取决于引用是什么类型的此处的a将调用B内的静态方法。
2.方法名必须相同,参数列表必须相同。
3.抛出的异常范围可以被缩小,但不能扩大。
4.也就是重写,子类的方法和父类的必须要一样,但是方法体可以不同。
5.重写后无关定义的数据类型,将调用子类的,例如:B a=new A();此时即使数据类型是B但是还是A,因此调用a内重写的方法。
6.原因:父类的东西子类不一定需要,或者不一定满足。
7.快捷键:alt+Insert ->override;会多一个注释,有注释的好处是会提醒是否有错误,也可以没有注释,但就需要自己去检查了。
7.多态:即同一方法可以根据发送对象的不同而采用多种不同的行为方式。
1.一个对象的实际类型是确定的,但是可以指向的引用类型就不确定了:父类的引用可以指向子类。
2.子类没有重写调用父类的;子类重写父类,调用子类的;如果子类有的方法而父类无则,类型定义是父类但实例是子类的也不能用该方法,必须要先强制类型转化(高转低:基础阶段是容量大小的关系,此处是父子关系)才能用子类的方法。结论:**对象能执行哪些方法,主要看对象左边的类型,和右边关系不大。**也就是左边是子类的引用,可以调用子类的以及从父类继承的;左边是父类的则只能调用自己没被重写过的,或者子类中已经被重写的方法,而不能调用子类独有的方法。
3.多态的存在条件:有继承关系,方法需要重写,父类的引用需要指向子类对象(Father f1=new Son())。特别的有的方法不能被重写,如:1.static修饰的方法是属于类的不属于实例。2.final修饰的在常量池里,无法再改变了。3.private修饰的是私有的,也不能再去重写了。
4.多态是方法的多态;父类和子类需要有继承关系(否则会出现类型转换异常)。
8.方法的类型转换:(类型转换) 引用类型。
1.instanceof:用于判断一个对象是什么类型。

//Object>String(继承关系)
//Object>Person>Student(继承关系)
//Object>Person>Teacher(继承关系)
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
//作用:即可以通过instanceof判断类型是否相似,再进行之后的类型转换。
//1.格式:System.out.println(x instanceof Y);
//2.查看能否编译通过,存在父子关系才能通过编译(此处看的是左边的类型定义)
//3.结果是true还是false主要看的是x指向的实际类型是否是Y的子类型(此处看的是x的右边和Y的关系)
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);//编译就会报错!
	2.①Father f1=new Son();其实就是子类转化为父类,低转高自动转换,但是注意子类转父类可能会丢失自己本来的一些方法;②把子类转换为父类,向上转型;③当需要调用子类独有的方法时,需要把父类转化为子类,向下转型高转低,强制转换:((Son)f1).子类方法,可能会丢失方法;
	3.存在的意义:方便方法的调用,减少重复的代码。

9.static详解:加在方法上就是静态方法,加在属性上就是静态属性。
1.静态属性在类中只有一个,被类的所有实例共享,和类一起加载。
2.静态方法可以通过类名调用,非静态方法只能通过实例调用。
3.静态方法因为和类一起加载,只能调用静态方法,不能调用非静态方法(此处需要注意main方法也是静态方法);非静态方法可以调用静态方法。
4.只有一个花括号的叫匿名代码块,也可以有静态代码块,可以用于加载一些初始化的数据。其中代码块是在程序执行时不能主动调用,创建对象时创建,在构造器之前;静态代码块是在类一加载就执行,且执行一次。也就是当构造多个对象时,每个对象执行一次匿名代码块和构造方法,而静态代码块永久只执行一次。
5.导入静态导入包,例如:本应该使用Math.random();而加上静态导入包:import static java.lang.Math.random;后,就可以直接使用random(),而不必加上前面的类名了。
10.final:通过final修饰的类,就不能够被继承了,也就是不会再有子类了。
11.抽象类:由abstract修饰的类就是抽象类。(本质还是类,还是单继承,故接口存在是为了实现多继承)
1.方法也可以有abstract修饰,不含有方法体(没有花括号),只有方法的名字,是一种约束,凡是继承了抽象类的子类(非抽象类时)都必须实现它的方法。
2.不能new出实例,只是一个约束。
3.抽象类可以包含非抽象方法,但是有了抽象方法必须是抽象类。
4.抽象类存在构造方法,用于子类的实例化(因为会用到父类的构造器)。
5.存在的目的是提高开发效率。
12.接口:只有规范,不能自己的实现。不是类不用class,而用interface关键字。
1.接口就是规范,定义的是一组规则,本质是契约,实现了约束和实现的分离。
2.接口中的所有方法都是public abstract的,是默认的,可以不写。
3.接口不能被实例化,接口都需要类去实现接口,实现了接口的类,都需要重写接口中的全部方法,实现类一般都以Impr结尾,并且需要implements 接口名,并且implements可以多继承,区别extend只能单继承;
4.接口中可以定义属性,默认类型是public static final的。
5.接口中没有构造方法,接口常以Service结尾。
13.内部类:就是在一个类的内部在定义一个类,例如:在A类中定义一个B类,则B类就是A类的内部类,而A类是B类的外部类。
区别之前的内部类是在java文件中写了两个类,且一个java文件中只能有一个public类,但是可以有多高class类,main在哪个里面都可以,可以用来测试,但是一个项目只有一个main入口更合理。
1.成员内部类:需要通过外部类的实例去实例化内部类,内部类的特点是可以获得外部类的私有属性。

Outer outer=new Outer();//Outer是外部类
Outer.Inner inner=outer.new Innner();//Inner是Outer的内部类public class Inner{}
	2.静态内部类:内部类有public static class Inner{}时就不能在获得外部类的私有属性了,因为static是和类一起加载的,所以此时只能访问static的属性。
	3.局部内部类:写在方法中的类,类似于在方法中定义的变量是局部变量一样。
	4.匿名内部类:没有名字的类,就是没有名字初始化类,不用将实例保存到变量中。
			例如:一般会A a=new A();现在new A().aWay();
			例如:对于一个接口public interface UserService{...},通常会先由一个类实现它,但是也可以匿名实现,如:UserService userservice=new UserService(){...//接口的实现};其中new UserService(){...//接口的实现}就是实现了接口的类,但是没有名字。

九、异常机制

1.什么是异常:软件程序在运行过程中,常常可能遇见一些例外(Exception),异常发生在程序运行期间,影响了正常的程序执行流程。
1.常见的异常有以下三类:
1.检查性异常:常是由用户错误或问题引起的,程序员无法预见,这些异常在编译时不能被简单的忽略。
2.运行时异常:可以被程序员避免的异常,在编译时可以被忽略。
3.错误:错误不是异常,而是脱离程序员控制的问题,错误在代码中常常被忽略。
2.java中把异常当做对象来处理,定义一个基类java.lang.Throwable作为所有异常的超类(最顶层的类)。在java API中已经定义了许多异常类,这些异常类分为两大类:错误Error(无法预见的)和异常Exception(可以预见的)。
1.Error:由虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关。主要包括JVM异常:当JVM不再有继续执行操作所需的内存资源时,将出现OutOfMemoryError,此时JVM一般选择线程终止,还有些发生在虚拟机试图执行应用时,例如类定义错误、连接错误等,这些错误时不可查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的情况;AWTError异常(GUI编程)。
2.Exception:IOException异常;RuntimeException异常(运行时异常,一个非常重要的子类):这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
3.两者的区别是:Error通常是灾难性的,遇见后JVM一般选择终止线程;Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能地去处理这些异常。
2.异常的处理机制
1.抛出异常
2.捕获异常
3.异常处理的五个关键字:try、catch、finally、throw、throws。
4.快捷键:选中需要的代码,Ctrl+Alt+T,选择需要的包裹代码块的方式。(自动提供的e.printStackTrace();//打印错误的栈信息,通常还需要自己的一些逻辑或判断,例如:可以使用System.exit(0);手动结束程序)

public static main(){
int a=1;
int b=0;
try{//try监控区域,放被监控的代码
	if(b=0){//当知道明显容易的错误时,可以先判断,后主动抛出异常
		throw new ArithmeticException();//主动的抛出异常,throws和throw不一样
		//但是此处什么也没有做,常常发生在方法中:当该方法处理不了异常时,将异常向上抛出
	}
	System.out.println(a/b);
}catch(ArithmeticException e){//catch(想要捕获的异常类型最高的是Throwable)用于捕获异常
 /*如果需要捕获多个异常也可以,可以有多个catch(),但像if-else一样,需要层层递进一步一步扩大异常范围,否则在前面捕获了后面就不能捕获了,事实上范围写反会报错,提示该范围已被覆盖*/
	System.out.println("程序出现异常,被除数不能为零");
}finally{//无论出现什么都会执行,处理善后工作,可以不要finally,一般常见于IO流等资源的关闭!
	System.out.println("finally");
}
}

在方法上抛出异常:

public class Test{
//假设方法中处理不了这个异常,方法上抛出异常
public void test(int a,int b) throws ArithmeticException{
	if(b==0){
		throw new ArithmeticException();//主动地抛出异常,一般在方法中使用
	}
}

public static void main(String[] args){
	try{//此处是运行时异常,需要将异常捕获,否则方法抛出异常后,程序将会停止,捕获后程序可以继续
		new Test().rest(1,0);
	}catch(ArithmeticException e){
		e.printStackTrace();
	}
}
}

3.自定义异常:使用java内置的异常类,可以描述在编程时出现的大部分异常情况。此外,用户还可以自定义异常。用户自定义异常类,只需继承Exception类即可。
在程序中使用自定义异常类的步骤:
1.创建自定义异常。
2.在方法中通过throw关键字抛出异常。
3.如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作。
4.在出现异常方法的调用者中捕获并处理异常。

//自定义异常类
public class MyException extends Exception{
	//传递一个数,大于10出错
	private int detail;
	//首先需要一个构造器,得到需要的数字
	public MyException(int a){
		this.detail=a;
	}
	//其次需要一个tostring方法使其能够输出异常的信息
	@override
	public String toString(){//在tyr-catch里的e就是在执行这个方法
		return "MyException{"+"detail="+detail+'}';
	}
}
	5.快捷键:alt+enter。

4.总结
1.采用逻辑去合理规避同时辅助try-catch处理。
2.多重catch块后面,加一个catch(Exception)处理可能被遗漏的异常。
3.对于不确定的代码,加上try-catch处理潜在异常。(idea很多时候会报错,alt+enter查看帮助的处理方法)
4.尽量去处理异常,切忌只是简单地调用printStackTrace()去打印输出。
5.具体如何处理异常,根据不同的业务需求和异常类型去决定。
6.尽量添加finally语句块去释放占用的资源。

十、总结

看到最后一个总结视频的60`处,之后的还没学,总结是全部的所以这一部分先到此为止了。
在别人博客上看到了总结的图
接下来需要学习:常用类,集合框架,I/O流,目前为止找到的合适的是百度javaAPI学习。

看完视频还需要补的:
可以去Leetcode(力扣)刷题
单例模式
补充八大排序(B站西部开源其他老师有讲)
其余关键字理解(百度搜索即可)

  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值