目录
一、什么是继承
在代码的编写中,当类的部分内容高度重合的时候,重复的书写会显得臃肿,例如,对于老师和学生的体测成绩,重合的指标有身高,体重,年龄,老师有学工号,学生有学号和年级,那么学生的类可以按照如下方式定义:
public class Student { public int age; public double weight; public double height; public String name; public String studentID; public int grade;
}老师则按照以下方式定义:
public class Teacher { public int age; public double weight; public double height; public String name; public String employeeID;
}但这样我们发现,age,weight,height,name的字段是重复的,因此我们想到能不能提取出来这两个类的普遍特征,提取成一个全新的类,并且让老师和学生这两个类都能够使用这个类的特征。
这种提取共性,实现代码复用的手段在Java中通过“继承”来实现,具体实现为:创建一个新的类,这个类承载原有类的共性,然后在原来的类中用extends继承属性。我们把被继承的类成为父类,继承的类成为子类。
代码如下:
public class Person { public int age; public double weight; public double height; public String name;}public class Student extends Person{ public String studentID; public int grade;
}public class Teacher extends Person{ public String employeeID;
}这样就简洁多了。
“继承”的作用就体现出来了:提取共性,实现代码的复用。反过来,还可以对原有的类进行拓展,增加新功能。
二、如何实现对父类的调用
(一)成员变量
1.不存在重名变量
此时父类的成员变量可以直接访问。
我们对Person类的age定义初始值为114514,并通过以下Main类运行测试。
public class Main { public static void main(String[] args) { Student stu = new Student(); Teacher tea = new Teacher(); System.out.println(stu.age); System.out.println(tea.age); }}
/**>>>114514114514*/这是可以正常运行的,此时当作这些成员变量就在子类中即可。
2.存在重名变量
如果Student类和Person类都有成员变量age,并且在Person中定义为114514,在Student中定义为18,stu.age又会输出什么结果呢?
结果是18。
我们可以得到以下规律,当在子类中访问成员时:
当子类和父类都含有该成员时,子类会优先访问自己的成员变量。
当子类没有该成员,则会访问父类,如果父类也没有则报错。
(二)成员方法
子类同样可以访问父类的方法,也分为不重名和重名两种情况:
1.不存在重名方法
直接访问即可:
我们此时对Person函数作以下修改:
public class Person { public int age = 114514; public double weight = 42; public double height = 158; public String name = "Miku"; @Override public String toString() { return "Person{" + "age=" + age + ", weight=" + weight + ", height=" + height + ", name='" + name + '\'' + '}'; }
}并用Main类运行:
public class Main { public static void main(String[] args) { Student stu = new Student(); Teacher tea = new Teacher(); System.out.println(stu.toString()); System.out.println(tea.toString());
}}/**>>>Person{age=114514, weight=0.0, height=0.0, name='null'}Person{age=114514, weight=0.0, height=0.0, name='null'}*/2.存在重名方法
我们对Person、Student、Main方法的定义如下:
public class Person { public int age = 114514; public double weight = 42; public double height = 158; public String name = "Miku"; @Override public String toString() { return "Person{" + "age=" + age + ", weight=" + weight + ", height=" + height + ", name='" + name + '\'' + '}'; }
public void show(int a) { System.out.println(a); }}public class Student extends Person{ public int age = 18; public String studentID; public int grade;
@Override public String toString() { return "Student{" + "age=" + age + ", studentID='" + studentID + '\'' + ", grade=" + grade + '}'; }
public void show() { System.out.println("您的学号是:" + studentID); }
}public class Main { public static void main(String[] args) { Student stu = new Student(); System.out.println(stu.toString()); stu.show(); stu.show(1); }}/*>>>Student{age=18, studentID='null', grade=0}您的学号是:null1*/访问成员方法的方式如下:
1.优先在子类找,找到则运行,找不到去父类找,找不到则报错。
2.若方法同名,但是函数参数列表不同,即重载,则在查找参数列表对应的函数运行。
(三)super关键字
重名情况访问父类成员
如果重名之后还是想要访问父类成员怎么办?可以用super关键字。
public class Student extends Person{ public int age = 18; public String studentID; public int grade;
@Override public String toString() { return "Student{" + "age=" + age + ", studentID='" + studentID + '\'' + ", grade=" + grade + '}'; } //使用super关键字访问父类重名成员 public String method() { System.out.println(super.age); return super.toString(); } public void show() { System.out.println("您的学号是:" + studentID); }
}
public class Main { public static void main(String[] args) { Student stu = new Student(); System.out.println(stu.method()); }}
/**>>>114514Person{age=114514, weight=42.0, height=158.0, name='Miku'}*/但需要注意的是:
1.super关键字必须在非静态方法下使用;
2.只能在子类方法中用于访问父类成员(换而言之在别的类中实例化对象然后stu.super.toString()是不可行的)
下一节讲继承的构造和代码块运行顺序。
部分信息可能已经过时











