Java私塾跟我学系列――JAVA篇 第五章 Java高级类特性

 

教学目标:

i掌握Java中的继承

i掌握方法的覆盖

i掌握方法的重载

i掌握Java中的多态

i掌握staticfinal的特性和使用

i理解Java的内存分配


 

一、Java中的继承                                                     

1.extends关键字                                                                

前面我们已经学习过了什么是继承,那么在Java里面如何来表达继承的关系呢?就是使用extends关键字,比如:经理这个类继承雇员这个类,示例如下:

public class Employee {  //雇员

  String name;       //姓名

  Date hireDate;     //雇佣日期

  Date dateOfBirth;  //生日

  String jobTitle;   //职位

  int grade;

  //...

}

public class Manager extends Employee {

  String department;          //部门

  Employee[] subordinates;    //下属

  //...

}

在这样的定义中,Manager类被定义,具有 Employee 所拥有的所有变量及方法。所有这些变量和方法都是从父类的定义中继承来的。所有的程序员需要做的是定义额外特征或规定将适用的变化。

 

注意:这种方法是在维护和可靠性方面的一个伟大进步。如果在Employee类中进行修改,那么,Manager类就会自动修改,而不需要程序员做任何工作,除了对它进行编译。

 

2.初始化子类必先初始化父类                                                    

在Java编程语言中,对象的初始化是非常结构化的,这样做是为了保证安全。在前面的模块中,看到了当一个特定对象被创建时发生了什么。由于继承性,对象被完成,而且下述行为按顺序发生:

    (1)存储空间被分配并初始化到0值

    (2)进行显式初始化

    (3)调用构造方法

(4)层次中的每个类都会发生最后两个步骤,是从最上层开始。Java技术安全模式要求在子类执行任何东西之前,描述父类的一个对象的各个方面都必须初始化。因此,Java编程语言总是在执行子构造方法前调用父类构造方法的版本。

有继承的类在运行的时候,一定要记得:初始化子类必先初始化父类,这是Java程序的一个基本运行过程。比如:

1publicclass Child extends Parent{

2   private String name = "Java私塾";

3   privateint age = 2;

4   public Child(){

5      age = 1000; //期望能到1000年,呵呵

6   }

7   publicstaticvoid main(String[] args) {

8      Child t = new Child();   //创建子类的对象

9      System.out.println(t.name+"的年龄是"+t.age+"年");

10  }  

11}

12class Parent{

13  privateint num = 1;

14  public Parent(){

15     System.out.println("现在初始化父类");

16  }

17  publicvoid test(){

18     System.out.println("这是父类的test方法");

19  }

20}

 

上述类的基本运行顺序是:

(1) 先运行到第7行,这是程序的入口

(2) 然后运行到第8行,这里要new一个Child,就要调用Child的构造方法

(3) 就运行到第4行,注意:初始化子类必先初始化父类

(4) 要先初始化父类,所以运行到第14行

(5) 然后是第13行,初始化一个类,必须先初始化它的属性

(6) 然后是第15行

(7) 然后是第16行,表示父类初始化完成

(8) 然后是回到子类,开始初始化属性,因此运行到第2行,然后是第3行

(9) 子类属性初始化完过后,才回到子类的构造方法,执行里面的代码,也就是第5行

(10) 然后是第6行,表示new一个Child实例完成

(11) 然后回到main方法中执行第9行

(12) 然后是第10行

 

运行结果是:

现在初始化父类

Java私塾的年龄是1000年

 

3.单继承性                                                                     

单继承性:当一个类从一个唯一的类继承时,被称做单继承性。单继承性使代码更可靠。接口提供多继承性的好处,而且没有(多继承的)缺点。

Java编程语言允许一个类仅能继承一个其它类,即一个类只能有一个父类。这个限制被称做单继承性。单继承性与多继承性的优点是面向对象程序员之间广泛讨论的话题。Java编程语言加强了单继承性限制而使代码更为可靠,尽管这样有时会增加程序员的工作。后面会学到一个被叫做接口(interface)的语言特征,它允许多继承性的大部分好处,而不受其缺点的影响。

 

 

 

 

使用继承性的子类的一个例子如图所示:

 

 

 

 

 

 

 

 

 

 

 

 

 


 

4.构造方法不能被继承                                                            

    尽管一个子类从父类继承所有的方法和变量,但它不继承构造方法,掌握这一点很重要。

一个类能得到构造方法,只有两个办法。或者写构造方法,或者根本没有写构造方法,类有一个默认的构造方法。

 

5.关键字super                                                                  

关键字super可被用来引用该类的父类,它被用来引用父类的成员变量或方法。父类行为被调用,就好象该行为是本类的行为一样,而且调用行为不必发生在父类中,它能自动向上层类追溯。

 

super关键字的功能:

(1)点取父类中被子类隐藏了的数据成员

(2)点取已经覆盖了的方法

(3)作为方法名表示父类构造方法

例如:

public class Employee {

  private String name;

  private int salary;

public String getDetails() {

      return "Name: " + name + "\nSalary: " + salary;

  }

}

public class Manager extends Employee {

  private String department;

 

  public String getDetails() {

    return super.getDetails() + //调用父类的方法

                           "\nDepartment: " + department;

  }

}

请注意,super.method()格式的调用,如果对象已经具有父类类型,那么它的方法的整个行为都将被调用,也包括其所有负面效果。该方法不必在父类中定义,它也可以从某些祖先类中继承。也就是说可以从父类的父类去获取,具有追溯性,一直向上去找,直到找到为止,这是一个很重要的特点。

 

6.调用父类构造方法                                                                 

在许多情况下,使用默认构造方法来对父类对象进行初始化。

当然也可以使用super来显示调用父类的构造方法。

 

public class Employee {

  String name;

  public Employee(String name) {

    this.name = name;

  }

public class Manager extends Employee {

  String department;

  public Manager(String name, String department) {

    super(name);

    this.department = department;

  }

}

注意:无论是super(…)还是this(…),都必须放在构造方法的第一句。(所以不会同时出现在一个方法中的,也没有这个必要。)

通常要定义一个带参数的构造方法,并要使用这些参数来控制一个对象的父类部分的构造。可能通过从子类构造方法的第一行调用关键字super的手段调用一个特殊的父类构造方法作为子类初始化的一部分。要控制具体的构造方法的调用,必须给super()提供合适的参数。当不调用带参数的super时,缺省的父类构造方法(即,带0个参数的构造方法)被隐含地调用。在这种情况下,如果没有缺省的父类构造方法,将导致编译错误。

public class Employee {

  String name;

  public Employee(String name) {

    this.name = name;

  }

}

public class Manager extends Employee {

  String department;

  public Manager(String name, String department) {

    super(name); // 调用父类参数为String类型的构造方法

    this.department = department;

  }

}

当被使用时,super或this的方法调用必须被放在构造方法的第一句。显然,两者不能被放在一个单独行中,但这种情况事实上不是一个问题。如果写一个构造方法,它既没有调用super(…)也没有调用this(…),编译器自动插入一个调用到父类构造方法中,而不带参数。其它构造方法也能调用super(…)或this(…),调用一个static方法和构造方法的数据链。最终发生的是父类构造方法(可能几个)将在链中的任何子类构造方法前执行。

Java私塾跟我学系列——JAVA  网址:http://www.javass.cn  电话:010-68434236

你可能感兴趣的:(java,继承,职场,目标,休闲)