继承是面向对象的核心特征之一,是由已有类创建新类的机制。利用继承机制,可以先创建一个具有共性的一般类,然后根据该一般类创建具有特殊性的新类,新类继承一般类的属性和方法,并根据需要增加自己的新属性和方法。类的继承机制是面向对象程序设计中实现软件可重用性的重要手段。
由已有类定义新类,已有类称为父类或超类,新类称为子类或派生类。通过继承机制,子类拥有父类所有的成员变量和成员方法,子类中既可以定义新的属性和方法,也可以对父类中的成员变量和成员方法进行改进,使类的功能得以扩充。
1.继承的实现
①、子类的声明,eg:
public class Dog extends Animal{ private String color; //新加的属性 private String kinds; public void sleep(String color, String kinds){ System.out.println("颜色为:" + color + ",种类为:"+ kinds + "的狗正在睡觉!!!" ); //新加的方法 } }
如上面所示:Dog类继承Animal类,那么Animal即为父类,Dog类即为子类,Dog类也将拥有父类Animal的所有成员变量和方法。
②、继承的原则
Java语言中继承机制的原则如下:
A:Java是单继承的,一个类只能继承一个父类。
B:子类继承父类的实例变量和类变量(静态变量)。
C:子类继承父类除构造方法以外的实例成员和类方法(静态方法)。
D:子类不能继承父类的构造方法,因为父类的构造方法用来创建父类对象,子类需要声明自己的构造方法,用来创建自己的对象。
E:子类可以重新声明父类的成员。
③、子类对父类成员的访问权限
子类虽然继承了父类的成员变量和成员方法,但并不是对父类所有的成员变量和成员方法都具有访问权限,即并不是在自己声明的方法中都能够访问父类的所有成员变量或成员方法。Java中子类访问父类成员的权限如下:
A:子类对父类的private成员没有访问权限。子类方法中不能直接引用父类的private成员变量,不能直接调用父类的private方法,但可以通过父类非private成员方法访问父类的成员变量。
B:子类对父类的public和protected成员具有访问权限。
C:子类对父类的默认权限成员的访问权限分为两种情况:对于同一个包中的父类默认权限成员具有访问权限,对其他包中父类的默认权限成员没有访问权限。
类中成员的访问权限体现了类封装的信息隐藏原则,如果类中成员仅限于该类使用,则声明为private;如果类中成员允许子类使用,则声明为protected;如果类中成员允许所有类访问,则声明为public。
根据一个案例来理解继承,eg:
package extendsExample; /** * * @author JackW * */ public class Animal { //私有属性 private String type; private String breed; private String name; //构造方法 public Animal(String type, String breed, String name) { super(); this.type = type; this.breed = breed; this.name = name; } //自我介绍方法 public void introduce(){ System.out.println("主人好,我是" + this.type +",我的品种是" + this.breed + ",我的名字叫:" + this.name); } //叫声方法 public void sound(){ } }
package extendsExample; /** * * @author JackW * */ public class Cat extends Animal{ //子类构造函数 public Cat(String breed, String name){ //调用父类构造函数 super("猫", breed, name); } }
package extendsExample; /** * * @author JackW * */ public class Dog extends Animal{ //子类构造函数 public Dog(String breed, String name){ //调用父类构造函数 super("狗", breed, name); } }
package extendsExample; /** * * @author JackW * */ public class PetShop { public static void main(String[] args) { // TODO Auto-generated method stub Cat cat = new Cat("波斯猫", "花花"); //定义猫对象cat Dog dog = new Dog("金毛", "芋头"); //定义狗对象dog cat.introduce(); //猫调用自我介绍方法 dog.introduce(); //狗调用自我介绍方法 } }
从上面的代码可以看出,Animal为父类,Cat类和Dog类为子类,父类中定义所有子类公共的属性和方法,不需要每个子类都再次的写一遍。
说明:
A:main()方法中的猫类对象cat和狗类对象dog都可以调用introduce()方法,但是Cat类和Dog类都未定义introduce()方法,这是因为Cat类和Dog类从父类Animal类中继承introduce()方法。
B:super 是Java的关键字,表示调用父类成员;this也是Java的关键字,表示调用当前类的成员。
④、super 和 this 引用
子类可以使用super关键字引用父类的成员变量,成员方法及构造方法。
A:引用父类成员变量
eg:super.成员变量名;
当子类中没有申明与父类同名的成员变量时,引用父类的成员变量可以不使用super 关键字;但当子类中声明了与父类同名的成员变量时,为类引用父类的成员变量,必须使用super 关键字,否则引用的是子类中同名的成员变量。
B:调用父类成员方法
子类自动继承父类所有的成员方法,可以使用以下方式调用父类的成员方法:
eg:super.成员方法(参数列表);
当子类中没有声明与父类同名且参数列表也相同的成员方法时,调用父类的成员方法可以不使用super 关键字;当子类中声明了与父类同名且参数列表也相同的成员方法时,为了调用父类的成员方法,必须使用super 关键字,否则调用的是子类中同名且参数列表也相同的方法。
C:调用父类的构造方法
在子类构造方法中,可以通过super 关键字调用父类构造方法,其调用形式如下:
eg:super(参数列表);
此处的参数列表由父类方法的参数列表决定,并且super()必须是子类构造方法体中的首条语句。
⑤、继承中的构造函数调用次序
实例化子类对象时,先调用子类构造函数,在调用父类构造函数。父类构造函数对属性进行初始化后,子类再对子类属性进行初始化。
⑥、继承中的实例化
实例化子类对象时,先实例化父类对象,后实例化子类对象,也就是说,实例化子类对象时,父类对象也被实例化了。
2.Object 类
在Java中,java.lang.Object 类是所有类的父类,当一个类没有使用 extends 关键字显式继承其他类时,该类默认继承 Object 类,因此所有类都是 Object 类的子类,都具有 Object 类的方法和属性。