继承
class 子类名 extends 父类名 {}
-
单独的这个类称为父类,基类或者超类;这多个类可以称为子类或者派生类。
-
有了继承以后,我们定义一个类的时候,可以在一个已经存在的类的基础上,还可以定义自己的新成员。
-
Java只支持单继承,不支持多继承
-
Java支持多层继承(继承体系)
-
子类只能继承父类所有非私有的成员(成员方法和成员变量)
其实这也体现了继承的另一个弊端:打破了封装性
-
子类不能继承父类的构造方法,但是可以通过super(后面讲)关键字去访问父类构造方法
-
不要为了部分功能而去继承
继承中成员变量的关系
-
首先在子类局部范围找
-
然后在子类成员范围找
-
最后在父类成员范围找
super关键字
-
super的用法和this很像
this代表本类对应的引用。
super代表父类存储空间的标识(可以理解为父类引用)
用法(this和super均可如下使用)
-
调用成员变量
this.成员变量 super.成员变量
-
调用构造方法
this(…) super(…)
-
访问成员方法
this.成员方法() super.成员方法()
继承中构造方法的关系
子类中所有的构造方法默认都会访问父类中空参数的构造方法
因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化。
子类每一个构造方法的第一条语句默认(隐藏)都是:super()
如果父类中没有无参构造方法,怎么解决
-
在父类中加一个无参构造方法
-
通过使用super关键字去显示地调用父类的带参构造方法
-
子类通过this去调用本类的其他构造方法
子类中一定要有一个去访问了父类的构造方法,否则父类数据就没有初始化
-
super()或this()必须出现在一条语句上,否则,就可能对父类的数据进行了多次初始化
继承中成员方法的关系
-
如果方法名不同,就调用对应的方法
-
如果方法名相同,最终使用的是子类自己的
方法重写
子类中出现了和父类中一模一样的方法声明,也被称为方法覆盖,方法复写。
-
使用父类的方法,在子类方法中通过
super.方法()
调用子类重写父类方法时,最好声明一样
-
父类中私有方法不能被重写
-
子类重写父类方法时,访问权限不能更低,最好一致。
-
父类静态方法,子类也必须通过静态方法进行重写,不算方法重写。
final关键字
final关键字是最终的意思,可以修饰类,成员变量,成员方法。
-
修饰类,类不能被继承
-
修饰变量,变量就变成了常量,只能被赋值一次
-
修饰方法,方法不能被重写
final修饰局部变量
-
基本类型,是值不能被改变
-
引用类型,是地址值不能被改变
final修饰变量的初始化时机
-
被final修饰的变量只能赋值一次
-
在对象构造完毕前即可
多态
某一个事物,在不同时刻表现出来的不同状态
多态前提和体现
-
有继承关系
-
有方法重写
-
有父类引用指向子类对象
父 f = new 子()
多态成员访问特点
-
构造方法
创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。
-
成员变量
编译看父类,运行看父类
-
成员方法
编译看父类,运行看子类
静态方法
编译看父类,运行看子类.... 静态和类相关,算不上重写,所以,访问还是父类的
由于成员方法存在方法重写,所以运行看子类。子类没有重写则调用父类方法(继承)。
多态利弊
提供代码的维护性(继承)
提高代码的扩展性(多态)
弊端:不能使用子类的特有方法
向下转型-把父类的引用强制转换为子类的对象 Zi z=(Zi)f;
向上转型:Fu f=new Zi();
抽象类
在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。
-
抽象类和抽象方法必须用abstract关键字
-
抽象类中不一定有抽象方法,但是抽象方法的类必须定义为抽象类
-
抽象类不能实例化,有构造方法,用于子类访问父类的初始化
-
抽象类的子类
-
要么是抽象类
-
要么重写抽象类中的所有抽象方法
-
抽象类的实例化其实是靠具体的子类实现的,是多态的方式。
抽象成员的特点
-
成员变量
可以是变量,也可以是常量
-
构造方法
有构造方法,用于子类访问父类数据的初始化
-
成员方法
抽象方法 限定子类必须完成某些动作
非抽象方法 提高代码复用性
abstract不能和哪些关键字共存
-
private 冲突
-
final 冲突
-
static 无意义
接口
接口特点
-
接口用关键字interface表示
格式:interface 接口名 {}
-
类实现接口用implements表示
格式:class 类名 implements 接口名 {}
-
接口不能实例化
按照多态的方式,由具体的子类实例化。
-
接口的子类
-
抽象类,意义不大
-
重写接口中的所有抽象方法
-
成员特点
-
成员变量
-
只能是常量
-
默认修饰符 public static final,建议手动给出
-
-
构造方法
-
没有,因为接口主要是扩展功能的,而没有具体存在
-
-
成员方法
-
只能是抽象方法
-
默认修饰符 public abstract
-
类与类
继承关系,只能单继承,但是可以多层继承
类与接口
实现关系,可以单实现,也可以多实现。还可以在继承一个类的同时实现多个接口
接口与接口
继承关系,可以单继承,也可以多继承
抽象类和接口的区别
抽象类: 变量,常量;有构造方法;抽象方法,非抽象方法
接口: 常量;抽象方法
形式参数和返回值问题
形式参数:基本类型
引用类型:类,需要该类的对象
抽象类,需要该抽象类的子类对象
接口,需要的是该接口的实现类对象
返回值类型:基本类型
引用类型:类,返回是该类的对象
抽象类 ,返回该抽象类的子类对象
接口,返回该接口的实现类对象
链式编程
包
其实就是文件夹,对类进行分类管理,把相同的类名放到不同的包中
定义包的格式
package 包名;
多级包用.分开即可
-
package语句必须是程序的第一条可执行的代码
-
package语句在一个java文件中只能有一个
-
如果没有package,默认表示无包名
导包
import 包名;
内部类位置
成员内部类
外部类名.内部类名 对象名 = 外部类对象.内部类对象;
-
private 为了保证数据的安全性
-
static 为了方便访问数据
注意:静态内部类访问的外部类数据必须用静态修饰
访问静态方法:上面创建的对象访问,或者外部类名.内部类名.方法名();
局部内部类
-
可以直接访问外部类的成员
-
在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
-
局部内部类访问局部变量必须用final修饰
匿名内部类
-
前提:存在一个类或者接口
这里的类可以是具体类也可以是抽象类。
-
格式:
new 类名或者接口名() {重写方法;}
-
本质:
是一个继承了类或者实现了接口的子类匿名对象