方法重载和方法重写
方法重载:
1、同一个类中
2、方法名相同,参数列表不同(参数顺序、个数、类型)
3、方法返回值、访问修饰符任意
4、与方法的参数名无关
方法重写:
语法规则:
1、返回值类型
2、方法名
3、参数类型、顺序、个数都要与父类继承的方法相同
注:子类只能重写父类方法,但定义属性的时候,子类可以定义与父类重名的属性,调用属性时,如父类和子类都定义了,则调用的为子类的属性,如子类没有定义,只定义了父类,则调用的是父类的属性方法重写:
1、有继承关系的子类中
2、方法名相同,参数列表相同(参数顺序、个数、类型),方法返回值相同
3、访问修饰符,访问范围需要大于等于父类的访问范围
4、与方法的参数名无关
一、java封装
1、封装的概念: 将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供的方法来对隐藏的信息进行操作和访问。
2、好处:
-只能通过规定的方法访问数据
-隐藏类的实例细节,方便修改和实现。
3、封装的实现步骤
-修改属性的可见性设为(private)
-创建getter/setter方法(用于属性的读写)(通过这两种方法对数据进行获取和设定,对象通过调用这两种方法实现对数据的读写)
-在getter/setter方法中加入属性控制语句(对属性值的合法性进行判断)
4、Java中的包
-作用:管理java文件,解决同名文件的冲突
-定义包:package 包名
-必须放在java源程序的第一行,包名间可以使用“.”号隔开例如:com.imooc.animal
5、包的使用。
-可以通过import关键字,在某个文件中使用其他文件中的类。 import com.imooc.animal.Cat
-java中,包的名字规范是全小写的字母拼写
-使用时,不仅可以加载某个包下的所有文件 比如:com.imooc.*,
也可以加载某个具体子包下的所有文件 比如:com.imooc.music.*
6、常用系统包
java.lang 包含java语言基础的类
java.util 包含java语言中各种工具类
java.io 包含输入、输出相关功能的类
7、static
-static+属性--静态属性
-static+方法--静态方法
-static+类--不存在
-static+方法内局部变量--不存在
静态成员随类加载产生,直至类销毁才回收
8、静态方法
-可以直接调用同类中的静态成员
-不可以直接调用同类中的非静态成员
-可以通过实例化对象后,对象调用的方式完成非静态成员调用
9、代码块
-通过{}可以形成代码块
-方法内的代码块称为:普通代码块
-类内的代码块称为:构造代码块
-构造代码块前+static:静态代码块
二、java继承
概念:
1、一种类与类之间的关系
2、使用已存在的类的定义作为基础建立新类
3、新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类
4、满足“A is a B”的关系
特点:
1、利于代码复用
2、缩短开发周期
语法:
1、使用extends实现继承
2、单一继承,只能有一个父类
1、继承后的初始化顺序
注:访问修饰符不影响成员加载顺序,跟书写位置有关
2、 子类构造默认调用父类无参构造方法
可以通过super()调用父类允许被访问的其他构造方法
super()必须放在子类构造方法有效代码第一行
3、super
代表父类引用
-访问父类成员方法 super.print();
-访问父类属性 super.name;
-访问父类构造方法 super();
-子类的构造的过程中必须调用其父类的构造方法
-如果子类的构造方法中没有显示标注,则系统默认调用父类无参的构造方法
-如果子类构造方法中既没有显示标注,且父类中没有无参的构造方法,则编译出错
-使用 super调用父类指定构造方法,必须在子类的构造方法的第一行
4、this和super!
构造方法调用时,super和this不能同时出现!
5、 Object类
-Object类是所有类的父类
-一个类没有使用extends关键字明确标识继承关系,则默认继承Object类(包括数组)
-java中的每个类都可以使用Object中定义的方法
6、final关键字的使用
-1.修饰类表示不允许被继承
-2.修饰方法表示不允许被子类重写
-final修饰的方法可以被继承 -不能修饰构造方法 -3.修饰变量表示不允许修改
-方法内部的局部变量》在使用之前被初始化赋值即可
-类中成员变量》只能在定义时、构造方法、构造代码块中进行
-基本数据类型的变量》初始赋值之后不能更改
-引用类型的变量》初始化之后不能再指向另一个对象,但对象的内容是可变的
-4、可配合static使用
配置信息
public static final String URL="www.imooc.com";
-5、使用final修饰可以提高性能,但会降低可扩展性
-6、注解
三、访问修饰符
1、公有的:public
2、私有的:private
3、受保护的:protected
4、默认
四、单例模式
-要点:
1、某个类只能有一个实例
2、必须自行创建实例
3、必须自行向整个系统提供这个实例
-实现:
1、只提供私有的构造方法
2、含有一个该类的静态私有对象
3、提供一个静态的公有方法用于创建、获取静态私有对象
优点:
1、在内存中只有一个对象,节省内存空间
2、避免频繁的创建销毁对象,提高性能
3、避免对共享资源的多重占用
缺点:
1、扩展比较困难
2、如果实例化后的对象长期不利用,系统将默认为垃圾进行回收,造成对象状态丢失
代码实现方案:
1、饿汉式:对象创建过程中实例化(在类加载时就创建实例)
空间换时间(时间快,空间大)
饿汉式线程安全
2、懒汉式:静态公有方法中实例化(只有在用到的时候才会去创建),第一次使用时进行实例化
时间换空间(时间慢,空间小)
懒汉式存在线程风险(1、同步锁 2、双重校验锁 3、静态内部类 4、枚举)
使用场景:(具体场景,具体分析)
1、创建对象时占用资源过多,但同时又需要用到该类对象
2、对系统内资源要求统一读写,如读写配置信息
3、对多个实例存在可能引起程序逻辑错误,如号码生成器
五、多态
-意味着允许不同类的对象对同一消息做出不同的响应
-编译时多态(设计时多态):编译器在编译状态就可以进行不同行为的区分,通常这种方式是通过方法重载来实现的
-运行时多态:程序运行时动态决定调用哪个方法
实现必要条件:
-满足继承关系
-父类引用指向子类对象
1、向上转型
java中的一种调用方式。向上转型是对A的对象的方法的扩充,即A的对象可访问B从A中继承来的和B复写A的方法
/* 向上转型、隐式转型、自动转型
- 父类引用指向子类实例,可以调用子类重写父类的方法以及父类派生的方法,无法调用子类独有方法
- 小类转型为大类 */
2、向下转型
/* 向下转型、强制类型转换
- 子类引用指向父类对象,此处必须进行强转,可以调用子类特有的方法
- 必须满足转型条件才能进行转换
- instanceof运算符:返回true/false */
3、instanceof 判断左边的对象是否满足右边的类:如果是就返回true,不是就返回false
4、抽象类&抽象方法
-没有方法体的方法是抽象方法
-应用场景:某个父类只是知道其子类应该包含怎样的方法,但无法准确知道这些子类如何实现这些方法!
-使用规则
1、abstract定义抽象类
2、抽象类不能直接实例化,只能被继承,可以通过向上转型完成对象实例
3、abstract定义抽象方法,不需要具体实现
4、包含抽象方法的类是抽象类
5、抽象类中可以没有抽象方法
问题:
-Java中只支持单继承
-如何解决一个类型中需要兼容多种类型特征的问题?
-以及多个不同类型具有相同特征的问题呢?
5、接口
-接口定义了某一批类所需要遵守的规范
-接口不关心这些类的内部数据,也不关心这些类里方法的实现细节,它只规定这些类里必须提供某些方法
6、内部类
-在java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类
-与之对应,包含内部类的类被称为外部类
-为什么要将一个类定义在另一个类里面呢?(内部类隐藏在外部类之内,更好的实现了信息隐藏)
-内部类的分类
1、成员内部类(普通内部类)
2、静态内部类
3、方法内部类:定义在外部类方法中的内部类,也称局部内部类
4、匿名内部类:
适用场景:
1、只用到类的一个实例
2、类在定义后马上用到
3、给类命名并不会导致代码更容易被理解
六、java异常
-异常本质上是程序上的错误
-错误在我们编写程序的过程中会经常发生,包括编译期间和运行期间的错误
-1、编译期间错误:
如:
括号没有正常的配对
语句结束后少写了分号
关键字编写错误
-2、运行期间错误:
如:使用空的对象引用调用方法
数组访问时下标越界
算术运算时除数为0
类型转接时无法正常转型
-在程序运行过程中,意外发生的情况,背离我们程序本身的意图的表现,都可以理解为异常
异常分类
Throwable:
1、Error:是程序无法处理的错误,表示运行应用程序中较严重问题
2、Exception:是程序本身可以处理的异常,异常处理通常指针对这种类型异常的处理!
异常处理
-在java应用程序中,异常处理机制为:
1、抛出异常
2、捕获异常!
try-catch-finally
-try块后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块
return关键字的异常处理中的作用
throw&throws
-可以通过throws声明将要抛出何种类型的异常,通过throw将产生的异常抛出
-如果一个方法可能会出现异常,但没有能力处理这种异常,可以在方法声明处用throws子句来声明抛出异常
-throws语句用在方法定义时声明该方法要抛出的异常类型
-当方法抛出异常列表中的异常时,方法将不对这些类型及其子类类型的异常作处理,而抛向调用该方法的方法,由他去处理
-throw用来抛出一个异常
例如:throw new IOException();
-throw抛出的只能够是可抛出类Throwable或者其子类的实例对象
例如:throw new String("出错啦");是错误的
自定义异常
-可以通过自定义异常描述特定业务产生的异常类型
-所谓自定义异常,就是定义一个类,去继承Throwable类或者它的子类
异常链
-有时候我们会捕获一个异常后在抛出另一个异常
-顾名思义就是:将异常发生的原因一个传一个串起来,即把底层的异常信息传给上层,这样逐层抛出
七、包装类
-Java中通过包装类来解决基本数据类型不具有对象化能力的问题,因此每一种基本数据类型都有它对应的包装类,我们也可以通过名字来找到基本数据类型和包装类之间的对应关系,Java中所有的包装类都是存在java.lang这个包装的
-可以通过装箱和拆箱来实现包装类和基本数据类型之间的转换,可以由包装类来完成基本数据类型和字符串之间的转换
八、java字符串
-String和StringBuilder
-如何创建String对象?
创建String对象的方法
1、String s1="imooc"; 创建一个字符串对象imooc,名为s1
2、String s2=new String(); 创建一个空字符串对象,名为s2
3、String s3=new String("imooc"); 创建一个字符串对象imooc,名为s3
-String对象的常用方法
-==和equals():
==用来比较两个对象是否相等
equals()用来比较字符串内容是否相等
-String和StringBuilder的区别,主要是不可变性
String具有不可变性,而StringBuilder不具备
如果频繁操作字符串,建议使用StringBuilder来完成,因为它不会产生多余的中间变量和一些不用的或废弃的字符串常量,一些简单的操作可以使用String类
-StringBuilder和StringBuffer
二者基本相似
StringBuffer是线程安全的,StringBuilder则没有,所以性能略高
九、java集合
-Java中的集合是工具类,可以存储任意数量的具有共同属性的对象
-应用场景
1、无法预测存储数据的数量
2、同时存储具有一对一关系的数据
3、需要进行数据的增删
4、数据重复问题
-集合框架的体系结构
-List(列表)
1、list是元素有序并且可以重复的集合,称为序列
2、list可以精确的控制每个元素的插入位置,或删除某个位置的元素
3、list的两个主要实现类是ArrayList和LinkedList
-ArrayList
1、ArrayList底层是由数组实现的
2、动态增长,以满足应用程序的需求
3、在列表尾部插入或删除数据非常有效
4、更适合查找和更新元素
5、ArrayList中的元素可以为null
-Set
-Set是元素无序并且不可以重复的集合,被称为集
HashSet是Set的一个重要实现类,称为哈希集
HashSet中的元素无序并且不可以重复
HashSet中只允许一个null元素
具有良好的存取和查找性能
-Iterator(迭代器)
Iterator接口可以以统一的方式对各种集合元素进行遍历
hasNext()方法检测集合中是否还有下一个元素
next()方法返回集合中的下一个元素
-Map
Map中的数据是以键值对(key-value)的形式存储的
key-value以Entry类型的对象实例存在
可以通过key值快速地查找value
一个映射不能包含重复的键
每个键最多只能映射到一个值
-HashMap
基于哈希表的Map接口的实现
允许使用null值和null键
key值不允许重复
HashMap中的Entry对象是无序排列的
十、java线程
首先引入进程的概念:
进程是指可执行程序并存放在计算机存储器的一个指令序列,它是一个动态执行的过程
-线程
线程是比进程还要小的运行单位,一个进程包含多个线程,线程可以看做一个子程序
线程的创建?
1、创建一个Thread类,或者一个Thread子类的对象
2、创建一个实现Runnable接口的类的对象
-Thread类
Thread是一个线程类,位于java.lang包下
Thread类的常用方法
-Runnable接口
只有一个方法run();
Runnable是Java中用以实现线程的接口
任何实现线程功能的类都必须实现该接口
线程创建
1、通过继承Thread类的方式创建线程类,重写run()方法
new MyThread().start()
2、通过实现Runnable接口的方式创建
new Thread(new MyRunnable()).start()
为什么要实现Runnable接口?
-Java不支持多继承
-不打算重写Thread类的其他方法
线程的状态和生命周期?
-线程的状态
1、新建(New)
2、可运行(Runnable)
3、正在运行(Running)
4、阻塞(Blocked)
5、终止(Dead)
-线程的生命周期
-线程优先级
1、Java为线程类提供了10个优先级
2、优先级可以用整数1-10表示,超出范围会抛出异常
3、主线程默认优先级为5
优先级常量
-MAX_PRIORITY: 线程的最高优先级10
-MIN_PRIORITY: 线程的最低优先级10
-NORM_PRIORITY: 线程的默认优先级5
优先级相关的方法
同步与死锁?
-多线程运行问题
1、各个线程是通过竞争CPU时间而获得运行机会的
2、各线程什么时候得到CPU时间,占用多久,是不可预测的
3、一个正在运行着的线程在什么地方被暂停是不确定的
十一、Java输入输出流
文件输入——读(read)
文件输出——写(write)
File类的使用
-什么是文件?
文件可认为是相关记录或放在一起的数据的集合
在Java中,使用java.io.File类对文件进行操作
字节流
-字节输入流InputStream
FileInputStream:
1、从文件系统中的某个文件中获取输入字节
2、用于读取诸如图像数据之类的原始字节流
-字节输出流OutputStream
FileOutputStream:
-缓冲流
缓冲输入流BufferedInputStream
缓冲输出流BufferedOutputStream
字符流
-字符输入流Reader
-字符输出流Writer
-字节字符转换流
InputStreamReader
OutputStreamWriter
对象的序列化: 把Java对象转换为字节序列的过程
反序列化:把字节序列恢复为Java对象的过程
步骤:
-创建一个类,继承Serializable接口
-创建对象
-将对象写入文件
-从文件读取对象信息
对象输入流ObjectInputStream
对象输出流ObjectOutputStream