继承

继承就是子类继承父类的特征和行为,使得子类具有父类的各种属性和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

为什么Java类是单继承的 为什么java只能单继承_java

提高了代码的复用性
让类与类之间产生关系,有了多态的特性。
不要单纯为了获取其他类的功能属性、简化代码而随意继承,必须是类与类之间有所属关系才可以继承。


Java只支持单继承。 即只能继承一个类。
单继承原因:
因为多继承容易有安全隐患。
假设继承多个类,则本类具有父类的属性和方法,如果多个类中有相同的属性或者方法,则不能区分。
虽然不支持多继承,但是用多实现弥补了不支持多继承的缺陷。
Java支持多层继承。

子父类中变量的特点

  1. 变量
public class Hello extends ClassTwo {
    public static void main(String[] args) {
        ClassTwo classTwo = new ClassTwo();
        System.out.println(classTwo.num + "===" + classTwo.num2);
    }

}

class ClassOne {
    int num = 3;
}

class ClassTwo extends ClassOne {
    int num2 = 1;
}
打印结果:
3===1

此时ClassOne中有一个int型变量,ClassTwo继承自ClassOne拥有了这个变量,然后自己又定义了一个int型的num2,互不冲突,于是对象classTwo 就有两个变量。
但是如果在CLassTwo中也有一个与父类同名的变量,就会覆盖掉原来的变量:

class ClassOne {
    int num = 3;
}

class ClassTwo extends ClassOne {
    float num = 1.0f;
}
此时ClassTwo的对象中只有一个变量,那就是float型的num,并且已经赋值。

为什么Java类是单继承的 为什么java只能单继承_子父类构造函数_02

public class Hello extends ClassTwo {
    public static void main(String[] args) {
        ClassTwo classTwo = new ClassTwo();
        classTwo.show();

        // 在创建对象时,会先加载父类,然后加载子类,在一个对象实例中既有父类的成员,也有本类的成员
    }

}

class ClassOne {
    public int num = 3;
}

class ClassTwo extends ClassOne {
    int num = 5;

    void show() {
        System.out.println(num);// 默认省略了 this.其实是this.num
        System.out.println(super.num);// 用super打印父类中的变量
        // 如果本类中没有num,则System.out.println(num);打印父类中的num
    }
}

为什么Java类是单继承的 为什么java只能单继承_为什么Java类是单继承的_03


2. 函数的特点

如果子类父类中的方法一致,则子类会重写父类的方法(覆盖)
覆盖并不是父类的方法不存在,只是不运行而已。子类中的方法优先运行。

public class Hello extends ClassTwo {
    public static void main(String[] args) {
        ClassTwo classTwo = new ClassTwo();
        classTwo.show();
    }

}

class ClassOne {
    void show() {
        System.out.println("我是父类!");
    }
}

class ClassTwo extends ClassOne {
    void show() {
        System.out.println("我是子类!");
    }
}
打印结果:
我是子类!

子类函数必须大于等于父类权限,才可以覆盖。

为什么Java类是单继承的 为什么java只能单继承_继承_04

重载和重写:
多个函数之间才可能有重载关系,多个同名函数参数列表不同会发送重载现象,详见 函数重载详解
子父类中不允许出现返回值类型不同的同名函数。

3. 构造函数的特点

public class Hello extends ClassTwo {
    public static void main(String[] args) {
        new ClassTwo();
    }
}

class ClassOne {
    ClassOne() {
        System.out.println("父类构造函数!");
    }
}

class ClassTwo extends ClassOne {
    ClassTwo() {
        // super();//这一句是默认的 但是不显示出来
        System.out.println("子类构造函数!");
    }
}
运行结果:
父类构造函数!
子类构造函数!

为什么Java类是单继承的 为什么java只能单继承_为什么Java类是单继承的_05

如果父类的有自己写的构造函数,即空参数的构造函数不存在,就必须在子类的构造函数中指明

public class Hello extends ClassTwo {
    public static void main(String[] args) {
        new ClassTwo();
    }
}

class ClassOne {
    ClassOne(int x) {
        System.out.println("父类构造函数!");
    }
}

class ClassTwo extends ClassOne {
    ClassTwo() {
        super(3);//指明父类的构造函数
        System.out.println("子类构造函数!");
    }
}

为什么Java类是单继承的 为什么java只能单继承_java_06

子类实例化过程:

为什么Java类是单继承的 为什么java只能单继承_子父类构造函数_07

就到这里,需要好好消化理解一下了。