java中的继承

一、继承

是面向对象三大特征之一。

继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承的方法,使得子类具有父类相同的行为。

继承需要符合的关系是:is-a。例如:智能手机是手机。

二、类的继承格式

在java中通过extends关键字可以申明一个类是从另一个类继承而来的,一般形式如下:

{修饰符列表} class类名 extends 父类名{

                        类体=属性+方法

}

class Phone{
    
}
class SmartPhone extends Phone{
    
}

三、java语言中的继承只支持单继承

一个类不能同时继承很多类,只能继承一个类。但是一个类也可以间接继承其他类。

class A{
}
class B{
}
class C{
}
class T{
}

class C extends class B{
}
class B extends class A{
}
class A extends class T{
}

C类直接继承B类,但是C类间接继承A、T类。

四、继承的特性

1、private修饰的属性、方法不支持继承。

2、构造方法不支持继承。

3、继承父类非private的属性和方法,并且子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。

五、所有类的父类---Object类

java语言中一个类没有显示的继承任何类,该类默认继承java.lang.Object类。

六、方法重写

在继承体系中,子类中出现了和父类中一模一样的方法声明,我们就称子类这个方法是重写的方法。

重写方法的名称、形参列表必须与被重写方法的名称和参数列表一致。私有方法不能被重写。子类重写父类方法时,访问权限必须大于或等于父类。

方法重写的应用场景,当父类的该功能不能完全满足自己的需求时,子类可以重写父类中的方法。

public class Teat4 {
    public static void main(String[] args) {
        SmartPhone hw=new SmartPhone();
        hw.call();
        hw.sendMsg();
    }
}
class Phone{
    public void call(){
        System.out.println("打电话");
    }
    public void sendMsg(){
        System.out.println("发短信");
    }
}
class SmartPhone extends Phone{
    public void call(){
        System.out.println("视频通话");
    }
    public void sendMsg(){
        System.out.println("发图片");
    }
}

运行结果:

七、继承后:成员变量、成员方法的访问特点。

在子类中访问成员变量或成员方法满足:就近原则。

先从子类开始找,按照从局部范围到成员范围的顺序;在子类中没有找到再从父类中找,也是按照从局部范围到成员范围找;若是在父类中也没有找到,就会报错!

如果子父类中出现了重名的成员,会优先使用子类的。此时如果一定要在子类中使用父类的怎么办?

可以通过super关键字,指定访问父类的成员。

格式:super.父类成员变量/父类成员方法格式,如下:

public class Teat4 {
    public static void main(String[] args) {
        SmartPhone hw=new SmartPhone();
        hw.call();
        hw.sendMsg();
    }
}
class Phone{
    public void call(){
        System.out.println("打电话");
    }
    public void sendMsg(){
        System.out.println("发短信");
    }
}
class SmartPhone extends Phone{
    public void call(){
        super.call();
        System.out.println("视频通话");
    }
    public void sendMsg(){
        super.sendMsg();
        System.out.println("发图片");
    }
}

运行结果:

 八、子类构造器

1、子类继承父类后,子类中所有的构造器都会默认先访问父类中无参数的构造器,然后再执行自己的。

public class Teat4 {
    public static void main(String[] args) {
        SmartPhone sm=new SmartPhone();
        SmartPhone sm1=new SmartPhone(6900);

    }
}
class Phone{
    int price;

    public Phone(){
        System.out.println("父类无参数的构造方法! ");
    }
}
class SmartPhone extends Phone{
    public SmartPhone(){
        System.out.println("子类中无参数的构造方法!");
    }
public SmartPhone(int price){
        this.price=price;
        System.out.println("智能手机的价格为:"+price);
    }
}

运行结果:

 2、如果父类中没有无参数的构造器,只有有参构造器,就会报错。因为子类默认是调用父类无参构造器的。

public class Teat4 {
    public static void main(String[] args) {
        SmartPhone sm1=new SmartPhone(6900);

    }
}
class Phone{
    int price;
    public Phone(int price){
        this.price=price;
        System.out.println("手机的价格为:"+price);
    }
}
class SmartPhone extends Phone{
    public SmartPhone(int price){
        this.price=price;
        System.out.println("智能手机的价格为:"+price);
    }
   
}

运行结果:

 3、如何解决

子类构造器中可以通过书写super(...),手动调用父类的有参构造器

public class Teat4 {
    public static void main(String[] args) {
        SmartPhone sm1=new SmartPhone(6900);
    }
}
class Phone{
    int price;
    public Phone(int price){
        this.price=price;
        System.out.println("手机的价格为:"+price);
    }
}
class SmartPhone extends Phone{
    public SmartPhone(int price){
        super(price);
        this.price=price;
        System.out.println("智能手机的价格为:"+price);
    }
}

运行结果: