抽取多个类中有相同的特征和行为,放入到一个共同的基类中;其余各类对其进行继承(extends),它们就具备了共同的特征与行为
继承关系,一般用来表示子类和父类的 是 的关系,即子类描述的事物 是父类描述的事物的一个特例
共性 与 个性
继承关键字:extends
、super
权限描述符 class 类名 extends 父类{
类名(T... a) {
super(T...a);
}
...
}
父类:超类、superClass
子类:派生类、subClass
继承关系中,子类可以继承所有父类非私有属性的关系及方法
java中类只可以拥有一个直接父类,即只能直接继承一个父类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yuRaGAco-1656645940604)(assets/wps1-1617714397276.jpg)]
如果可以继承两个父类,存在调用的不确定性问题;当子类继承的这两个父类中都具有共同的属性或行为时,子类对象中调用JVM就不清楚到底会调用哪个,指代不明。
java中继承中,父类可以再继承其他类,叫做多重继承
一个类只能直接继承一个父类,但是可以有多个子类;一个类的父类还可以继承父类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QkLhW3K4-1656645940607)(assets/wps3-1617714539540.jpg)]
子类直接拥有父类非私有
成员变量
如果存在同名成员变量,子类实例使用子类成员变量(就近原则)
子类直接拥有父类非私有
成员方法
子类可以重写父类成员方法,实例化后调用的为子类方法(重写)
结论:
如果子类中没有定义和父类中一样的成员变量和函数,子类对象直接调用时使用的是父类中定义的成员;如果子类中定义了和父类中一样的成员变量和函数,子类对象直接调用时使用都是子类中定义的成员;此时要使用父中定义的成员,需要通过super关键字调用;
调用的格式是:
super.成员变量;
super.成员函数名(参数);
在子类中定义和父类中相同的函数,直接调用函数时,实际使用的是子类中的函数,这种情况叫做方法的重写(覆写);
一般开发中,如果父类的功能不满足子类需要,子类都会重写父类的函数;
实际开发中,根据里氏代换原则
,子类尽量不要重写基类已经写好的方法;根据依赖倒转原则
,任何类不从具体类派生。
前提:
存在继承关系,子类中进行方法重写
原因:
父类中的某个方法功能逻辑不能完全满足子类的需求
注意事项:
存在继承关系
子类修改父类中的同名方法
子父类中同名方法的形参列表相同
子父类中static
访问修饰符相同
子父类中返回值类型相同
子类方法的权限修饰符需要大于等于父类方法的,子类方法的访问级别不能低于父类相应方法的访问级别(子类访问级别不能低于父类访问级别)
举例:
父类 -> public 子类 -> public
父类 -> 缺省 子类 -> 缺省、protected、public
private修饰的方法不存在重写
子类抛出的异常下不能超过父类相应方法抛出的异常(子类异常不能大于父类异常)
总结:
将父类需要重写的方法签名完全复制即可
方法签名 --> 权限修饰符 访问修饰符 返回值类型 方法名(形参列表)
案例
/*
演示方法的重写(Override)
案例:旧手机和新手机
*/
//旧手机
class OldPhone
{
//打电话
public void call(String name,String msg){
System.out.println("正在和" + name + "打电话,内容为:" + msg);
}
//发短信
public void sendMSG(String name,String msg){
System.out.println("正在和" + name + "发送短信,内容为:" + msg);
}
}
//新手机
class NewPhone extends OldPhone
{
/*
父类中的打电话和发短信功能不能完全满足子类的使用需求,所以在子类中对其进行重写操作,效果如下:
*/
//打电话
public void call(String name,String msg){
System.out.println("显示通话人的位置和大头贴");
super.call(name,msg);
}
//发短信
public void sendMSG(String name,String msg){
super.sendMSG(name,msg);
System.out.println("正在发送表情包,么么哒~~");
}
}
class TestPhone
{
public static void main(String[] args)
{
//创建子类对象
NewPhone np = new NewPhone();
//先打个电话
np.call("xx","最近好吗?");
//再发一条短信
np.sendMSG("xx","一起吃个饭吧!");
}
}
继承中类的加载顺序,是先加载父类,然后再加载子类;
【注意事项】