第八章 继承、抽象类和接口
类的继承可以使用已有的类为基础派生出新的类。通过类继承的方式,便能开发出新的类,而不需要编写相同的程序代码,所以说类的继承时程序代代码再利用 的概念。
8.1 类的继承
类的继承是面向对象的程序设计的一个重要特点,通过类的继承可以实现代码的复用,被继承 的类称为父类,继承的类称为子类。一个父类可以拥有多个子类。父类实际上是所有子类的一个公共的集合,每个子类则是对父类的特殊化,是对公共成员变量的方法、性能和内涵方面的扩展和延申。
8.1.1 子类的创建
Java语言中类的继承是通过extends关键字来实现的,在定义类时若使用extends关键字指出新定义类的父类,就是在两个类之间建立了继承关系。子类从父类那里继承所有非private的成员为自己的成员。
calss SubClass extends SuperClass
{
.
.
.
}
如果没有extends关键字,该类默认为java.lang.Object类的子类。因此,java语言的所有类都是通过直接或间接地继承java.lang.Object类得到的。所以在此之前的所有例子中的类均是java.lang.Object的子类。
子类的每个对象都是父类的对象,这是继承性”即是“的性质。反之,父类的对象不一定是子类的对对象。
1.子类的构建方法
//filename: App8_1.java class Person { private String name; private int age; public Person() { System.out.println("The individual class build method Person() is called "); } public void setNameAge(String name, int age) { this.name=name; this.age=age; } public void show() { System.out.println("name: "+name+"age: "+age); } } class Student extends Person { private String department; public Student() { System.out.println("the student class build method Student() is called"); } public void setDepartment(String dep) { department=dep; System.out.println("I am a "+department+"'s student."); } } public class App8_1 { public static void main(String[] args) { Student stu=new Student(); stu.setNameAge("zhang_xiaosan",21); stu.show(); stu.setDepartment("pharmacy"); } }
2.调用父类中特定的构造方法
如果父类中有多个构造方法,在子类中需要用super()来调用父类的方法。
//filename:App8_2.java class Person { private String name; private int age; public Person() { System.out.println("The no-argument constructor of the Person class is called"); } public Person(String name, int age) { System.out.println("The parameter constructor of the Person class is called"); this.name=name; this.age=age; } public void show() { System.out.println("name :"+name+" age :"+age); } } class Student extends Person { private String department; public Student() { System.out.println("The no-argument constructor of Student class is called"); } public Student(String name, int age, String dep) { super(name,age); department=dep; System.out.println("I am a "+" student of "+department); System.out.println("The parameter constructor of the Student class is called, which is Student(String name, int age, String dep)"); } } public class App8_2 { public static void main(String[] args) { Student stu1=new Student(); Student stu2=new Student("li_xiaosi",23,"medicine"); stu1.show(); stu2.show(); } }
注:调用父类的构造方法的super()语句必须写在子类构造方法的第一行,否则编译时将出现错误信息。
8.1.2 在子类中访问父类的成员
在子类中使用super不但可以访问父类的构造方法,还可以访问父类的成员变量和成员方法,但super不能访问在子类中添加的新成员。在子类中访问父类成员的格式如下:
super.变量名;
super.方法名;
另外,由于在子类中不能继承父类中的private成员,所以无法在子类(类外)中访问父类中的这种成员。但如果父类中的成员被声明为protected(保护成员),而非private成员,则protected成员不仅可以在父类中直接访问,同时也可以在子类中访问。
1.3 覆盖
覆盖(Overriding)的概念与方法的重载相似,它们均是Java”多态“的技巧之一。
覆盖指在子类中,定义名称、参数个数或类型均与父类完全相同的方法,用于实现重写父类中同名方法的功能。
1.覆盖父类的方法
父类中重新定义的父类已有的方法时,应保持与父类中完全相同的方法头声明,即应与父类中被覆盖的方法有完全相同的方法名、返回值类型和参数列表,否则就不是方法的覆盖,而是子类自己的与父类无关的方法。
注:子类中不能被覆盖的方法用final或static声明。
2.用父类的对象访问子类的成员
8.1.4 不可被继承的成员与最终类
在默认的情况下,所有的成员变量和成员方法都可以被覆盖,如果父类的成员不希望被子类覆盖可以将它们声明为final。final修饰的为最终变量,即常量,可以提高代码的安全性。