Java基础

零.JDK

1.jdk的卸载:

​ 计算机–>卸载或更改程序–>
​ javaSE Development Kit9 update -->右键卸载

2.jdk的安装

​ 双击jdk-9.0.4_windows-x64_bin.exe -->下一步–>更改C:\Java\jdk-9.0.4–>下一步

3.检测是否安装成功

​ win+r -->输入cmd–>回车–>进入黑窗口(Dos命令行窗口)
​ 输入cd C:\Java\jdk-9.0.4\bin 回车 —>输入java -version回车 -->版本为9.0.4

一.java语言发展

​ java语言之父:詹姆斯.高斯林
​ jdk1.0发布时间:1995年
​ 最早的公司:Sun公司 -->最后被Oracle甲骨文公司收购,发布jdk7.0

二.Dos命令行窗口

​ 1.进入dos命令行窗口:win+R–>输入cmd–>回车
​ 进入计算机窗口:win+E
​ 快速显示桌面:win+D
​ 2.常用的命令
​ 1)切换盘符–> 盘符名称: (注意冒号是英文状态下的)
​ 统一设置:搜狗输入法–>工具箱–>属性设置–>常用–>中文时使用英文标点(把√勾上)–>应用–>确定
​ 2)进入单级文件夹–> cd 文件夹名称
​ 3)进入多级文件夹–> cd 文件夹名称1\文件夹名称2
​ 4)回退到上一级文件夹–> cd …
​ 5)回退到磁盘根目录–> cd
​ 6)显示当前文件夹下的所有内容–> dir
​ 7)清除屏幕–> cls
​ 8)退出命令行–> exit
​ 9)tab键–> 自动补全
​ 10)ctrl+s–> 手动保存

三.java程序的跨平台

​ java程序只用写一遍,针对不同的操作系统有对应的jvm虚拟机,保证java程序的跨平台是借助于jvm虚拟机的

Java的跨平台性和原理

​ 平台:操作系统,常见的操作系统,Windows、mac、Linux等
​ 跨平台:Java程序可以在不同的操作系统下运行
​ 原理:不同的操作系统有对应的JVM,JVM在中间相当于一个翻译
​ 注:JVM保证了Java的跨平台性,但是JVM并不具备跨平台性,也就是说不同
​ 的操作系统下有不同的JVM对应

四.JDK,JRE,JVM

​ JDK:java开发工具包,如果想要开发java程序,必须安装JDK
​ JRE:java的运行环境,如果只是运行java程序,只需要安装JRE
​ JVM:java的虚拟机, 保证java程序的跨平台
​ JDK包含JRE,JRE包含JVM
​ 总结:由JDK来开发java程序,交给JRE运行,由JRE中的JVM保证java程序的跨平台

JDK、JRE和JVM的概念和区别

​ JDK:Java开发工具包
​ JRE:Java运行环境
​ JVM:Java虚拟机

JRE = JVM + 核心的类库
JDK = JRE + 开发工具包

JDK > JRE > JVM 
如果要运行Java程序,必须安装JRE
如果要进行Java程序开发,必须按照JDK

五.配置环境变量

​ 1.为什么要配置环境变量:
​ 如果没有配置环境变量,那么所有的java程序必须在jdk安装的bin目录下编写,
​ 配置环境变量就可以在任意目录下编写java程序,通过javac和java命令来运行
​ 2.怎么配置环境变量:
​ 计算机右键–>属性–>高级系统设置–>环境变量–>在系统变量下
​ 1)新建 变量名:JAVA_HOME
​ 变量值:C:\Java\jdk-9.0.4
​ 新建完成之后确定
​ 2)编辑Path:在变量值上将光标移动到最前面添加 %JAVA_HOME%\bin;
​ 3)点击三个确定–>重启dos命令窗口输入java -version查看jdk版本

六.进制转换

​ Java中常见的进制
​ 二进制:由0和1组成的,0b开头
​ 八进制:由0~7组成的,0开头,一个八进制为等于3个二进制位
​ 十进制:由0~9组成的
​ 十六进制:由09,af组成的,0x开头,一个十六进制等于4个二进制位

8421码
	16 8 4 2 1
	
请画图演示十进制数78这个数字,转为二进制的过程,然后再将这个二进制转为十进制

计算机中存储数据的最小单元:字节(Byte)

七.Java程序开发的三步骤

1.编写

1、创建一个文本文档,修改名称和后缀名,目前文件就叫HelloWorld,后缀名是java
		2、打开HelloWorld.java文件,编写HelloWorld代码
			public class HelloWorld {
				public static void main(String[] args) {
					System.out.println("Hello,World!");
				}
			}
		3、保存文件(ctrl+s)

2.编译

javac命令
		compile 编译
		

	(1)进入到源代码所在的目录,找到源代码
	(2)通过javac命令
		javac 文件名.java
		
	编译之后会生成一个.class文件,该文件称为字节码文件

3.运行

java命令
	java 类名

八.注释

​ 作用:对代码进行解释说明

	分类:
		(1)单行注释
			// 注释的内容
		(2)多行注释
			/*
				注释的内容
			*/
		(3)文档注释
			/**
				注释的内容
			*/

九.关键字

​ 在Java中有特定含义的单词,只能在特定的情况下使用,不能随便使用
​ 比如class就是一个关键字,只能在定义类的时候使用

特点:
	(1)形式上都是英文的小写
	(2)在高级编辑工具中会有颜色变化

十.标识符

​ 什么是标识符
​ 用于取名字的符号,比如给类、方法、变量等取名字的
​ 标识符的组成规则【硬性要求】
​ (1)英文大小写字母,另外中文、日文和韩文等字符也可以使用
​ (2)数字
​ (3)美元符($)
​ (4)下划线(_)

	注意事项:
		(1)不能以数字开头
		(2)不能是关键字
标识符的命名规范【软性要求】
	类:如果是一个单词组成,首字母大写即可,如果是多个单词组成,每个单词的首字母大写,其余小写,比如HelloWorld,Hello
	方法和变量:如果是一个单词组成,全部小写,如果是多个单词组成,从第二个单词开始首字母大写,其余小写,比如main,getMax

以下属于合法的标识符的有()
	hello123				√
	$class					√
	Hello World				×,包含了空格
	Hello_World				√
	public2					√
	void					×,是一个关键字

十一.常量

​ 什么是常量
​ 在程序运行的过程中,其值固定不变的量

常量的分类
	自定义常量
		
	字面值常量
		(1)字符串常量,是使用""引起来的内容,比如:"Hello,World!","123"
		(2)整数常量,比如:10,20,-5
		(3)浮点数(小数)常量,比如:2.5,-8.0
		(4)字符常量,是使用''引起来的内容,其中的内容有且只能有一个字符,不能有多个,也不能一个都没有
			比如:'a','1',' '
		(5)布尔常量,只有两个值:true和false
		(6)空常量(null)

十二.数据类型

​ 基本数据类型(4类8种)
​ 整数类型 字节 取值范围
​ byte 1 -128~127 -2^7 ~ 2^7-1
​ short 2 -2^15 ~ 2^15-1
​ int 4 -2^31 ~ 2^31-1
​ long 8 -2^63 ~ 2^63-1
​ 浮点类型
​ float 4
​ double 8
​ 布尔类型
​ boolean 1 true和false
​ 字符类型
​ char 2 0 ~ 65535
​ 引用数据类型
​ 类
​ String
​ 接口
​ 枚举
​ 数组

十三.变量

​ 什么是变量
​ 在程序的运行过程中,其值可以发生改变的量

变量的定义和使用格式:
​ (1)先定义再使用
​ 数据类型 变量名; // 定义变量
​ 变量名 = 值; // 使用变量,赋值

​ (2)定义的同时赋值
​ 数据类型 变量名 = 值;

十四.数据类型的转换

​ 这里的转换,指的是基本数据类型的转换

分类
	自动类型转换(隐式转换):不需要进行特殊处理,能够直接转换,类型的取值范围从小到大
		转换的小公式:
			byte、short、char->int ->long ->float ->double
		
		注意:
			(1)boolean类型的不能和其他7种之间进行转换
			(2)byte、short不能直接转换成char,反之亦然
			
	强制类型转换(显式转换):需要进行特殊处理,不能直接转换,类型的取值范围从大到小
		格式:
			小的数据类型 变量名 = (小的数据类型)大类型的数据;
			比如:
				int i = (int)120L;

十五.运算符

1.算术运算符

+  - * /  %  ++  --

	/ :
		(1)得到相除的商,整数相除只能得到整数,如果要得到小数,必须有小数参与运算
		(2)负数参与运算,如果除数或者被除数其中有一个为负,得到的结果也为负,否则都是正
	%:
		(1)得到的相除的余数
		(2)负数参与运算,得到的结果是正还是负,只和被除数是正还是负有关,和除数无关的
		
	++:自增1
		
	--:自减1

面试题:
		++在前和在后,使用的时候的区别?
		(1)单独使用,没有区别
			 ++num;
			 num++;
		(2)混合使用
			++在前,变量自增1,然后将自增的结果再使用
			++在后,先使用变量原来的值,然后再自增1
			

2.赋值运算符

基本的赋值运算符:=
		将运算符右边的值,赋给左边,让左边的变量来存储右边的值
	复合的赋值运算符:+= -= *= /= %=
		将运算符左边和右边进行运算,得到的结果赋值给左边
		
		注:
			复合的赋值运算符隐含了强制类型转换
			
			short s = 5;
			s += 1;// s = (short)(s + 1);
			System.out.println(s);// 6		

3.比较运算符

==  !=  <  <=  >  >=
	
	得到的结果都是boolean类型的,不是true就是false	

4.逻辑运算符

&&:遇false则false,只有两边都为true时结果才为true
	||:遇true则true,只有两边都为false时结果才为false
	!:非true则false,非false则true
	&:遇false则false,只有两边都为true时结果才为true
	|:遇true则true,只有两边都为false时结果才为false
	^(异或):只有两边不同时结果才为true,否则都为false
面试题:
		&和&&的区别?
			&&有短路效果,当运算符左边已经能够确定最终的结果,右边不参与运算
		

5.三元运算符

格式:	
		数据类型 变量名 = 布尔表达式?表达式1:表达式2;
		
	执行流程:
		先执行布尔表达式,看结果是true还是false
		如果结果是true,执行表达1
		如果结果是false,执行表达2
		
	注:布尔表达式的结果一定是true或者false,不能是其他结果

十六.流程控制语句

1.顺序结构

​ 按照从上往下的顺序依次执行

2.选择结构

(1)if语句
格式一:单if
			if(布尔表达式){
				// 语句体;
			}

		执行流程:
			首先判断布尔表达式的结果,如果是true,就执行if里面的语句体
			如果是false,就不执行。
	
格式二:if...else...
		if(布尔表达式){
			// 语句体1;
		}else {
			// 语句体2;
		}
		
		执行流程:	
			首先判断布尔表达式的结果,如果是true,就执行if里面的语句体
			如果是false,就执行else里面的语句体
			
		二选一的情况,有且仅会有一个语句体会执行
		
格式三:if...else if...else
		if(布尔表达式1){
			// 语句体1;
		}else if(布尔表达式2){
			// 语句体2;
		}else if(布尔表达式3){
			// 语句体3;
		}
		...
		else {
			// 语句体n+1;
		}
		
执行流程:
		首先执行if小括号中的布尔表达式1,如果为true,就执行语句体1,然后整个if语句结束;
		如果为false,继续判断else if小括号中的布尔表达式2,如果为true,就执行语句体2,然后整个		if语句结束;
		如果为false,依次类推,继续判断else if小括号中的表达式
		最后如果所有的布尔表达式的结果都为false,这时才执行else里面的语句体n+1
			
		多选一的情况,有且仅会有一个语句体会执行
(2)switch语句
格式:
		switch(表达式){
			case 值1:
				// 语句体1;
				break;
			case 值2:
				// 语句体2;
				break;
			case 值3:
				// 语句体3;
				break;
			...
			default:
				// 语句体n+1;
				break;
		}
		
执行流程:	
		首先执行表达式,拿到表达式的结果从上往下依次匹配case后面的值,
		如果相等,就执行对应case里面的语句体,执行完之后结束整个switch语句
		如果不相等,继续匹配下面的case后面的值
		依次类推,如果相等就执行对应的case后面的语句体,执行完之后结束整个switch语句
		如果不相等,继续匹配下面的case后面的值
		当所有的case都不匹配的时候,最终会执行default里面的语句体,结束整个switch语句
			
注意事项:
		(1)default语句的位置可以任意,可以在所有的case之上,也可以在所示的case之下,还可以在多个case之间
			default语句的位置在哪里,不影响程序的正常执行流程
			甚至default语句都可以省略,一般不建议省略default语句
		(2)switch后面的小括号中的表达式的结果的类型只能是
			byte short char int
			JDK1.5之后可以是枚举
			JDK1.7之后可以是String
		(3)case穿透问题
			switch语句结束的条件由两个:第一个是遇到break,第二个遇到switch的右大括号(})
			当break省略之后就容易出现case穿透问题
(3)循环结构
for循环
		格式:
			for(初始化语句;布尔表达式;步进语句){
				循环体;
			}
while循环
	标准格式:
		while(布尔表达式){
			循环体;
		}
	
	扩展格式:
		初始化语句;
		while(布尔表达式){
			循环体;
			步进语句;
		}		
do...while循环
	标准格式:
		do{
			循环体;
		}while(布尔表达式);
		
	扩展格式:
		初始化语句;
		do{
			循环体;
			步进语句;
		}while(布尔表达式);
		
	特点:
		不论布尔表达式结果是否为true,循环体一定至少会执行一次

1.三种循环的区别
	1、do...while跟for和while的区别
		do...while不论布尔表达式结果是否为true,一定会至少执行一次循环体
		for和while如果布尔表达式结果为false,不会执行循环体
	2、for跟do...while和while的区别
		for中定义的初始化语句,只在for循环中有效,出了for循环消失了不可以用
		do...while和while循环里的初始化语句,即使出了循环也可以继续使用	
2.循环的选择
(1)循环的次数确定,选择的顺序: for > while > do...while
		(2)循环的次数不确定,选择的顺序: while > for > do...while
			while(true){
				// 当满足条件,可以通过跳转语句,结束循环
			}
3.跳转语句
break
		使用场景:
			1、在switch语句中,用于退出switch语句
			2、在循环中,用于结束整个循环
			
		注:
			出了使用场景使用break会出错。
	continue
		使用场景:
			只能在循环中使用
			用于结束当次循环,继续下一次循环
面试题:
		请说说break和continue的区别?
		
		(1)使用场景的区别
		(2)在循环中的作用的区别
		
4.死循环
1、
		while(true){
		
		}
2、
		for(;;){
			
		}

十七.方法

什么是方法
        是一段特定功能的代码,抽取出来放到一对大括号中,然后取上名字
*.注意事项:
(1)方法必须位于类中,不能直接写在.java文件中,也不能写到另一方法中(方法不能嵌套)
    (2)方法要运行必须调用
        方法名();
1.格式:
  修饰符 返回值类型 方法名(参数列表){
        // 方法体;
        retrun 返回值;
    }

    修饰符:public static
    返回值类型:
            规定了方法的返回值对应的数据类型
            如果方法有返回值,类型必须对应
            如果方法没有返回值,返回值类型也不能省略,必须使用void
    方法名:
            给方法取一个见名知意名字
            方法名方便调用
    参数列表:
            参数列表可以有,也可以没有
            参数列表可以有多个,多个之间用逗号(,)隔开
            由两部分组成:
                参数类型
                变量名称
     方法体:
            方法执行的核心代码
     return 返回值:
            return有两个作用,一:结束方法 二:返回方法执行后的结果
            如果方法有返回值,就可以通过return返回
            如果方法没有返回值,这时return;,这样的语句可以省略
    参数列表相当于原材料(输入)、返回值相当于成品(输出)

2.方法的调用
 有返回值的方法
        (1)单独调用,得不到结果
        (2)输出调用,将得到的结果打印出来
        (3)赋值调用,将得到的结果用一个变量接收起来,方便使用
    无返回值的方法
        (1)单独调用

3.方法重载(Overload)
在同一个类,有多个方法名相同,但是参数列表不同的方法
    重载的条件
        (1)同一个类中,方法名相同
        (2)参数列表不同
            a:参数个数不同
            b:类型不同
            c:顺序不同
         只和以上两个条件有关,和其他(返回值类型、修饰符、变量名)无关

 面试题:
   以下和public static int method(int a,double b)方法构成重载的有()
        public int method(int i,double j)               ×
        public static int method(double a,int b)        √
        public static void method(int a,double b)       ×
        public static void method(int a,int b)          √
        public static void method(int a,int b,double c) √

4.方法重写(Override)

十八.数组

数组的概念:
    数组是一种容器,可以存储多个元素
特点:
    (1)数组是一种容器,可以存储"同一种数据类型"的多个元素
    (2)数组有整数索引(编号),索引的范围在0~数组的长度-1
    (3)数组存储的元素即可以是基本数据类型,也可以是引用数据类型
    (4)数组一经初始化长度就固定了

1.数组的定义
 数据类型[] 数组名;          // 推荐使用的方式
  举例:int[] array;
 数据类型 数组名[];
  举例:int array2[];

2.数组的初始化
动态初始化:在初始化的时候给定数组的长度,由系统来赋予默认初始化值
        数据类型[] 数组名 = new 数据类型[数组的长度];
        格式举例:
            int[] arr = new int[3];
        格式解释:
           数据类型[] 数组名 = new 数据类型[数组的长度];
           左边
               数据类型:规定了数组中能够存储的元素的数据类型
               []:说明定义的是一个数组类型
               数组名:给数组取一个名字,方便使用
           右边
               new:是一个关键字,用于在内存中开辟一片内存空间,固定写法
               数据类型:规定了数组中能够存储的元素的数据类型,和定义的时候的数据类型必须一模一样
               []:说明定义的是一个数组
               数组的长度:规定了数组能够存储的元素的个数
        数组中元素的默认初始值:
                整数类型(byte、short、int、long)      :0
                浮点类型(float、double)               :0.0
                布尔类型(boolean)                    :false
                字符类型(char)                       :'\u0000'
                引用数据类型                           :null

静态初始化:在初始化的时候,给定数组的元素,由系统计算数组的长度
    标准格式
        数据类型[] 数组名 = new 数据类型[]{元素1,元素2,....};
        举例:
            int[] array = new int[]{10,20,30};

    简化格式
        数据类型[] 数组名 = {元素1,元素2,....};
        举例:
            int[] array = {10, 20, 30};

3,数组的元素访问
 取值
    数据类型 变量名 = 数组名[索引];
 赋值
    数组名[索引] = 新值;

4.Java中的内存划分
  栈:方法要执行在栈区中要开辟空间,局部变量是方法中的变量,随着方法都在栈区
        栈内存中的变量,一使用完立马消失
  堆:一切new出来的东西,比如数组、对象
        有地址值
        堆内存中的东西用完不是立马消失,消失有时机(垃圾回收机制)
  方法区
        .class文件

本地方法栈:和操作系统相关
寄存器:和CPU相关

5.数组中的两个常见错误(异常)
数组索引越界异常
  ArrayIndexOutOfBoundsException
    产生的原因:
        操作的索引超出了数组的索引范围:0~数组的长度-1
    解决方式:
        让操作的索引在数组的索引范围
空指针异常
  NullPointerException
    产生的原因:
        直接给数组类型的引用赋值为null,而没有new
        还去使用它
    解决方式:
        给它补上new

6.获取数组的长度
length属性
   int len = 数组名.length;

7.数组的常见操作
 1、数组的遍历:将数组中的元素按顺序依次取出来
        // 定义一个数组
        int[] arr = {3,1,5,8,9};
        // 遍历数组
        for(int i=0;i<arr.length;i++){// i在0~arr.length-1之间变化
            // i代表的就是索引值,每循环一次会依次增加1
            System.out.println(arr[i]);
        }

2、数组元素求和:将数组的元素的值加总起来
    // 定义一个数组
    int[] array = {9,10,-2,5,3};

    // 求和变量
    int sum = 0;
    // 遍历求和
    for (int i = 0; i < array.length; i++) {
        // array[i]代表的就是每一个元素
        sum += array[i];
    }

    // 打印求和的结果
    System.out.println(sum);

3、数组元素求最值(最大值和最小值):求出数组中的元素的最大值或者最小值
    // 定义一个数组
    int[] array = {9,10,-2,5,3};

    // 定义一个变量用于记录最大值
    int max = array[0];

    // 遍历比较,求出最大值
    for(int i=1; i<array.length; i++){
        if(array[i] > max){
            max = array[i];
        }
    }

    System.out.println("最大值为:"+max);

4、数组的反转:将数组中存储的元素倒过来        1 2 3 -> 3 2 1

5、数组元素查找:给定一个元素查找出该元素在数组中的索引位置

6、数组的元素排序:按照一定的顺序(从小到大或者从大到小)对元素进行排列   {3,1,5,8,9} ->{1,3,5,8,9}
   冒泡排序
   选择排序

十九.面向对象

面向对象的概念
    面向过程:强调的是过程(步骤),关注的是“我该如何做”,所有完成功能的步骤和过程都是自己亲力亲为
	面向对象:强调的是对象,关注的是“谁来帮我做”,其中的“谁”指的就是对象
	面向对象是基于面向过程的
面向对象的优点:
    (1)更符合人们的思维习惯,懒人思想
    (2)将复杂的事情简单化
    (3)从任务的执行者变成了指挥者

1.类与对象
学习编程语言为了解决现实世界的实际问题,使现实世界实现信息化
在Java语言中我们使用类来描述现实世界的事物
    类                     事物
    成员变量             	属性:特点
    成员方法             	行为:能够做什么
类:是对象的抽象描述,是一系列属性和行为的集合,它是模板
对象:是类的具体体现,它是根据模板创建的一个个具体事物

类只有一个,但是根据类可以创建出无数个对象
要创建对象,必须先有类

类根据作用不同可以分为很多种:
    标准类(JavaBean):描述现实事物类
    测试类:每个类都有主方法,都可以独立运行

2.使用一个类的步骤
(1)创建对象(导包)
        类名 对象名 = new 类名();
        举例:
            Student stu = new Student();
(2)使用
        成员变量
            赋值
                对象名.成员变量名 = 新值;     // 这里“.”可以为“的”
                举例:
                    stu.age = 18;
            取值
                数据类型 变量名 = 对象名.成员变量名;
                举例:
                    int age = stu.age;
        成员方法
            调用格式:
                对象名.成员方法名(参数);
                举例:
                    stu.study();

3.类作为方法的形式参数
形式参数
       数据类型
            基本数据类型
            引用数据类型
                数组
                类
                    JDK提供的:String
                    自定义的:Phone
            接口
            枚举
    	变量名

如果一个类作为方法的形式参数的类型,需要传递的是该类的对象,本质上其实传递的是该对象的内存地址值

4.类作为方法的返回值类型
类作为返回值类型,应该使用return返回的是该类的对象,本质上其实返回值的该对象的内存地址值

局部变量和成员变量的区别(面试题)
(1)定义的位置
    局部变量:在方法的小括号或者大括号
    成员变量:在类中方法外
(2)作用域(范围)
    局部变量:只能在所在的方法中
    成员变量:在整个类中
(3)默认值
    局部变量:没有默认值,使用之前必须先赋值,否则就报错
    成员变量:有默认值
(4)内存中的位置
    局部变量:跟着方法进入栈内存
    成员变量:跟着对象进入堆内存
(5)生命周期
    局部变量:随着方法的进栈而存在,随着方法的出栈而消失,立刻回收
    成员变量:随着对象的创建而存储,随着对象被垃圾回收机制回收而消失,在合适的时候回收

5.面向对象的三大特征
 	封装
    继承
    多态

封装
简单说,拿一个箱子装起来,密封起来,让其中的东西对外界不可见

隐藏实现的细节问题,对外不可见,但是要提供公共(public)的访问方式。

封装的体现:
    (1)方法
    (2)private修饰成员变量
private
    是一个关键字,被private修饰的成员变量只能在本类中使用,其他类中不能用
    以后我们都必须用private修饰成员变量,同时提供一对getter和setter方法
this关键字
    this:代表的是当前对象的引用,谁来调用方法,当前对象就是谁,每一个非静态(不是static修饰)方法内部都有一个this
    作用:
        (1)通过this.成员变量的方法调用本类的成员变量
            当局部变量和成员变量同名的时候,通过this.成员变量的方式区分这是一个成员变量
构造方法
    用于创建对象,并给成员变量赋值
格式:
    public 类名(参数列表){
        // 方法体
        return;
    }
格式的特点:
   (1)没有返回值,当然也没有返回值类型,连void都没有
   (2)构造方法名和类名一致,大小写也相同
   (3)return;可以省略
给成员变量赋值的方式
    方式一:
         对象名.成员变量名 = 新值;
     不推荐使用,原因是学习了封装之后,所有的成员变量都会用private修饰
     修饰之后,这种方式用不了了
	方式二:
    通过setter方法
    Student stu = new Student();
    stu.setName("张三");
	方式三:
    有参构造
    Student stu = new Student("张三", 30);

继承(extends)
现实世界中的继承是儿子拥有父辈的财产
    在Java中的继承是子类拥有父类的“内容”
    描述的是一种所属关系,"is a"的关系
子类拥有父类的“内容”
    内容:
        非private修饰的成员变量
        非private修饰的成员方法
     注意:
        (1)构造方法不能被继承
        (2)私有的成员变量和成员方法不能被继承
继承的由来
    多个类的共性内容不断向上抽取,得到的类就是父类,这多个类就可以称为子类
继承的格式:
    public class 子类 extends 父类 {}
继承的好处:
    (1)提供了代码的复用性
    (2)继承是多态的前提之一
继承中成员变量访问的特点
    (1)继承之后,只可能子类拥有父类的内容,但是不可能父类去拥有子类的内容
    (2)就近原则,子类中如果有则使用子类的,如果子类中没有则使用父类的
    (3)如果是通过成员方法间接访问,对象是谁我就找谁,如果没有再往上找
局部变量、本类的成员变量和父类的成员变量重名情况下的访问
    (1)就近原则,谁离我近我就使用谁
        如果有局部变量,就使用局部变量,
        如果没有局部变量,就找本类的成员变量,
        如果本类的成员变量没有,就找父类的成员变量
        如果父类的成员变量也没有,报错
    (2)如果局部变量、本类的成员变量和父类的成员变量都有
        如果想访问局部变量,直接访问
        如果想访问本类的成员变量,通过this.的方式访问
        如果想访问父类的成员变量,通过super.的方式访问
继承中成员方法访问的特点:
    就近原则,谁离我近我就使用谁
    子类有该方法,创建子类对象使用的是子类的方法,
    如果子类没有该方法,则向上找父类的方法
    如果父类也没有该方法,则报错
方法重写(覆盖)
    什么是方法重写
        在继承关系中(子父类),子类和父类中的方法声明(一般)一致,但是方法体进行重新定义的过程
    为什么要方法重写(使用场景)
        继承之后,父类的方法无法满足子类对于功能的需求
    方法重写的条件(注意事项)
      方法重写一般都是子类的方法声明和父类完全一致,但是如果偏要声明不一致,则需要满足以下条件:
        一大两同两小
        一大:子类重写的方法的权限修饰符必须大于等于父类方法的权限修饰符
            权限修饰符:public > protected > 默认 > private
            以下属于的权限修饰符的是
            a.private
            b.static
            c.default
            d.void
        两同:
            子类重写的方法必须和父类的方法名完全相同
            子类重写的方法的参数列表必须和父类的方法参数列表完全相同
        两小:
            子类重写的方法的返回值类型必须小于等于父类方法的返回值类型(针对的只是引用数据类型,对基本数据无效)
                如果返回值类型是基本数据类型或者是void,那么子类必须一样
                如果返回值类型是引用数据类型,满足小于等于就可以,引用数据类型大小:父类 > 子类
            子类重写方法抛出的异常必须小于等于父类的异常,或者少于等于父类的异常,
            如果父类没有抛出异常,子类方法必须不能有异常
 面试题:方法重写和方法重载的区别
        方法重载(Overload)
            (1)在同一个类中
            (2)方法名相同,参数列表不同
            (3)和其他(权限修饰符、返回值类型、抛出的异常)的无关
        方法重写(Override)
            (1)在多个类(有继承关系的子父类)中
            (2)方法名相同,参数列表相同
            (3)和其他(权限修饰符、返回值类型、抛出的异常)的有关
                如果不同需满足以上的条件
继承中,父子类构造方法访问的特点:
    父类构造方法一定会先于子类构造方法执行。
    (1)每一个构造方法的第一行语句默认都有一个super(),调用的是父类的无参构造方法
    (2)如果显式在构造方法中使用super(参数)和this(参数),这样的语句调用父类的构造方法或者本类的其他构造方法,
        那么默认的super()就没有了。
        super(参数)和this(参数)必须位于构造方法的第一行来调用,而且它们在同一个构造方法中不能同时出现
        super(参数)和this(参数)只能在构造方法中使用,不能在其他地方使用
this和super的区别
    this:代表当前对象的引用,谁来调用方法谁就代表当前对象
        (1)可以调用本类的成员变量,通过this.成员变量
        (2)可以调用本类的成员方法,通过this.成员方法
        (3)可以在本类的构造方法中的调用本类的其他构造方法,通过this(参数)的方式
    super:代表父类的那片空间,通过它可以访问父类的内容
        (1)可以在本类成员方法中调用父类的成员变量,通过super.成员变量
        (2)可以在本类成员方法中调用父类的成员方法,通过super.成员方法
        (3)可以在本类的构造方法中调用父类的构造方法,通过super(参数)的方式
继承中的三个特点:
    (1)Java语言中的类是单继承的,不支持多继承
        也就是一个类只能有一个直接父类,不能有多个直接父类
    (2)Java语言中的类可以多层继承
        多层继承,一个类不光可以继承父类中的内容,还可以继承爷爷类中内容
    (3)Java语言中一个类可以是多个类的父类
抽象(abstract)类
    抽象:反义词是具体,不清楚不确定
抽象的由来
    多个类不断向上抽取,在多个类中的功能是具体是明确的,但是抽取到父类中之后该功能就不明确了
    例如:一个三角形计算面积可以具体实现,一个圆形计算面积也可以具体实现,它们两个都有计算面积的方法
        这时共性内容不断向上抽取,形成一个父类,父类中的计算面积的方法就无法明确如何实现,这是这个方法就应该
        定义为抽象的方法。
抽象类:使用abstract关键字修饰的类
        如果一个类中有抽象方法,那么这个类必须是抽象类
格式:
    // 抽象类
    public abstract class 类名 {
         // 抽象方法
         public abstract 返回值类型 方法名(参数列表);
    }
抽象类的特点:
    (1)抽象类和抽象方法都必须使用abstract关键字修饰
    (2)不能创建对象
    (3)一个类去继承抽象类,要么实现所有的抽象方法
        要么该类必须也是一个抽象类
    (4)抽象类有构造方法
       构造方法两个作用:
        a:创建对象
        b:给成员变量初始化
    (5)类与抽象类之间的关系是继承
    (6)抽象类中可以有抽象方法也可以没有抽象方法
        抽象类中可以非抽象的方法

多态
什么是多态
    现实中指的是,事物的多种形态
	 在Java中的多态,指的是对象的多种形态
多态的前提:
    (1)有继承或者实现关系
    (2)方法重写
    (3)父类的引用指向子类的对象,父接口的引用指向实现类的对象
多态格式:
    父类类名【父接口名】 对象名 = new 子类类名【实现类名】();
    例如:Animal a = new Dog();
多态下成员方法调用的特点:
    编译看左边(父类),运行看右边(子类)
    编译的时候看父类中是否有这个方法,如果没有编译就报错,如果有,运行的时候执行的子类中的方法
引用数据类型的转换
    向上转型:小的类型(子类或者实现类)转为大的类型(父类或者接口),其实多态就是一种向上转型
    向下转型:大的类型(父类或者接口)转为小的类型(子类或者实现类)
        格式:
            小的类型 变量名 = (小的类型)大的类型的数据;
基本数据类型的转换
  隐式转换(自动类型转换):取值范围小的类型转为取值范围大的类型
        byte/short/char ->int ->long ->float ->double
    		byte b = 20;
   		int i = b;
    		short s = 30;
    		int i2 = b + s;
  显式转换(强制类型转换):取值范围大的类型转为取值范围小的类型
    	小的类型 变量名 = (小的类型)大的类型的数据;
    		int i3 = 100;
   		 byte b2 = (byte)i3;
多态的优缺点
  缺点:
      多态之后(向上转型),不能再调用子类特有的方法
  优点:
      提高了代码的复用性
类型转换异常:ClassCastException

instanceof运算符
格式:
    对象或者对象名 instanceof 类型名
作用:
    判断对象是否是指定的类型
使用
    编译报不报错
        instanceof作用的对象的类型和右边的类型名必须有子父类或者父子类关系,否则编译报错
    运行结果是否为true
        如果编译不报错,结果到底是true还是false,要看运行是否属于指定的类型

二十.接口(interface)

    接口是有一种公共的规范标准。
定义格式:
    public interface 接口名 {}
 接口名的命名规范和类名一致

接口中的内容
如果是Java 7,那么接口中可以包含的内容有:
    1. 常量
       1. 抽象方法
如果是Java 8,还可以额外包含有:
    1. 默认方法
       1. 静态方法
如果是Java 9,还可以额外包含有:
    1. 私有方法

注意:接口中不能有变量和构造方法

接口中的抽象方法
定义格式:
    public abstract 返回值类型 方法名(参数);
    接口中的抽象方法有默认修饰符:public abstract,即使不写默认也有
    抽象类中的抽象方法没有默认修饰符,如果是抽象方法就必须加上abstract

接口的使用步骤:
(1)不能直接创建对象,编写一个实现类去实现该接口
        实现的格式:
            public class 实现类名 implements 接口 {}
(2)实现类要实现接口的所有的抽象方法
        一个类去实现接口必须实现其中的所有抽象方法,否则该实现类必须声明为抽象类。
(3)在测试类中创建实现类的对象,使用

接口中的默认方法
格式:
     public default 返回值类型 方法名(参数) {}
默认方法中的public可以省略,但是default不能省略
默认方法可以被实现类型创建对象直接调用,也可以被实现类重写

接口中的静态方法
格式:
      public static 返回值类型 方法名(参数) {}
使用格式:
    接口名.静态方法名();
    注意:不能通过实现类的对象来调用接口中的静态方法

接口中的私有方法
普通私有方法,多个默认方法重复代码的问题
   private 返回值类型 方法名(参数列表){}
静态私有方法
   private static 返回值类型 方法名(参数列表){}

接口中的常量
 常量分类
    字面值常量
            整数常量        10,-5
            浮点数常量       2.5
            字符常量        'a'
            布尔常量        true false
            字符串常量       "abc"
            空常量           null
    自定义常量
        通过final关键字定义
	  	格式:
    		public static final 数据类型 常量名 = 值;
(1)接口中的常量有默认修饰符:public static final ,即使不写默认也有
(2)常量的命名规范:都是大写字母组成,如果有多个单词组成,每个单词之间用下划线(_)隔开
(3)常量必须赋值
(4)由于接口中的常量是static修饰的,所以使用的时候可以直接“接口名.常量”的方式使用

一个类在继承一个类的同时,还可以实现多个接口
    类与类之间是继承关系,单继承,不支持多继承,支持多层继承
    类与接口是实现关系,多实现
    接口与接口之间是继承关系,多继承
    class A extends B implements C,D {
    }

二十一.Scanner类 Random类 String类

Scanner类
作用:通过键盘录入数据
使用步骤:
    (1)创建对象
        Scanner sc = new Scanner(System.in);
    (2)使用
        int i= sc.nextInt();
        String str =sc.next();

Random类
作用:用于生成随机数(任意变化的数)
使用步骤:
    (1)创建对象
        Random r = new Random();
    (2)使用
        int num = r.nextInt();
        int num = r.nextInt(10);// [0,10)
常用方法:
     int nextInt():生成一个在int范围内(-2^31 ~ 2^31-1)的随机整数     [使用较少]
     int nextInt(int i):生成一个在0~i-1范围的随机整数                [使用较多]

String类
String类的概述
        表示的是字符串,它位于java.lang包下,使用的时候不需要导包
        字符串是一个常量,一旦创建了内容不会发生改变
        是一个引用数据类型(类类型),不是基本数据类型
        "abc"这样的字符串也是String类的一个对象,即使没有new
创建对象的4中方式
    构造方法:
        String():                       //使用很少
        String str = new String();  // String s = "";
        String(char[] chs):传递char类型数组构造一个String类型对象
        String(byte[] bys):传递byte类型数组构造一个String类型对象
        String(String original):传递一个String类型的数据构造一个String类型的对象
        String str = new String("abc");// String str = "abc";
    直接创建:
        String str = "abc";             // 使用最多
判断方法
     boolean equals(Object o):判断两个字符串的内容是否相等,区分大小写
     boolean equalsIgnoreCase(Object o):判断两个字符串的内容是否相等,不区分大小写
    	 面试题:请说出==和equals的区别
       		 ==可以比较基本数据类型的数据,比较的时候是比较值是否相等,
            		也可以比较引用数类型,比较的时候是比较地址值
        		equals方法只能比较引用数据类型,比较的时候是比较里面的内容,
            		String也是一种引用数据类型,所以使用equals比较的也是内容
获取方法
    int length():获取字符串的长度(字符串中字符的个数)
    char charAt(int index):获取指定索引处的字符
    String concat(String str):拼接字符串,作用和“+”
    int indexOf(String str):获取指定的字符串在大字符串中第一次出现的索引位置,如果没有找到返回-1
        面试题:请说说数组、集合和字符串分别如何获取长度?
            数组的长度:数组名.length
            集合的长度:集合名.size()
            字符串的长度:字符串.length()
截取方法
    String substring(int index):从指定索引(包括)处截取一直到末尾
    String substring(int start,int end):从指定的start索引(包括)处开始截取一直到end索引(不											  包括)处结尾
转换方法
    char[] toCharArray():将字符串转为字符数组
    byte[] getBytes():将字符串转为字节数组
    String replace(String oldString,String newString):将字符串中的oldString转为newString
切割方法
    String[] split(String regex):,和空格这些可以直接根据它们来切割,但是如果是.必须转义写成\\.

二十二.static关键字 final关键字 权限修饰符

static是一个关键字,也可以叫做静态修饰符,可以修饰成员变量、成员方法和静态代码块
    static修饰的成员变量属于类,而不属于某个对象,而是被该类的所有对象所共享
什么情况下使用static修饰成员变量?
    当一个类的多个对象中有某个成员变量的值都相同,该成员变量就可以使用static修饰,否则不用

static的特点:
(1)static修饰的成员(成员变量和成员方法)都是属于类的,调用的时候更方便,直接通过类名.的方式调用
        原来的调用方式也是可以的,但是我们推荐使用类名.的方式来调用
         MyClass obj = new MyClass(); // 首先创建对象
        // 对于静态方法来说,可以通过对象名进行调用,也可以直接通过类名称来调用。
        obj.methodStatic(); // 正确,不推荐,这种写法在编译之后也会被javac翻译成为“类名称.静态方法名”
        MyClass.methodStatic(); // 正确,推荐
        System.out.println(obj.numStatic);// 正确,不推荐
        System.out.println(MyClass.numStatic);// 正确,推荐
(2)静态只能访问静态,不能访问非静态
           静态的方法
               访问非静态的成员变量          不可以
               访问静态的成员变量            可以
               访问非静态的成员方法          不可以
               访问静态的成员方法            可以
    非静态可以访问静态,也可以访问非静态
           非静态的方法
               访问非静态的成员变量          可以
               访问静态的成员变量            可以
               访问非静态的成员方法          可以
               访问静态的成员方法            可以
   因为静态在内存中先出现的,非静态的东西是后出现的,先出现的不能使用后出现的

静态代码块
格式:
        static {
            // 代码
        }
位置:类中方法外
特点:
   (1)静态代码块在程序的运行过程中只会执行一次
       静态代码块随着类的加载而执行,由于类的加载只会加载一次,所以静态代码块也只会执行一次
   (2)随着类的加载而执行,所以执行的时间比较早,比构造方法执行早
   (3)比main方法还早执行
运用场景:
     对数据进行提前准备的工作,比如:JDBC加载数据库驱动



final关键字
最终,不可以改变的意思,它可以修饰类、方法、成员变量和局部变量
final修饰类
    final修饰的类不能被继承
    注:没有子类,但是可以有父类,可以继承和重写父类的方法
    final修饰的类其中的方法都不能被重写
    面试题:
        请说出JDK提供的API中常见的final类。
        Math类、String类、Scanner类和System类
final修饰方法
    final修饰的方法不能被重写
    注:但是可以被继承
final修饰成员变量
    final修饰的成员变量不能被重新赋值,变成了常量
    final修饰的成员变量必须赋值,赋值两个时机:
        (1)直接手动赋值
            private final String name = "张三";
        (2)通过构造方法赋值
            // 没有手动赋值,就必须使用构造方法赋值
            private final String name;
            public Person() {
                 name = "关晓彤";
            }
final修饰局部变量
    final修饰的局部变量不能被重新赋值,变成了常量
    基本数据类型的局部变量,不能改变的是值
        // final修饰的基本数据类型的局部变量
        final int num = 10;
        // 错误,值不能改变
        // num = 20;
    引用数据类型的局部变量,不能改变的是地址值,但是其中存储的内容是可以改变的
        // final修饰的引用数据类型的局部变量
        final Student s = new Student("张三",20);
        // 错误,地址值不能改变
        // s = new Student("张三",21);
         System.out.println(s.getName() +","+s.getAge());// 张三,20
        // 正确,内容改变,但是地址值没有改变
        s.setAge(21);
        System.out.println(s.getName() +","+s.getAge());// 张三,21
总结:
    (1)final修饰的类不能被继承
    (2)final修饰的方法不能被重写
    (3)final修饰的变量(成员或者局部变量)不能重新赋值

权限修饰符
可以修饰类、成员变量、成员方法、构造方法等,限制它们的访问范围(本类、本包、本模块)
    4个:public > protected > default > private
                本类          本包             不同包子类            不同包其他类
public          √               √               √                   √
protected       √               √               √                   ×
default         √               √               ×                   ×
private         √               ×               ×                   ×
总结:
    private修饰的只能在本类中访问,出了类不能访问
    default修饰的只能在本包中访问,出了包不能访问
    protected在本包和不同包的子类中可以访问
    public修饰的在整个模块中访问,出了模块不能访问
修饰符
    权限修饰符:public protected 默认 private
    其他修饰
        静态修饰符:static
        最终修饰符:final
        抽象修饰符:abstract
    修饰类
        public 默认
        final abstract
    修饰成员变量
        public protected 默认 private
        static final
    修饰局部变量
        final
    修饰成员方法
        public protected 默认 private
        static final abstract
    修饰构造方法
        public protected 默认 private

二十三.内部类

一个类中的组成部分:
        成员变量(常量)
        成员方法
        构造方法
        代码块(静态代码块、构造代码块)
        成员内部类(内部接口、内部枚举)
	注:一个类只能直接编写以上的内容,否则编译报错
		在一个类的内部再定义一个类,内部定义的那个类就是内部类
分类:
    (1)成员内部类
    (2)局部内部类
    (3)匿名内部类(特殊的局部内部类)

成员内部类
位置:类中方法外
格式:
   修饰符 class 外部类类名{        // 外部类
        修饰符 class 内部类类名{    // 成员内部类
        }
    }
特点:
    内部类可以直接访问外部类的成员,即使是private修饰的
    外部类想访问内部类的成员,不能直接访问,必须借助内部类的对象
    不管是外部类还是内部类,都会生成.class文件,如果是成员内部类生成的文件名的格式:
    外部类名$内部类名.class
    Outer$Inner.class
使用:
    (1)间接使用
        在外部类的方法中创建内部类的对象,再通过对象调用内部类的方法
        在测试类中创建外部类的对象,再通过对象调用外部类的方法
    (2)直接使用
        在测试类中创建内部类的对象,再通过对象调用方法
内部类的对象创建的格式:
      外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
      Outer.Inner oi = new Outer().new Inner();
      Body.Heart bh = new Body().new Heart();
内部类的成员变量和外部类的成员变量同名,在内部类中访问外部类的同名成员变量:
    外部类名.this.成员变量
成员内部类的修饰符:
    我们目前学习到的7种修饰符都可以使用
    public protected 默认 private
    static final abstract

局部内部类
位置:
	方法中
特点:
    只能在其所定义的方法内部使用,而且必须先定义再使用
    出了所定义的方法内部是不能使用的,即使在本类的其他方法中都不能使用
使用:
    在其所定义的方法内部创建局部内部类的对象,然后再通过对象调用方法
编译之后的.class文件格式:
    外部类名$编号内部类名.class
    Outer$1Inner.class
局部内部类访问所在方法的局部变量时,局部变量必须使用final修饰
从JDK1.8开始,如果保证局部变量事实不改变(没有对其进行重新赋值),final关键字可以省略

匿名内部类(掌握)
本质:
    是一个局部内部类,只不过它没有名字
应用场景:
    当一个接口的实现类(父类的子类)只使用一次的情况下,为了简化操作
匿名对象:解决对象只使用一次的情况,是为了代码简化,不需要再使用变量接收
匿名内部类:解决类只使用一次的情况,是为了简化操作,不需要再创建类
格式:
    接口名或者父类名 对象名 = new 接口名或者父类名(){
            // 方法重写
    };
    new 接口名或者父类名(){
            // 方法重写
    }.重写的方法;
    (1)由于匿名内部类没有名字,所以使用的时候只能直接创建其对象
    (2)new 接口名或者父类名(),不是在创建接口的对象,也不是在创建父类的对象,
        而是创建接口的实现类对象,或者父类的子类对象
    (3)要使用匿名内部类必须有一个接口,或者有一个父类(普通类或者抽象类)
如果一个类作为方法的形式参数,调用方法传递的实参是该类的对象或者该类的子类对象
如果一个抽象类作为方法的形式参数,调用方法传递的实参只能是该类的子类对象
如果一个接口作为方法的形式参数,调用方法传递的实参只能是该接口的实现类对象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值