面向对象三大特征:封装、继承、多态
继承
继承是Java面对对象很重要的一部分,给类进行等级层次的划分,即分为父类和子类,父类拥有的特征和行为,能被子类继承。
继承格式
class 子类 extends 父类{
}
Java中只有单继承,多重继承(c继承b,b继承a),没有多继承。
Java脱胎于C++。C++也是面向对象的语言,拥有多继承,即一个子类对应多个父类,但若多个父类内部有同名特征或行为时,继承会出现错乱。Java为了防止这种情况出现,没有多继承。
子类实例化内存分析
子类拥有父类的对象名称super,拥有父类的地址,所以就继承了父类。子类只能使用父类public、protected修饰的特征、行为。
super详解
子类在不明确用super调用时,父类内部必有无参构造方法。否则,程序报错。
在明确调用时,作用如下
-
子类访问父类构造方法;
注意:调用super构造方法的代码,必须写在子类构造方法的第一行,且不能与this重用。
-
子类访问父类属性;
-
子类访问父类的方法。
重写(Override)
子类的方法跟从父类继承过来的方法一样,方法体经过了改变,导致子类方法的生效称为重写。
重写(Override)规则
- 参数列表必须完全与被重写方法相同;
- 返回类型必须完全与被重写方法的返回类型相同;
- 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected;
- 父类的成员方法只能被它的子类重写;
- 声明为static和private的方法不能被重写,但是能够被再次声明。
重写(Override)与重载(Overload)的区别
区别 | 重载 | 重写 |
---|---|---|
发生的位置 | 一个类中 | 子父类中 |
参数列表限制 | 必须不同 | 必须相同 |
返回值类型 | 与返回值类型无关 | 返回值类型必须一致 |
访问权限 | 与访问权限无关 | 子的方法权限必须不能小于父的方法权限 |
异常处理 | 与异常无关 | 异常范围可以更小,但是不能抛出新的异常 |
final关键字
作用
-
修饰属性、变量;
注:变量成为了常量,无法对其再次进行赋值;
final修饰的局部变量,只能赋值依次(可以先声明后赋值);
final修饰的成员属性,必须在声明时赋值。全局常量(public static final)
常量的命名规范:
由1个或多个单词组成,单词与单词之间必须使用下划线隔开,单词中所有字母大写。
例如:SQL_INSERT -
修饰类;
final修饰的类,不可以被继承。 -
修饰方法。
final修饰的方法,不能被子类重写。
抽象类
概念
抽象类必须使用abstract class声明;
一个抽象类中可以没有抽象方法;
抽象方法必须写在抽象类或者接口中。
格式
abstract class 类名{
// 抽象类
}
抽象方法
只声明而未实现的方法称为抽象方法(未实现指的是:没有“{}”方法体),抽象方法必须使用abstract关键字声明。
格式:
abstract class 类名{
// 抽象类
public abstract void 方法名() ; // 抽象方法,只声明而未实现
}
不能被实例化
在抽象类的使用中有几个原则:
- 抽象类本身是不能直接进行实例化操作的,即:不能直接使用关键字new完成;
- 一个抽象类必须被子类所继承,被继承的子类(如果不是抽象类)则必须覆写(重写)抽象类中的全部抽象方法。
常见问题
- 抽象类能否使用final声明?
不能,因为final属修饰的类是不能有子类的 , 而抽象类必须有子类才有意义,所以不能。 - 抽象类能否有构造方法?
能有构造方法,而且子类对象实例化的时候的流程与普通类的继承是一样的,都是要先调用父类中的构造方法(默认是无参的),之后再调用子类自己的构造方法。
抽象类和普通类的区别
- 抽象类必须用public或protected修饰(如果为private修饰,那么子类则无法继承,也就无法实现其抽象方法),默认缺省为public;
- 抽象类不可以使用new关键字创建对象,但是在子类创建对象时,抽象父类也会被JVM实例化;
- 如果一个子类继承抽象类,那么必须实现其所有的抽象方法。如果有未实现的抽象方法,那么子类也必须定义为abstract类。
接口
概念
如果一个类中的全部方法都是抽象方法,全部属性都是全局常量,那么此时就可以将这个类定义成一个接口。
定义格式:
interface 接口名称{
全局常量;
抽象方法;
}
面向接口编程思想
这种思想是接口是定义(规范,约束)与实现(名实分离的原则)的分离。
优点:
- 降低程序的耦合性;
- 易于程序的扩展;
- 有利于程序的维护。