在上一节我们说封装的时候,曾提到继承的概念。继承是代码复用的一种形式,即在具体包含关系的类中,从属类继承主类的全部属性和方法,从而减少代码冗余,提高程序的运行效率。有一句谚语是这样说的,“龙生龙,凤生凤,老鼠的儿子会打洞”,这里可以理解为老鼠的儿子继承了其父打洞的行为能力。
类的继承是通过扩展其他类而形成新类来实现的,原来的类称为父类(或基类),新类称为原来类的子类(或派生类),类的继承并不会改变成员的访问权限。上一节中我们提到的DogClaz类就是Husky类的父类,而Husky类就是DogClaz的子类。
/**
* 公共狗类
* @author ohayoi
*/
public class DogClaz {
private String name;//种类
private String color;//毛色
private double weight;//体重
private double height;//身高
/**
* 构造函数,用于构建特定属性的狗种类
* 可以根据需要的不同属性来设定构造函数,
* 若不重写构造函数,则使用默认不带参数的构造函数
* @param name
* @param age
* @param color
* @param weight
* @param height
*/
public DogClaz(String name) {
super();
this.name = name;
}
public DogClaz(String name, String color, double weight, double height) {
super();
this.name = name;
this.color = color;
this.weight = weight;
this.height = height;
}
public void sleep() {
System.out.println("我来自" + getName() + "家族,我已经睡着了~");
}
public void jump() {
System.out.println("我来自" + getName() + "家族,我能够跳很高~");
}
public void weight() {
System.out.println("我来自" + getName() + "家族,最近吃的有点多,该减肥了~");
}
/*
* getter & setter
* getter 对外接口,用户获取相关属性设置
* setter 对外接口,用户设置相关属性
*/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
}
/**
* 哈士奇
* @author ohayoi
*/
public class Husky extends DogClaz{
private int age;//年龄
/**
* 重写父类构造函数,设置具体的狗类,加入年龄
* @param name
* @param age
*/
public Husky(String name, int age) {
super(name);
this.age = age;
}
@Override
public void sleep() {
System.out.println("我是" + getName() + ",我已经睡着了~");
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
在Java编程中,我们使用extends
关键字来建立继承关系,而且仅支持单继承,即只允许一个类直接继承另一个类,也可以理解为子类只能有一个父类。
由于子类不能继承父类的构造方法,因此要调用父类的构造方法,必须在子类的构造方法体的第一行使用super()
方法。该方法会调用父类相应的构造方法来完成子类对象的初始化工作。
在子类中我们对父类的sleep()方法进行了重写。方法重写即子类中如果创建一个与父类中相同名称、相同返回值类型、相同参数列表的方法,知识方法体中的实现不同,此方式被称为方法重写,又称方法覆盖。