一、面向对象特征之二:继承性(inheritance)
1.继承性的好处
减少了代码的冗余,提高了代码的复用性
便于功能的扩展
为之后多态性的使用提供了前提
2.继承性的格式:class A extends B{}
A:子类、派生类、subclass
B:父类、超类、基类、superclass
2.1体现:一旦子类A继承父类B之后,子类A中就获取了父类B中声明的所有属性、方法
特别的,父类中声明为private的属性或方法,子类继承父类以后,仍然认为获取了父类中私有的结构。只有因为封装性的影响,使得子类不能直接调用父类的结构而已。
2.2子类继承父类以后,还可以声明自己特有的属性或方法,实现功能的拓展。
extends:延展、扩展
三、Java中关于继承性的规定
1.一个类可以被多个子类继承。
2.Java中类的单继承性:一个类只能有一个父类
3.子父类是相对的概念。
4.如果我们没有显式的声明一个类的父类,则此类继承于java.lang.Object类
所有的java类具有java.lang.Object类声明的功能
案例:在CylinderTest类中创建Cylinder类的对象,设置圆的底面半径和高,并输出圆柱的体积
Circle.java 文件
package Test;
public class Circle {
private double radius;//半径
//创建一个无参的构造器
public Circle(){
radius = 1.0;
}
//右键source,选择Generate Getter and Setters...生成get,set方法
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
}
Cylinder.java文件
package Test;
public class Cylinder extends Circle{
private double length;//高
public Cylinder(){
length = 1.0;
}
//获取get,set方法
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
//返回圆柱的体积
public double findVolume(){
return Math.PI * getRadius() * getRadius() * getLength();
//或者return findArea() * getLength();
}
}
CylinderTest 文件
package Test;
public class CylinderTest {
public static void main(String[] args) {
Cylinder cy = new Cylinder();
cy.setRadius(2.11);
cy.setLength(6.66);
double volume = cy.findVolume();
System.out.println("圆柱的体积为:" + volume);
double area = cy.findArea();
System.out.println("底面圆面积为:" + area);
}
}
四、Debug 操作
1.常用操作
2.图示
五、方法的重写
1.定义:
在子类中可以根据需要对从父类中继承来的方法进行改造,也称为方法的重置、覆盖。在程序执行时,子类的方法将覆盖父类的方法。
2.要求:
●子类重写的方法必须和父类被重写的方法具有相同的方法名称、参数列表
●子类重 写的方法的返回值类型不能大于父类被重写的方法的返回值类型
●子类重写的方法使 用的访问权限不能小于父类被重写的方法的访间权限
➢子类不能重写父类中声明为private权限的方法
➢父类被重写的方法返回值类型是void,则子类重写的方法返回值类型只能是void
➢父类被重写的方法返回值类型是A类,则子类重写的方法返回值类型是A类或A类的子类
➢父类被重写的方法返回值类型基本数据类型,则子类重写的方法返回值类型必须是相同的基本数据类型
●子类方法抛出的异常不能大于父类被重写方法的异常
3.注意:
子类与父类中同名同参数的方法必须同时声明为非static的(即为重写),或者同时声明为static的(不是重写)。因为static方法是属于类的,子类无法覆盖父类的方法。
案例
Person 文件
package Test2;
public class Person {
String name;
int age;
public Person(){
}
public Person(String name,int age){
this.name = name;
this.age = age;
}
public void eat(){
System.out.println("吃饭");
}
public void walk(int distance){
System.out.println("走路,走的距离是:"+ distance + "公里");
}
}
Student 文件
package Test2;
public class Student extends Person{
String major;
public Student(){
}
public Student(String major){
this.major = major;
}
public void study(){
System.out.println("学习,专业是:" + major);
}
//对父类中的方法进行重写override
public void eat(){
System.out.println("学生应该吃健康有营养的食物");
}
}
PersonTest 文件
package Test2;
public class PersonTest {
public static void main(String[] args) {
Student s = new Student("信息与计算科学");
s.eat();
s.walk(10);
s.study();
}
}
六、super 关键字
super 理解为:父类的
super 可以用来调用:属性、方法、构造器
1.super 调用属性或构造器。
➢我们可以在子类的方法或构造器中。通过使用 "super.属性" 或 "super.方法" 的方式,显示的调用父类中声明的属性或方法。通常情况下,我们习惯省略"super."
➢特殊情况:当子类和父类中定义了同名的属性时,我们想要在子类中调用父类中声明的属性,则必须显式的使用"super.属性"的方式,表明调用的是父类中声明的属性。
➢特殊情况:当子类重写了父类的方法以后,我们想要在子类的方法中调用父类中被重写的方法时,则必须显式的使用"super.方法"的方式,表明调用的是父类中被重写的方法。
2.super 调用构造器
➢我们可以在子类的构造器中显式的使用"super(形参列表)"的方式,调用父类中声明的指定的构造器
➢"super(形参列表)"的使用,必须声明在子类构造器的首行!
➢我们在类的构造器中,对于"this(形参列表)"或"super(形参列表)"只能二选一,不能同时出现。
➢在构造器的首行,没有显式的声明"this(形参列表)"或"super(形参列表)",则默认调用的是父类中空参的构造器:super()
➢在类的多个构造器中,至少有一个类的构造器是用了"super(形参列表)",调用父类中的构造器。
七、子类对象实例化的过程
1.从结果上看:
●子类继承父类以后,就获取了父类中声明的属性或方法。
●创建子类的对象,在堆空间中,就会加载所有父类中声明的属性
2.从过程上看
内存中有父类的结果,子类对象才可以考虑进行调用
明确
创建子类对象时,调用了父类的构造器,但自始至终只创建过一个对象,即为new的子类对象。