1.常见基础的DOS命令
Window+R 弹窗输入cmd
2.Java语言特性
简单性 安全性 面向对象 高性能 编译性 解释性 分布式管理 健壮性 开源 跨平台
什么是跨平台性?
1.通过Java语言编写的应用程序在不同的系统平台上都可以运行,那原理是什么?
2.我们所写的JAVA程序是".java"为后缀的源文件,但这些文件计算机无法直接执行,需要先进行编译环节,通过编译变为以".class"为后缀的字节码文件,这个字节码文件交由JVM(JAVA虚拟机)来运行.
3.那我们只要在需要运行java应用程序的OS(操作系统)上,安装一个JVM,由JVM来负责Java程序在该系统中的运行即可。不同的OS(操作系统)都有与之对应的JVM,所以只需要写一个Java程序,就可以在多个不同的操作系统上执行。这样就实现了Java程序的跨平台性。也称为Java具有良好的可移植性。
跨平台拓展知识
3.Java标识符
1.由字母 数字 下划线 美元符号 组成
2.不能以数字开头
3.严格区分大小写
4.见名知意,并且不要使用拼音或者中英文夹杂的方式
5.标识符不可以使用Java的关键字
4.Java关键字
1.被Java提前指定好的全小写单词,一共有50个
2.有2个保留字:const和goto,目前还没有明确意义的关键字
3.3个不可以作为标识符的单词:true false null
5.常用注释
1.注释不会影响程序的执行,或被编译器自动忽略
2.单行注释: // 可以注释一行的内容
3.多行注释: /**/ 可以注释多行内容
4.文档注释: / ** */ 也可以注释多行内容,还可以添加一些额外的信息,比如:作者/时间/版本…
6. 数据类型
基本类型
引用类型
常用的引用类型是String字符串类型,这个类型的数据需要使用双引号包裹
7.总结经验
1.静态数据想要与动态的变量名进行拼接,之间需要用"+"来连接
2.char字符型既可以保存单个字符(字符需要用单引号包裹),也可以保存数字(数字需要去查询ASCII码表)
3.从控制台接受用户输入的数据 代码为:int a=new Scanner(System.in).nextInt();
4.变量进行值交换,首先需要一个第三方变量协助交换(用三个杯子交换水的例子),代码格式为:斜相对,首尾相连
8.定义变量
1.定义的时候并且赋值:变量的类型 变量名 = 变量值,比如:int a=1;
2.先定义变量,后面在赋值: int a; a =1;
3.注意:这里的=是赋值符号,=右边的值交给=左边的变量来保存
9.类型转换
1.boolean类型不参与类型的转换
2.小转大,直接转–隐式转换
3.大转小,强制转–显式转换,int a=(byte) b;
4.浮变整,小数没–浮点型转换直接舍弃后面的小数部分,不会四舍五入(类型能否转换取决于类型的取值范围)
10.字面值规则
1.整数类型默认为int类型
2.小数类型默认为double类型
3.byte short char 三种比int小的类型,可以使用范围内的值直接赋值
4.字面值后缀: L F D
5.字面值前缀: 0b-2 0-8 0x-16
11.运算规则
1.运算结果的数据类型与最大类型保持一致
2.3种比int小的类型,运算时会自动提升成int再运算
3.整数运算溢出的问题,一旦溢出,数据就错误了
4.浮点数运算不精确
5.浮点数的特殊值 Infinity NaN
12.运算符
1.普通运算+ - * /
是不会改变变量本身的值,如果想改变变量本身的值,需要把表达式的结果重新赋值给变量
2.取余%(求模 mod)
取余数,如果整除的话,余数为零
3.自增自减运算符
自增++:表示变量本身的值+1
自减-- :表示变量本身的值-1
前缀式:符号在前:先改变变量的值再使用
后缀式:符号在后:先使 用,再改变变量本身的值
4.比较运算符
!= == > < <= >= 比较结果都是布尔类型(true/false)
5.逻辑运算符
&&:双与:逻辑与单与相同,全真才为真
|| :双或:逻辑与单或相同,全假才为假
(注意:双与.双或相比较于单与.单或多了短路的效果,就是左边出现结果就不会再执行右边)
6.三目运算符
格式 1 ? 2 : 3; 1号位是表达式,若1成立取2号位值,反则取三号位值
7.赋值运算符
= :是普通的赋值运算符,等号右边的值交给等号左边的变量来保存
复合赋值运算符:+= -= *= /=,主要是可以简写&类型的自动转换
sum += 30; 等效于 sum = sum+30;
13.分支结构
1.单分支结构
适合只有一个判断条件时使用,符合条件,执行大括号里的代码,不符合条件,大括号的代码跳过
2.多分支结构
适合有两种情况时使用,符合条件,执行代码1,其他情况执行代码2
3.嵌套分支结构
适合有多个条件时使用,else-if的个数没有限制,else可加可不加
4.选择结构
执行顺序:先拿着变量a的值,依次与每个case后面的值进行比较,若相等就执行后面的操作,如果case后面没有break,就继续执行下一个case后的操作,如果一直没有遇到break,就会发生穿透现象,包括default
注意事项:
1.这里变量a支持的类型是byte,short,int,char,String
2.变量a的数据类型与case后的value的数据类型必须一致
3.如果没有添加break,且有case被匹配到,那么就会发生穿透现象,包括defaul
4.case的个数 是否加break 是否加default 完全根据自己的业务来决定
5.如果添加了default保底选项,又没有任何一个case被匹配到,就会执行default后的语句
6.case后面的break根据自己的需要添加
5.循环结构
14.for循环
1.循环的开始条件只会在第一轮开始时执行一次,后续不再执行
2.循环结构适合我们在程序中需要反复执行某一件事时使用
3.循环执行几次,取决于变量能够取到几个值,而不是循环变量的取值范围
例:
15.嵌套for循环
1.外层循环控制的是执行的轮数,内层循环控制的是这一轮中执行的次数
2.外层循环控制的是图形的行数,内层循环控制的是这一行的列数
例:(矩形)
例:(直角三角形)
如果把内层循环的循环变量j,设置成随着外层循环循环变量i的变化而变化,打印出来的是直角三角形
16.while循环
先判断,再执行,注意while循环设置死循环后必须设置出口
17.do-while循环
先执行,再判断,本循环最少执行一次
18.几种循环的区别
1.for:知道循环的次数
2.while/do while:当循环次数不确定时
3.while:先判断再执行,不符合不执行代码
4.do-while:先执行再判断,代码最少先被执行一次
循环之间都可以互相替代,但是一般最好选择合适的循环结构来完成代码
19.成员变量和局部变量
成员变量:
1)位置:类里方法外
2)注意事项:成员变量有自己的对应类型的默认值,不需要我们手动初始化/赋值
3)生效范围:在整个类中都生效,类消失,成员变量才会随之释放
局部变量:
1)位置:在方法里 / 局部代码块里
2)注意事项:使用时必须赋值/初始化
3)生效范围:在方法里/局部代码块中,对应的代码执行完毕,局部变量也随之释放
20.方法
1.方法定义的格式:修饰符 返回值类型 方法名(参数列表){方法体}
2.一个方法会不会执行,取决于有没有调用这个方法,调用的格式:方法名+参数列表
3.方法定义的位置没有关系,执行顺序取决于main()怎么调用
4.一个方法可以不设置参数,也可以设置多个参数,如果有参数,使用方法时,必须传对应类型的参数
5.如果方法的返回值类型是void,则不允许有返回值
6.如果方法要返回一个值,必须设置返回值类型,并且return对应类型的结果
7.在调用有返回值的方法时,可以选择接不接这个方法返回的值
如果接了,后续可以多次使用这个返回值
如果不接,那就是只是调用该方法的功能,并不使用这个返回值
21.数组
1.静态创建
int [ ] a={1,2,3,4,5};
int [ ] a=new int[ ]{1,2,3,4,5};
2.动态创建
int [ ] a=new int [5] ;
3.数组创建的过程
1.在内存中开辟连续的空间,用来存放数据
2.给数组完成初始化过程,给每个元素赋予默认值
3.数组完成初始化会分配一个唯一的地址值
4.把唯一的地址值交给引用类型的变量a去保存
5.如果想要操作数组中的元素,可以根据变量保存的地址找到数组,然后根据下标来操作数组的具体元素
数组名保存的是数组的地址值,不是数组中每一个具体的元素,数组名是一个引用类型的变量
4.数组的特性
1.数组的长度通过 数组名.length; 来获取
2.数组一旦创建,长度无法改变
3.数组的下标从0开始,最大下标为数组长度-1
4.如果访问到了不存在的下标,会出现数组下标越界的异常
5.数组的工具类Arrays
1.Arrays.toString(数组名),除了char类型以外,其他类型的数组想要查看数组的具体元素,都得使用这个方法,如果不用.打印的是数组的地址值
2.Arrays.sort(数组名),给数组进行排序
3.Arrays.copyOf(要复制的数组,新数组的长度)
如果新数组的长度大于原数组的长度–数组的扩容
如果新数组的长度小于原数组的长度–数组的缩容
如果新数组的长度等于原数组的长度–数组的复制
注意:不管是什么长度,都不是修改原数组,而是创建的新数组
6.数组的遍历
1.如果只是想查看数组中有哪些元素,直接使用System.out.println(Arrays.toString(数组名));就可以
2.如果想要拿到数组中的一个个的具体元素,或者是对数组中的元素做进一步的操作,就需要对数组进行遍历
3.遍历:把数组中的所有元素,从头到尾逐个“过一遍”
4.通过循环遍历数组,所以循环中的**循环变量代表的是数组的下标
22.面向过程
编程思想强调的是过程,凡事亲力亲为
23.面向对象
这种思想强调的是结果,Java就是一门面向对象的语言
不在意是怎么完成的,在意的是有对象可以帮我完成
24.类
类指的是类型Type,是指一类事物,使用Java中的class关键字来描述
类是抽象的,要提取这一类事务的特征与功能
注意:类在现实世界中不是真实存在的,它只是一种对象的数据类型
25.对象
对象就是根据类创建出来的一个个独立且具体的实例
一个类可以创建出多个对象,我们通过对象唯一的地址值区分不同的对象
对象具有各种特征,并且每个对象的每个特征都可以有自己特定的值
对象具有各种行为,每个对象可以执行的操作
26.对象创建过程分析
Phone p = new Phone();创建对象时,内存发生了什么?
1.在栈内存中开辟一块空间,Phone类型的引用类型变量p,把p压入栈底,此时p只有一个默认值null
2.在堆内存中开辟一块空间用于存放Phone类型的对象
3.要给这个对象进行初始化,比如:String brand=null;
4.此对象已经准备好,所以会生成一个唯一的地址值,并将这个地址值交给栈内存中的变量p来保存
5.如果后续想要对对象做操作,比如:p.price=88.8;先会找到栈中p变量保存的地址值,根据这个地址找到堆中的对象再做进一步的操作
27.面向对象的特征–封装(私有化)
1.为什么要进行封装
1.封装可以提高程序的安全性
2.封装可以让资源按照我们预先规定的方式来操作
2.属性的封装
用private修饰属性,一旦属性被private修饰,就只能在本类中使用这个属性,外界无法访问
所以为了让外界能够按照我们提供的方式来调用,需要根据属性生成公共的getXxx()与setXxx()方法
3.方法的封装
方法的封装也是使用private来修饰方法
如果想要调用私有方法的功能,就需要在本类的公共方法里调用这个私有方法
28.构造函数
格式:与本类类名同名,而且没有返回值类型
作用:创建对象一次,就执行一次构造函数
分类:
无参构造:默认存在的,如果添加了其他构造,默认的构造函数会被覆盖
含参构造:对于参数没有要求,有参数就行
全参构造:全参构造的参数必须与本类属性一直
全参构造不仅可以创建对象,还可以给对象的所有属性赋值
29.方法的重载
1.在同一个类中,存在多个方法名相同,但参数列表不同的方法
2.如果在同类中,多个同名方法的参数个数不同,一定构成重载
3.如果在同类中,多个同名方法的参数个数相同:需要查看对应位置上的参数的类型,而不是参数名,与参数名无关
4.如:(int a ,String b)与(int b,String a)----不构成重载
(int a,String b)与(String a,int b)----构成–构成重载
30.构造代码块
位置:类里方法外
执行时机:每次创建对象时执行,优先于构造方法执行
作用:用于提取所有构造方法的共性功能
31.局部代码块
位置:类里方法里
执行时机:调用本局部代码块所处的方法时执行
作用:用于控制变量的作用范围
执行顺序:构造代码块–构造方法–普通方法–局部代码块
32.this的用法:
1.当成员变量与局部变量同名时,使用this指定成员变量
2.使用this在构造方法的第一行调用构造方法的功能
this(); 调用的是本类的无参构造
this(参数); 调用的是本类对应参数的构造方法
33.super的用法:
1.当父类的成员变量和子类的成员变量同名时,使用super指定父类的成员变量
2.使用super在子类构造方法的第一行调用父类构造方法的功能
super(); 调用的是父类的无参构造
super(参数); 调用的是父类对应参数的构造方法
34.继承
1.继承的关键字----extends,格式:子类 extends 父类
2.继承相当于子类把父类的功能复制了一份,包括父类的私有资源
3.Java只支持单继承:一个子类只有一个父类,一个父类可以有多个子类
4.继承具有传递性
5.子类只可以使用父类的非私有资源,私有资源不可用的原因是不可见
6.子类可以拥有自己的特有功能
7.继承是is a 强耦合的关系,依赖性非常强,比如我们看到”熊孩子”,就知道他有一个”熊父母"
35.继承中变量的使用
父类成员变量和子类成员变量同名时,使用super.变量名来指定父类的成员变量
36.继承中构造方法的使用
1.创建子类对象时,会先调用父类的无参构造,因为子类的构造函数中默认存在一个super();
2.如果父类没有无参构造的话,我们就需要手动去指定子类调用父类的含参构造super(参数);
3.构造方法不可以被继承,原因是:构造方法名必须是本类的类名,不可能在子类中存在一个父类名字的构造方法
37.方法的重写
1.什么是重写:
子类对父类的方法不满意时,可以重写父类的方法
注意:重写是在不改变父类方法的前提下,实现功能的修改,重写后子类对象调用的就是重写后的功能
2.重写的原则 (两同两小一大)
两同:方法名相同,参数列表相同
一大:子类方法的修饰符权限>=父类方法的修饰符权限
两小:子类方法的返回值类型,有两种选择:
1)子类方法的返回值类型与父类方法的返回值类型相同
2)子类方法的返回值类型是父类方法的返回值类型的子类
比如:父:void 子:void
父:int 子:int 但是:byte short long都不行!没有继承关系
父:Animal 子:Animal/Cat都可以,但不可以是Car
注意:我们还可以给方法上加@Override注解,标记这是一个重写的方法
38.静态
1.static可以修饰成员变量和方法
2.被static修饰过的资源被称为静态资源
3.静态资源随着类的加载而加载,最先加载,优先于对象加载
4.静态资源可以通过类名直接调用,也称之为类资源
5.静态资源被全局对象共享,值只有一份
6.静态资源只能调用静态资源
7.静态区域内不允许使用this与super关键字,因为this代表本类对象,super代表父类对象,有静态时还没有对象呢
39.静态代码块static{}
1.格式:static{ }
2.位置:类里方法外
3.执行时机:随着类的加载而加载,优先于对象进行加载【只加载一次】
4.作用:用于加载那些需要第一时间就加载,并且只加载一次的资源,常用来初始化
5.顺序:静态代码块 构造代码块 构造方法 普通方法【如果普通方法里有局部代码块,执行局部代码块】
…TIPS: 如果有多个静态资源,加载顺序取决于先后位置
…TIPS: 静态不可以与this和super共用
40.final关键字
1.用final修饰的类是最终类,不可以被继承
2.用final修饰的方法是方法的最终实现,不可以被重写
3.修饰常量:值不可以被更改,且常量定义时必须赋值
注意:常量的定义需要使用全大写,单词之间需要使用下划线分隔
41.面向对象之多态
1.前提:继承+重写
2.口诀一:父类引用指向子类对象
解释:父类类型的引用类型变量保存的是子类类型的对象的地址值
3.口诀二:编译看左边,运行看右边
解释:编译时要看父类是否定义了这个资源,运行时使用的是子类的功能
4.资源使用情况
1)成员变量使用的是父类的
2)成员方法使用的是父类的方法定义,子类的方法体
3)如果多态对象调用的是子类没有重写过的方法,方法定义与方法体使用的都是父类的,所以这个不符合多态的前提,直接使用纯纯的父类对象调用即可
4)静态资源属于类资源,随着类的加载而加载,只会加载一次,优先于对象进行加载,可以通过类名直接调用,被全局所有对象共享,所以静态不存在重写的现象,在哪个类定义,就属于哪个类的资源
5)我们现在学习的多态,把自己看作是父类类型,参考“花木兰替父从军”
42.异常
1.异常的继承结构
异常层次结构中的根是Throwable
Error:目前我们代码解决不了的问题
Exception:异常
编译异常:未运行代码就报错了,强制要求处理
运行时异常:运行代码才报错,可以通过编译,不强制要求处理
2.异常的解决方法
1.捕获处理try-catch------自己解决
异常捕获处理的格式:
1)try-catch结构可以嵌套:如果有多种异常类型需要特殊处理的话
2)使用多态的思想,不论是什么子异常,统一看作父类型Exception
做出更加通用的解决方案,甚至可以只写这一个
2.向上抛出throws------交给别人解决
异常抛出的格式:
在方法的小括号与大括号之间,写:throws异常类型
如果有多个异常,使用逗号分隔即可
1)如果一个方法抛出了异常,那么谁来调用这个方法,谁就需要处理这个异常,这里的处理也有两种方案:捕获解决 或者 继续向上抛出
2)不能直接把异常抛给main(),因为调用main()是JVM,没人解决了,该报错还报错,所以我们一般会在main()调用之前将异常解决掉
43.抽象
1.抽象类
1.被abstract修饰的方法是抽象方法,抽象方法没有方法体
2.一旦一个类中有抽象方法,这个类必须被声明为抽象类
3.如果一个子类继承了一个抽象父类,有两种解决方案:
1)抽象子类:不实现/实现一部分抽象父类中的抽象方法
2)普通子类:实现抽象父类中全部的抽象方法
4.抽象类不能够实例化(不能创建对象)
5.抽象类有构造方法的,但不是为了自己使用,是为了子类super()调用
6.抽象类可以定义成员变量/成员常量
7.抽象类中可以定义全普/全抽/半普半抽
8.如果一个类不想被实例化,可以把这个类声明成抽象类
2.抽象方法
1.被关键字abstract修饰的方法是抽象方法
2.抽象方法没有方法体{},直接以分号结束
3.案例一
4.案例二
44.接口的特点
1.我们使用interface关键字来定义接口
2.我们使用implements关键字建立接口实现类和接口的实现关系,接口是父级,接口实现类是子级
3.接口实现类如果实现部分/不实现接口中的抽象方法,那么实现类是一个抽象类
接口实现类如果实现了接口所有的抽象方法,那么这个实现类是一个普通类
4.抽象类与接口都不可以实例化/创建对象
5.接口没有构造函数,实现类使用的super()是父类的无参构造
如果没有明确指定父类,super()代表的才是Object的无参构造
6.接口中都是静态常量,没有成员变量,因为会默认拼接public static final
7.接口中都是抽象方法,默认会拼接public abstract
故此:静态常量与抽象方法默认拼接的部分,可以省略不写
8.接口不是类!!!
9.接口是用来制定规则的【有哪些功能?方法有参数吗?有返回值吗?】
方法具体的实现交给接口的实现类去完成
45.接口与类的复杂关系
1.类与类的关系
继承关系,只支持单继承
比如,A是子类,B是父类,A具备B的所有功能(除了父类的私有资源和构造方法)
子类如果要修改父类的原有功能,需要重写(两同两小一大)
2.类与接口的关系
实现关系,可以单实现也可以多实现
class A implements B,C{}
其中A是实现类,B和C是接口,A拥有BC接口的所有功能,只是需要进行方法的重写,否则A就是抽象类
3.接口与接口的关系
是继承关系,可以单继承,也可以多继承
interface A extends B,C{}
其中ABC都是接口,A是子接口,具有BC接口的所有功能(抽象方法)
class X implements A{}
X实现类需要重写ABC接口的所有方法,否则就是抽象类
class A extends B implements C,D{}
其中A是实现类,也是B的子类,同时拥有CD接口的所有功能
这时A需要重写CD接口里的所有抽象方法
4.接口与抽象类的区别
1.接口是一种用interface定义的类型
抽象类是一种用class定义的类型
2.接口中的方法都是抽象方法,还有默认方法与静态方法
抽象类中的方法不做限制
3.接口中的都是静态常量
抽象类中可以写普通的成员变量
4.接口没有构造方法,不可实例化
抽象类有构造方法,但是也不可以实例化
5.接口是先天设计的结果,抽象是后天重构的结果
6.接口可以多继承
抽象类只可以单继承
46.内部类的总结
1.内部类创建对象的格式:
外部类名.内部类名 对象名 = 外部类对象.内部类对象
2.根据内部类的位置不同,分为:
成员内部类(类里方法外)
局部内部类(方法里)
3.内部类可以直接使用外部类的资源,外部类使用内部类资源时,
需要先创建内部类的对象,通过内部类对象来调用
4.成员内部类被private修饰后,需要在外部类创建公共方法,间接访问内部类的资源
5.静态内部类不需要先创建外部类对象,
而是要先通过外部类的类名找到内部类,再创建内部类的对象
6.如果静态内部类有静态资源,可以不创建一个对象,就通过
外部类名.内部类名.静态资源名 的链式加载的方式,使用资源
7.直接创建外部类对象,调用局部内部类所处的方法时,并不会触发内部类的功能
需要在内部类所处的方法中,创建内部类对象,并调用其功能,功能才会被触发
8.匿名内部类没有名字,通常与匿名对象结合在一起使用
9.如果想要多次使用实现后的功能,还是要创建之前的普通对象
匿名对象只能使用一次,一次只能调用一个功能
匿名内部类其实就是充当了实现类的功能,去实现未实现的方法,只是没有名字而已