继承
继承就是子类继承父类的特征和行为,使得子类具有父类的各种属性和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
提高了代码的复用性
让类与类之间产生关系,有了多态的特性。
不要单纯为了获取其他类的功能属性、简化代码而随意继承,必须是类与类之间有所属关系才可以继承。
Java只支持单继承。 即只能继承一个类。
单继承原因:
因为多继承容易有安全隐患。
假设继承多个类,则本类具有父类的属性和方法,如果多个类中有相同的属性或者方法,则不能区分。
虽然不支持多继承,但是用多实现弥补了不支持多继承的缺陷。
Java支持多层继承。
子父类中变量的特点
- 变量
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,并且已经赋值。
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
}
}
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("我是子类!");
}
}
打印结果:
我是子类!
子类函数必须大于等于父类权限,才可以覆盖。
重载和重写:
多个函数之间才可能有重载关系,多个同名函数参数列表不同会发送重载现象,详见 函数重载详解
子父类中不允许出现返回值类型不同的同名函数。
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("子类构造函数!");
}
}
运行结果:
父类构造函数!
子类构造函数!
如果父类的有自己写的构造函数,即空参数的构造函数不存在,就必须在子类的构造函数中指明
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("子类构造函数!");
}
}
子类实例化过程:
就到这里,需要好好消化理解一下了。