java基础知识复习
可变参数
• 如果该方法除了可变参数还有其它的参数,可变参数必须放到最后;
调用使用了可变参数的方法时:
a) 可以不写参数,即传入空参;
b) 可以直接在里边写入参数,参数间用逗号隔开;
c) 可以传入一个数组;
• 拥有可变参数的方法可以被重载,在被调用时,如果能匹配到参数定长的方法则优 先调用参数定长的方法。
• 可变参数可以兼容数组参数,但数组参数无法兼容可变参数,所以试图使用数组作为参数去实现重载时,会报错,说明可变参数与数组冲突
封装
封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式。
权限访问控制符
同一类中 | 同一包中 | 子类 | 全局范围 | |
---|---|---|---|---|
private | √ | |||
default(可省略) | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
封装的好处
(1)良好的封装能够减少耦合
(2)类内部的结构可以自由修改
(3)可以对成员进行更精确的控制
(3)隐藏信息,实现细节
封装的步骤
(1)修改属性的可见性来限制对属性的访问(一般限制为private)
(2)对每个值属性提供对外的公共方法访问--创建一对赋值取值方法
继承
继承:是指可以让某个类型的对象获得另一个类型的对象的属性的方法。
语法:
class 父类 { // 定义父类
...
}
class 子类 extends 父类 { // 用extends关键字实现类的继承
...
}
继承的特性
(1)子类拥有父类非private的属性和方法
(2)子类可以拥有自己的属性和方法,即子类可以对父类进行扩展
(3)子类可以用自己的方式实现父类的方法
(4)一个子类只能有一个父类,但是Java中允许多层继承
(5)提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系)
方法的重写
概念:子类从父类中继承方法,有时,子类需要修改父类中定义的方法的实现。
规则:
- 参数列表必须完全与被重写方法的相同
- 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类
- 访问权限不能比父类中被重写的方法的访问权限更低
- 父类的成员方法只能被它的子类重写
- 声明为final的方法不能被重写。声明为static的方法不能被重写,但是能够被再次声明
- 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
- 构造方法不能被重写
方法的重载
概念:多个方法可以享有相同的名字,但是参数的数量或类型不能完全相同。
规则:
- 被重载的方法必须改变参数列表(参数个数或类型不一样)
- 被重载的方法可以改变返回类型
- 被重载的方法可以改变访问修饰符
- 被重载的方法可以声明新的或更广的检查异常
- 方法能够在同一个类中或者在一个子类中被重载
- 无法以返回值类型作为重载函数的区分标准
构造方法
构造函数(构造器、构造函数):构造函数是一种特殊的函数。其主要功能是在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用以创建对象。
构造方法使用的原则:
- 方法名与类名相同
- 没有返回类型(例如return、void等)
- 不能被static、final、native、abstract和synchronized修饰,不能被子类继承
- 父类的构造方法不能被子类调用,可以通过super语句调用父类的构造方法
- 构造方法可以重载,以参数的个数、类型和顺序,分为无参和有参构造方法
抽象
抽象方法
定义规则:
- 用abstract关键字修饰
- 只声明返回值的数据类型、方法名称与所需的参数
- 无需定义方法体
抽象类
定义规则:
- 用abstract关键字修饰
- 抽象类不能被实例化
- 含有抽象方法的类必须被声明为抽象类
- 抽象类的子类必须复写所有的抽象方法后才能被实例化,否则这个子类还是个抽象类
多态
多态的优点
- 消除类型之间的耦合关系
- 可替换性
- 可扩充性
- 接口性
- 灵活性
- 简化性
多态存在的必要条件
- 继承
- 重写
- 父类引用指向子类对象
特点
- 只对非静态的方法有效
- 继承或者实现关系。
- 父类/父接口的引用指向子类/子实现类的对象。
- 编译看左边,运行看右边。
运用
- 使用多态的方式作为方法的形参,那么此方法可以接受更多的实参数据类型。
- 使用多态作为方法的返回值,那么此方法可以接受更多的返回值类型。 Animal a = new Cat(); // 向上转型 Cat c = (Cat) a; // 向下转型
接口
接口概念
接口(Interface):在JAVA编程语言中是一个抽象类型,是抽象方法的集合。接口通常以interface来声明。一个类通过继承接口的方式,从而继承接口的抽象方法。
如果一个类只由抽象方法和全局常量组成,那么这种情况下应将其定义为一个接口,所以接口严格的来讲属于一个特殊的类,而这个类中只有抽象方法和全局常量,就连构造方法也没有。
接口使用原则
- 接口中所有的成员变量默认以 public static final 修饰
- 接口中所有的方法默认以 public abstract 修饰
- 类只能单继承,但接口可以继承多个接口
- 接口必须要有子类,但此时一个子类可以使用implements关键字实现多个接口
- 接口的子类(如果不是抽象类),那么必须要覆写接口中的全部抽象方法
- 接口的对象可以利用子类对象的向上转型进行实例化 对于子类而言,若既要继承抽象类,同时还要实现接口的话,使用以下语法格式:
- class 子类 [ extends 父类 ] [ implements 接口1,接口2,…] { } 从接口的概念上来讲,接口只能由抽象方法和全局常量组成,但是内部结构是不受概念限制的,正如抽象类中可以定义抽象内部类一样,在接口中也可以定义普通内部类、抽象内部类和内部接口。(但从实际的开发来讲,用户自己去定义内部抽象类或内部接口的时候是比较少见的)
示例如下,在接口中定义一个抽象内部类:
interface A {
public void funA();
abstract class B{ //定义一个抽象内部类
public abstract void funB();
}
}
在接口中如果使用了static去定义一个内接口,它表示一个外部接口:
interface A {
public void funA();
static interface B{ //使用了static,是一个外部接口
public void funB();
}
}
class C implements A.B{
@Override
public void funB() {
}
}
关键字
super关键字
- super可以用来引用直接父类的实例变量
- super可以用来调用直接父类的方法
- super()可以用于调用直接父类的构造方法
super 与 this 的区别
super关键字:
- 可以实现对父类成员的访问,用来引用当前对象的父类
- 子类调用父类的方法或属性
- 调用父类中的构造方法时放在程序首行
this关键字:
- 指向自己的引用,表示当前对象
- 调用本类中的方法或属性
- 调用本类中的构造方法时放在程序首行
为什么要使用final修饰一个类?
- 出于安全性的原因和效率上的考虑,有时候需要防止一个类被继承
- 如果你认为一个类的定义已经很完美,不需要再生成它的子类,这时也应把它修饰为final类
final关键字
- final标记的类不能被继承
- final标记的方法不能被子类复写,可以被重载
- final标记的变量(成员变量或局部变量)即为常量,只能赋值一次
注意:声明为final的类隐含地声明了该类的所有方法为final方法
instanceof 关键字
作用:
- 判断一个类是否实现了某个接口
- 判断一个实例对象是否属于某一个类
语法格式:
对象 instanceof 类(或接口) // 返回值是布尔型
多态的实现形式:
- 基于继承实现的多态
- 基于接口实现的多态
注:当子类对象调用重写的方法时,调用的是子类的方法,而不是父类中被重写的方法。 要想调用父类中被重写的方法,则必须使用关键字 super。
transient 关键字
- 一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
- transient关键字只能修饰变量,而不能修饰方法和类。注:本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
- 被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。
序列化和反序列化
- 序列化:将一个对象转换成一串二进制表示的字节数组,通过保存或转移这些字节数据来达到持久化的目的。
- 反序列化:将字节数组重新构造成对象。