继承
- 继承是类和类之间的一种关系。继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模
- 继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。extends的意思是“扩展”。子类是父类的扩展。子类和父类之间,从意义上来讲应该具有“is a”的关系
- java中类只有单继承,没有多继承(一个儿子只能有一个爸爸,一个爸爸可以有多个儿子)
- ctrl+h可以打开查看继承关系
- java中所有的类都默认直接或者间接继承object
- private修饰的私有的东西无法被继承
super
- 子类的系统默认生成的无参构造方法中其实隐藏有一句:
super();
也就是会调用父类的无参构造方法。如果这一句想自己写的话,必须是在子类构造器的第一行
- super也可以调用父类的有参构造方法,和调用无参构造方法一样,也是必须在子类构造方法的第一行
- super只能出现在子类的方法或者构造方法中
- super和this不能同时调用构造方法,因为这两个都是只能放在第一行,super是调用父类无参构造器,this是调用自己的无参构造器,如果这俩都不写,系统默认调用父类无参构造器,即super();
- 当父类手动添加了一个有参构造方法(比如person(int age){})后,原来系统默认自动生成的无参构造方法就没有了,这时子类的无参构造方法因为无法执行super();也会报错,除非将这句改为super(10);或者在写父类有参构造方法的时候,再手动添加一个无参构造方法
super和this的比较
- 代表的对象不同:this是本身调用者这个对象,super是代表父类对象的应用
- 前提不同:this没有继承也可以使用,super只能在继承后才能使用
- 构造方法不同:this();是本类的构造,super();是父类的构造
关于super和this的一个例子
假设有三个类,分别为父类Person,子类Student和测试类Test
- 父类Person代码为:
public class Person{
public String name = "人的名字";
public void print(){
System.out.println("人");
}
}
- 子类Student代码为:
public class Student extends Person{
public String name = "学生的名字";
public void print(){
System.out.println("学生");
}
public void method(){
print();
this.print();
super.print();
}
}
- 测试类Test代码为:
Student student = new Student();
student.method();
那么测试类的运行结果为:
学生
学生
人
解释:测试类实例化了Student类,调用了里面的method();方法,这个方法又调用了三个方法,第一个print();和第二个this.print();就是Student类里的print();方法,第三个super.print();是Person类里面的print();方法,所以运行结果如上。
方法的重写
- 重写需要有继承关系,子类重写父类的方法
- 重写都是指方法的重写,属性是没有重写这一说的
- 非私有的非静态方法才能重写,static静态方法无法重写
- 重写的方法,要求方法名相同;参数列表相同;修饰符的范围可以扩大不可以缩小(比如父类的方法是private,可以在子类重写时扩大为public,但是不能缩小);重写方法抛出的异常的范围可以被缩小不能被扩大
- alt+insert,选择override就是重写方法
两个例子说明重写和非重写
父类是static静态方法,子类无法对其重写:
- 父类B
public class B{
public static void method(){
System.out.println("B");
}
}
- 子类A
public class A extends B{
public static void method(){
System.out.println("A");
}
}
- 测试类
public class Test{
public static void main(String[] args){
//静态方法调用只和左边定义的数据类型有关
A a = new A();
a.method();
//父类的引用指向了子类
B b = new A();
b.method():
}
}
运行结果为:
A
B
当父类和子类去掉static后,运行结果为:
A
A