继承是面向对象编程的三大特性之一。首先观察如下代码:
Animal:
public class Animal {
public String name;
public Animal(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
}
Cat:
class Cat {
public String name;
public Cat(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
public void cute() {
System.out.println(this.name + "卖萌");
}
}
Bird:
class Bird {
public String name;
public Bird(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
public void fly() {
System.out.println(this.name + "正在飞 ");
}
可以看出代码中包含许多重复代码,1.三者都有eat的动作,且行为一样;2.都具备相同的属性值name;3.Cat与Bird都属于Animal;继承描述的就是这种事物间的从属关系。其中Animal称为父类,超类或基类,Cat,Bird等称为子类,派生类。
继承的格式如下:
class 父类 {
...
}
class 子类 extends 父类 {
...
}
可以将上述代码优化:
import java.lang.String;
class Animal {
public String name;
public Animal(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
}
class Cat extends Animal {
public Cat(String name) {
// 使用 super 调用父类的构造方法.下文会对其做出详细解释
super(name);
}
}
class Bird extends Animal {
public Bird(String name) {
super(name);
}
public void fly() {
System.out.println(this.name + "正在飞");
}
}
public class Test {
public static void main(String[] args) {
Cat cat = new Cat("猫");
cat.eat("鱼");
Bird bird = new Bird("鸟");
bird.fly();
}
}
继承后的特点:
成员变量:
当父类与子类中的成员变量名重名时,对访问会有影响,例如:
class Fu {
int num = 5;
}
class Zi extends Fu {
int num = 6;
public void show() {
System.out.println("Fu num=" + num); // 访问父类中的num
System.out.println("Zi num=" + num);// 访问子类中的num
}
}
class Demo {
public static void main(String[] args) {
Zi z = new Zi();
z.show();
}
}
此时访问结果为:
Fu num = 6 Zi num = 6
因此,子父类中出现了同名的成员变量时,在子类中需要访问父类中非私有成员变量时,需要使用 super关键字,修饰父类成员变量,类似this 。代码如下:
class Fu { // Fu中的成员变量。
int num = 5;
}
class Zi extends Fu { // Zi中的成员变量
int num = 6;
public void show() {
System.out.println("Fu num=" + super.num); // 访问父类中的num
System.out.println("Zi num=" + this.num);// 访问子类中的num
}
}
class Demo {
public static void main(String[] args) {
Zi z = new Zi();
z.show();
}
}
此时结果为:
Fu num = 5 Zi num = 6
成员方法:
当父类与子类中出现完全一样的方法时(方法名,返回值类型,参数列表都相同),此时子类方法会覆盖父类方法,这种情况称为方法的重写或复写。
class Fu {
public void show() {
System.out.println("Fu show");
}
}
class Zi extends Fu {
public void show() {
System.out.println("Zi show");
}
}
class Demo {
public static void main(String[] args) {
Zi z = new Zi();
//子类中重写了父类中的show()方法,此时只执行子类的show()方法
z.show();
}
}
注意:子类方法覆盖父类方法,必须保证权限大于等于父类方法。
构造方法:
1. 构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的。 2. 构造方法的作用是初始化成员变量的。所以子类的初始化过程中,必须先执行父类的初始化动作。子类的构造方法中默认有一个 super() ,表示调用父类的构造方法,父类成员变量初始化后,才可以给子类使用。class Fu {
Fu() {
System.out.println("Fu()");
}
}
class Zi extends Fu {
Zi() {
super();
System.out.println("Zi()");
}
}
public class Demo {
public static void main(String args[]) {
Zi zi = new Zi();
}
}
输出为:
Fu() Zi()
注意:Java只支持单继承(即一个子类只能继承一个父类),不支持多继承,但支持多层继承,例如:class A {}
class B extends A {}
class C extends B {}



