Java的继承机制

继承是定义了两个类之间的关系:一个类可以从另一个类继承属性和方法。

1. 对属性和方法的继承

  • 定义一个Animal类,任何一个Animal都有属性:年龄,此外Animal还有发出声音的方法makeNoise()
  • 再定义一个Cat类,显然 Cat是Animal的一种 ,所以Cat理所当然应该继承Animal的属性age和发出声音的方法makeNoise().

Java实现.

(1) 创建一个Animal类

Animal.java

package animal;

public class Animal {
	
	public int age = 10;
	
	public void makeNoise() {
		System.out.println("The animal is making noise!");
	}
	
}

(2) 创建一个Cat类,继承Animal类

package animal;

public class Cat extends Animal{

}
这里 extends Animal 表明了继承关系,extends是继承关系的关键词。

(3) 使用Cat类

我们创建一个Cat的对象,并尝试调用他的age属性和makeNoise()方法。

import animal.Cat;

public class AnimalExample {

	public static void main(String[] args) {
		
		Cat cat = new Cat();
		
		// 引用cat对象的age属性
		System.out.println("Age = " + cat.age);
		
		// 调用cat的makeNoise()方法
		cat.makeNoise();
	}

}

运行结果:

Age = 10
The animal is making noise!

这里我们注意到:

  • 我们在上述Cat类里并没有定义age属性和makeNoise()方法,所以可以确信:agemakeNoise()是从其超类Animal继承来的。

2. Terminology

上述例子中,Animal叫做Cat超类SuperclassCat叫做Animal子类Subclass

3. 子类可以有自己的属性和方法

子类除了可以从其超类继承属性和方法,还可以有自己独有的属性和方法。

下面我们给Cat添加上自己的属性:nameowner,并且添加一个自己的方法:interact(String str);

package animal;

public class Cat extends Animal {

    //Cat 自己的属性
	public String name = "";
	public String owner = "";

    // Cat 自己的方法
	public boolean interact(String str) {
		if ("food".equals(str)) { 
			return true;  // 给食物就回应true,表示开心
		} else {
			return false;	// 否则回应false,表示不开心
		}
	}

}

测试类:

AnimalExample.java

import animal.Cat;

public class AnimalExample {

	public static void main(String[] args) {
		
		Cat cat = new Cat();
        // 修改 cat 对象的属性,包括继承来的属性age
		cat.age = 3;
		cat.name = "Ame";
		cat.owner = "XU, Xiaoyan";
		
		// 引用cat对象的属性
		System.out.printf("Cat named '%s', aged '%d', is owned by '%s' \n", cat.name, cat.age, cat.owner);
		
		// 调用cat的makeNoise()方法
		cat.makeNoise();
		
		// 调用interact(String)方法
		boolean isHappy = cat.interact("food");
		if (isHappy) {
			System.out.println(cat.name + " is happy.");
		} else {
			System.out.println(cat.name + " is unhappy.");
		}
	}

}

运行结果

Cat named 'Ame', aged '3', is owned by 'XU, Xiaoyan'
The animal is making noise!
Ame is happy.

4. 子类可以重写继承来的方法

上面的运行结果并不完美,因为Cat应该有自己独特的发声方式,即makeNoise()方法。Java允许子类重写继承来的方法。

package animal;

public class Cat extends Animal {

    //Cat 自己的属性
	public String name = "";
	public String owner = "";

    // 重写继承来的makeNoise()方法
	@Override
	public void makeNoise() {
		System.out.println("Cat says: Meow Meow");
	}

    // Cat 自己的方法
	public boolean interact(String str) {
		if ("food".equals(str)) { 
			return true;  // 给食物就回应true,表示开心
		} else {
			return false;	// 否则回应false,表示不开心
		}
	}

}

注.

  • 这里使用Java注解(annotation) @Override强制要求我们重写继承来的方法(防止写错方法名、参数表、或返回类型)。不写@Override虽然不会出错,但是也会承担写错继承方法的风险。

再运行上面的AnimalExample.java,我们将得到如下结果:

Cat named 'Ame', aged '3', is owned by 'XU, Xiaoyan'
Cat says: Meow Meow
Ame is happy.

显然这里执行的是Cat重写后的makeNoise()方法.

5. 一个类只能有一个超类

下面的代码中,类A想要继承两个类B和C,是不可以的。

public class A extends B, C{
	// 报错,一个类不能继承两个超类
}