继承性
-
子类(也称为派生类)继承父类(也称为基类),子类就获取到了父类中声明的所有属性和方法(构造方法不能继承,只能在子类构造方法第一行调用父类的构造方法)。但是由于封装性的影响,可能子类不能直接调用父类中的属性和方法(如父类中声明为private)。继承提高了代码的复用性
-
子类继承父类后,可以扩展自己的属性和方法。继承的出现更有利于功能的扩展
-
子类继承父类后,还可以重写方法,也叫方法的覆盖,覆盖是指派生类中存在重新定义的函数,其与父类中的某个函数(函数名、参数列表、返回值类型)都相同,那么当派生类对象调用该函数时,会自动调用子类中的覆盖版本。不过要注意:实现方法覆盖时,子类方法不能比父类的方法权限小,子类方法抛出的异常不能比父类多。注意方法覆盖与方法重载的不同
super 关键字
结论:
-
Java构造器不是函数,所以不能被继承,只能在子类构造方法第一行通过使用super来调用父类的构造方法。
-
如果父类中有显式无参构造函数或者默认无参构造函数时,子类中的构造函数的方法体中会默认调用父类无参构造函数。当然,以上情况下我们也可以自行在子类构造函数中通过super()来显式调用父类无参构造函数或通过super(参数)来显式调用父类有参构造函数。但是,当父类中仅有有参构造函数时,那么子类构造函数中必须由我们手动通过super(参数)来显式调用,否则运行时会报错。
以下由两段代码用于解释:
😄
//父类
public class Person {
public String name;
public Person(){
System.out.println("Person222");
}
public Person(int a){
System.out.println("Person333");
}
}
//测试
public class Main {
public static void main(String[] args) {
Student s1=new Student(110);
System.out.println(s1.sid);
}
}
//子类1如下,测试结果为Person222以及110
public class Student extends Person{
public int sid;
public Student(int n){
super();//根据上述解释,这里不写的话也会默认调用,输出结果一样
this.sid=n;
}
}
//子类2如下,测试结果为Person333以及110
public class Student extends Person{
public int sid;
public Student(int n){
super(n);//根据上述解释,这里可以显示调用父类有参构造函数
this.sid=n;
}
}
😄
//父类
public class Person {
public String name;
public Person(int a){
System.out.println("Person333");
}
}
//测试
public class Main {
public static void main(String[] args) {
Student s1=new Student(110);
System.out.println(s1.sid);
}
}
//子类如下:测试结果为Person333以及110
public class Student extends Person{
public int sid;
public Student(int n){
super(n);//根据上述解释,由于父类中仅有有参构造函数,所以这里必须显示调用父类有参构造函数,否则出错
this.sid=n;
}
}
方法覆盖-向上转型
结论:
- 实例变量、静态变量、静态方法在编译期间就已经静态绑定了,而普通方法实行的是动态绑定。当调用参数或方法时,参数和静态方法会根据当前声明的类型去调用声明对象对应的成员,而普通方法会根据实际创建的对象类型去调用相应的方法。
- 父类引用指向子类对象,上转型,父类引用无法对子类新增成员变量和新增方法进行操作和使用。
以下代码用于解释:
😄
//父类
public class Person {
String name="fathername";
static String sex="staticfathersex";
public void say(){
System.out.println("fathersay");
}
public static void staticsay(){
System.out.println("staticfathersay");
}
}
//子类
public class Student extends Person{
String name="sonname";
static String sex="staticsonsex";
public void say(){
System.out.println("sonsay");
}
public static void staticsay(){
System.out.println("staticsonsay");
}
String age="11岁";
public void getAge(){
System.out.println("刚满11岁");
}
}
//测试,由上述解释可得以下测试结果
public static void main(String[] args) {
Person s1=new Student();//父类引用指向子类
System.out.println(s1.name);//fathername
System.out.println(s1.sex);//staticfathersex
s1.staticsay();//staticfathersay
s1.say();//sonsay
System.out.println(s1.age);//报错
s1.getAge();//报错
}
小tips:
-
Java中声明的所有类,如果没有显式地声明其父类是,默认继承了Object类。
-
Java支持多层继承,但不支持多重继承。
-
继承的本质是对一批类的进一步抽象。