面向对象概述
面向对象思想:将数据作为第一位,将功能通过对象来实现。
面向对象三大基本特征:封装,继承,多态
封装:封装是把数据成员和方法都放进一个类中,在用访问权限控制器可见性,从而隐藏了类的内部实现机制,在不影响使用者的前提下改变类的内部结构,起到了保护数据的作用。
继承:提高代码的利用率,为实现多态做准备
多态:指同一行为具有多种不同的表现形式。多态的语法特征是在类的继承层次结构上体现的,基于方法调用的动态绑定技术,当多个子类都重写了同一个基类的方法时,将子类对象的引用转化为基类类型,再通过基类引用动态调用某个子类中对应的方法的方式即为多态调用。通过过使用多态语法,可以在代码中仅仅通过基类引用就可以动态调用子类中实现的功能,使代码有良好的可扩展性。
面向对象和面向过程的区别:
面向过程是分析出解决问题所需要的步骤,然后用函数一步一步实现,使用的时候依次调用即可。面向对象是把构成问题的事物分解成一个一个的对象,建立对象的目的是为了描述某个事物在整个解决步骤中的行为。
java语言的跨平台性:
指java语言编写出的程序,一次编译可以在多个系统平台上运行。
原理是java程序是通过java虚拟机在系统平台上运行的,只要该系统可以安装相应的java虚拟机,该系统就可以运行java程序。java源文件编译出java字节码,在不同系统的JVM上通过解释器加载出相应的机器码,即为一次编译,处处运行。
类、对象
对象的状态和行为是对象的主要属性;
前者对应类的 变量 ,行为又称为对象的操作,对应着类的 方法 。类的定义包括 变量 声明和 方法 声明。
基本类型
整型:
int:4字节 32位
short:2字节 16位
long:8字节 32 位
byte:1字节 8位
java中的整型大小和机器平台都无关,故能在各种平台上进行移植。
java中不存在任何无符号形式的整型
浮点型:
float:4字节 有效位数7位
double:8字节 有效位数16位
浮点数添加后缀f表示float类型,添加d或者不添加任何后缀表示double类型
字符类型:
char类型的字面量值要用单引号括起来。双引号括起来代表字符串。转义序列是char类型的,所有的转义序列都可以出现在加引号的字符字面量或字符串中
布尔类型:
boolean类型有两个值:false和true,用来判定逻辑条件,整形和布尔值不能相互转化。
关键字
final,意为最终的,不可更改的
类:被final修饰的类是最终类,意思是不能有子类,不能被继承
方法:最终方法,子类可以继承使用,但不能修改
变量:是常量,一旦赋值不可被修改,且必须在初始化对象的时候赋值
final修饰的成员变量必须在声明时初始化或在构造器中初始化,final修饰的局部变量必须在声明时赋值,否则将呈现编译错误
final类不可以被继承
final关键字大多修饰基本数据类型(实际变量值不变),如果修饰引用数据类型决定的是变量不再指向另一个对象(引用地址不变),对象的内容是可以更改的;
super
是一个引用变量,用于直接引用父类对象,每当创建子类时,父类的实例被隐式创建,由super关键字引用变量引用。由于子类不能继承父类的构造方法,因此要调用父类的构造方法,必须在子类的构造方法体的第一行使用super()方法,该方法会调用父类的构造方法来完成子类对象的初始化。
用法:
调用父类的构造方法
访问父类的实例变量
访问父类的方法
指的是对象,不能在static环境中使用。
this
代表当前对象的引用,即调用类中方法或属性的那个对象。
this在当前类中使用时,代表的是当前类。
只能在方法内部使用
不能用于静态方法,也不能用于main方法
static
修饰类的成员方法,类的成员变量,从属于类,普通变量和成员从属于方法
静态内容在程序中保留一份,各个对象之间共享,推荐使用类名去访问静态内容
且是优先于对象产生的
用static修饰的成员变量为静态成员变量,被所有对象共享
static修饰的方法称为静态方法,不能访问非静态方法和非静态成员变量,但是非静态成员变量可以访问静态成员方法和静态成员变量。
static不能修饰局部变量。
运算符
算数运算符
赋值运算符
别名现象:
假设有一个类,它有两个实例(c1 和 c2),原本c1和c2分别指向两个不同的对象。如果执行c1=c2, 则c1这个引用就会被覆盖,也就是丢失了;而那个不再被引用的对象会由“垃圾回收器”自动清理。这种特殊的现象通常称作“别名现象”,修改一个引用内容后,所有引用都发生了改变。
比较运算符
逻辑运算符
==和!=比较的是对象的引用,故相同值对应的结果是false。基类中object中的equals方法比较的是对象的引用,所以需要对equals方法进行重写来比较内容。
条件运算符
类型转换
类型从小到大:byte short int long float double
自动转换:从小类型转化为大类型,不需要强制转换符
强制转换:从大类型到小类型,需要强制转换符实现强制转换:(需要转换成的类型)变量
关于byte,short,char 复制与运算的强转规则:
1.不参与运算时,整数直接量可以直接赋值给byte,short,char,不需要强转
2.byteshortchar参与运算时需要强转
强转会产生精度丢失
控制流程
break:跳出当前循环
continue:跳会循环开头执行下一次循环
标签:只能写在循环体之前
带标签的break和continue跳到标签处执行
构造器
也叫构造方法,构造函数,格式如下:
[修饰符,比如public] 类名 (参数列表,可以没有参数){ //这里不能有return}
一个类可以定义多个构造器,java会在没有构造器的时候提供一个默认构造器。
作用:实例化对象,给对象赋初值
代码游离块优先运行
构造器的继承
子类构造器默认调用父类无参构造器,若弗雷没有无参构造器,必须在子类构造器中第一行用super关键字指定
执行顺序
无继承情况下:
静态代码块;程序启动后执行一次
构造代码块:构造器被调用的时候执行
构造器
有继承情况下:
父类静态代码块 子类静态代码块 父类构造代码块 父类构造器 子类构造代码块 子类构造器
垃圾回收
释放垃圾占用的空间,防止内存泄漏
初始化
为变量分配内存空间,并确定其初始值的过程。
可以初始化:构造器,static语句块,类的变量(局部变量,静态变量,普通变量)
初始化顺序:
static变量和构造函数先执行,普通变量优先于构造方法执行。
有父类就先执行父类
父类普通变量执行完毕后执行父类构造块
单例模式:确保每个类只有一个实例,且自行实例化并向整个系统提供这个实力。
主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。 使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收
方法重载
同一个类中包含两个及两个以上的方法名相同,方法参数的个数、顺序或者类型不同的方法,则称为方法的重载。与返回值类型无关,只看参数列表。
和重写的区别:
重写:子类中根据需要对从父类中继承的方法进行改造,执行时子类的方法覆盖父类的方法。
需要具有相同的方法名称和参数列表,子类返回值类型不能大于父类返回值类型
必须同时声明非static,表现为多态性,且重写涉及动态绑定。
package
包允许将类组合成较小的单元(类似文件夹),它基本上隐藏了类,并避免了名称上的冲突。包允许在更广泛的范围内保护类、数据和方法。你可以在包内定义类,而在包外的代码不能访问该类。这使你的类相互之间有隐私,但不被其他世界所知。
包的作用:
1.区分相同名称的类
2.较好的管理较大的类
3.控制访问范围
命名方式:
编译器会强迫将.class文件所在的路径位置编写成package名称,习惯上会以class开发者的域名相反顺序作为package名称的第一部分,能保证包名不会冲突
编译器如何根据import语句找出.class文件:
将package名称分解为机器上的磁盘目录名称,先找出环境变量classpath,classpath含有一个或多个目录,每个目录视为.class查找起点,java从这个起点开始,将package名称中的每个句号替换为斜线,以获得在classpath下的路径名称,路径接续于classpath的项目之下,这些路径名称就是java解释器查找.class文件的地点
.java文件
.java文件是 保存源代码的文本文件
.class文件是通过编译后得到的二进制字节码文件
Java类文件是Java程序的二进制表示形式。每一个类文件代表一个类或者接口。不可能在一个类文件中放入多个类或者接口。这样就使得无论类文件是在哪一种平台上生成,都可以在任何主机上执行。
虽然类文件是Java体系结构的一部分,但是他并不是与Java语言不可分的。
类库
常用类库
math
objects:equals(),isNull(),toString()重写该方法可以打印时输入类对象名打印出类中的属性
arrays:arr()
访问权限
private:被其修饰的属性以及方法只能被该类的对象访问,其子类不能访问,更不能允许跨包访问。
default:即不加任何访问修饰符,通常称为“默认访问权限“或者“包访问权限”。该模式下,只允许在同一个包中进行访问。
public:被其修饰的类、属性以及方法不仅可以跨类访问,而且允许跨包访问。
protected:被其修饰的属性以及方法只能被类本身的方法及子类访问,即使子类在不同的包中也可以访问。
封装
将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供的方法来对隐藏的信息进行操作和访问。
getter/setter
public String getName()
{ return name; }
public void setName(String name)
{ this.name = name; }
继承
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
通过继承可以快速创建新的类,实现代码的重用,提高程序的可维护性,节省大量创建新类的时间,提高开发效率和开发质量。
关键字:extends
- 子类不能选择性继承父类;
- Java不支持多重继承,但一个类可以实现多个接口,从而克服单继承的缺点;
- 构造方法不会被子类继承,但可以从子类中调用父类的构造方法。
多态
指同一个实体同时具有多种形式,即同一个对象,在不同时刻,代表的对象不一样,指的是对象的多种形态。
- 多态的前提1:是继承
- 多态的前提2:要有方法的重写
- 父类引用指向子类对象,如:Animal a = new Cat();
- 多态中,编译看左边,运行看右边
前提:多态对象把自己看做是父类类型
- 成员变量: 使用的是父类的
- 成员方法: 由于存在重写现象,所以使用的是子类的
- 静态成员: 随着类的加载而加载,谁调用就返回谁的
抽象类和抽象方法
抽象类:
包含抽象方法的类就是抽象类
,反之不一定成立。通过 abstract 方法定义规范,然后要求子类必须定义具体实现。通过抽象类,我们就可以做到严格限制子类的设计,使子类之间更加通用。
抽象类不能实例化,即不能用 new 来实例化抽象类
。
抽象类可以包含属性、方法、构造方法。但是构造方法不能用来 new 实例, 只能用来被子类调用。
抽象类只能用来被继承。
抽象方法必须被子类实现。
抽象方法:
使用 abstract 修饰
的方法,没有方法体,只有声明
。定义的是一种“规范”,就是告诉子类必须要给抽象方法提供具体的实现
。
接口
关键字:interface
访问修饰符:只能是 public 或默认。
接口名:和类名采用相同命名机制。
extends:接口可以多继承。
常量:接口中的属性只能是常量,总是:public static final 修饰。不写也是。
方法:接口中的方法只能是:public abstract。 省略的话,也是 public abstract。
子类通过 implements 来实现接口中的规范。
接口不能创建实例,但是可用于声明引用变量类型。
一个类实现了接口,必须实现接口中所有的方法,并且这些方法只能是 public 的。
JDK1.8(不含 8)之前,接口中只能包含静态常量、抽象方法,不能有普通属性、构造方法、普通方法。
JDK1.8(含 8)后,接口中包含普通的静态方法、默认方法。
内部类
静态内部类
创建对象的语法:
new 外部类名.内部类名 ()
内部类可以间接访问外部类静态私有特征
外部类也可以间接访问内部类的静态私有特征,需要创建内部类对象
普通内部类
1.不能拥有静态代码块,静态方法,静态变量,静态内部类
2.先创建外部类对象由外部类对象创建内部类对象
new外部类().new 内部类();
3.内部类对象间接共享外部类对象特性
4.外部类若存在子类,子类的特性对内部类隐藏,内部类不能访问到子类中的方法
匿名内部类:
默认static修饰的没有名称的内部类,前提是必须是类或者接口
在调用包含有接口类型的参数的时候,为了简化代码,直接通过匿名内部类的形式传入一个接口类型的参数,在匿名内部类中直接完成方法的实现。
格式:
new 类名/接口名(){重写抽象方法}相当于子类对象,一个实现类
容器类
容器概述:能装对象的对象
1.list 线性结构,可变长度(是一个接口,有两个实现类)
ArrayList 内存连续
语法:
list.add添加数据,
list.remove移除数据,
list.size()列表的大小,装了多少元素,
list.get(i)查询第i个元素,list内的元素被向上转型成object类型
object obj=list.get(1);
string s=(string) obj;使用强制转换
contains()判断容器中是否有xxx东西,返回boolean
遍历列表
for(int i=0;i<arr.length;i++){
sout(arr[i]);
}
LinkedList 内存可以不连续,有后继指针
但是对于程序员使用时一样的
列表可以存放重复数据,按照存储顺序进行存储的
2.set集合,非线性,去除重复
重复数据无法添加
hashset
无序,乱的,不重复
treeset
不重复,默认进行排序
set的操作:
add()添加元素
没有get 无序的
remove()删除
size()set种元素的个数
contains()是否包含,数字在set中是integer(基本数据类型)
3.map映射 存储的时候 以key::value形式存储数据,名字::电话
拿着key去存value key->value
hashmap
treemap 可以排序 根据key来排序
语法:
map.put(key,value);存放数据
remove(key)删除数据
size() 存储键值对数量
containskey()判断是否包含
containsvalue()
出现重复key,原来的value会被顶掉
keyset()map中所有的key打包成set集合返回
get(key)查找数据
java中所有集合的根:collection接口,衍生出所有集合
迭代器Iterator:
set集合不能遍历,只能通过迭代器遍历
一个一个往外拿
iterator it=list.iterator();
string s0=(string) it.next();//打印第一个,之后重复代码
sout(s0);
循环遍历:
while(it.hasnext()){
string s=(string) it.next();
sout(s);
}
语法:
next();
hasnext();返回boolean
泛型
规范容器内的数据类型,可以省略掉强转
容器<数据类型>
自己写的类也可以用泛型
lambda表达式
替代匿名内部类实现接口,本质是一种函数式编程
接口名 变量名=(参数列表)->{执行语句};
一般函数有返回值,方法名,参数列表,方法体
lambda表达式只有参数名和方法体
有返回值则在方法体中写return
化简lambda表达式:
参数类型可以省略,单个参数的时候()括号可以省略,方法体只有一条语句{}大括号可省略,
方法体中唯一语句是return,省略大括号的同时也要省略return
方法引用:
将lambda封装成方法,定义通用函数
对象::方法
创建方法,创建对象,接口名 变量名=对象::方法
构造方法引用:
类名::new
异常处理
1.异常是错误对象,运行时异常,编译时异常
2.抛异常,创建一个错误对象,把错误对象丢出来
3.捕获异常,默认由jvm捕获错误信息然后打印,jvm会终止程序执行
处理异常
1.try。。。catch
语法
第一种方案
try{
尝试执行的代码
}catch(exception e){
处理异常的代码,给客户看的
e.printstacktrace();//打印错误信息
}finally{
最终的,一定执行,收尾工作
}
如果在catch中存在return语句,则先执行完finally语句再回头执行return语句
第二种方案
throws和throw
throws exception 表示当前方法会扔出exception这个错误
throws:方法 准备扔出异常
throw:向外抛出异常
throw new exception();
自定义异常
直接继承exception或runtimeexception实现自定义异常
IO流
字节流:
- 按照
字节
的方式读取数据,一次读取1个字节byte,等同于一次读取8个二进制位。
这种流是万能的,什么类型的文件都可以读取。包括:文本文件,图片,声音文件,视频文件
等…
eg.
假设文件file1.txt,采用字节流的话是这样读的:
a中国bc张三fe
第一次读:一个字节,正好读到’a’
第二次读:一个字节,正好读到’中’字符的一半。
第三次读:一个字节,正好读到’中’字符的另外一半。
字符流:
- 按照
字符
的方式读取数据的,一次读取一个字符.
这种流是为了方便读取 普通文本文件
而存在的,这种流不能读取:图片、声音、视频等文件。只能读取 纯文本文件
,连word文件都无法读取。
eg.
假设文件file1.txt,采用字符流的话是这样读的:
a中国bc张三fe
第一次读:'a’字符('a’字符在windows系统中占用1个字节。)
第二次读:'中’字符('中’字符在windows系统中占用2个字节。)
输入流:读,往内存中去
输出流:写,从内存中往外去
在java中只要“类名”以 Stream
结尾的都是字节流。以“ Reader/Writer
”结尾的都是字符流。
需要掌握得流
文件流
- java.io.FileInputStream(掌握)
文件字节输入流,万能
- java.io.FileOutputStream(掌握)
- java.io.FileReader
- java.io.FileWriter
转换流
- java.io.InputStreamReader
- java.io.OutputStreamWriter
缓冲流
- java.io.BufferedReader
BufferedReader带有缓冲区的字符输入流。使用这个流的时候不需要自定义char数组,或者说不需要自定义byte数组。自带缓冲。
- java.io.BufferedWriter
- java.io.BufferedInputStream
- java.io.BufferedOutputStream
序列化:
序列化是把Java对象存在一个硬盘,网络,以便传输
也就是把我们的数据永久的存放到计算机当中