李浩荣的专栏

学习是件快乐的事情。每天下班路上想到比昨天进步了,那种幸福很美妙

java 继承

继承是面向对象编程技术的一块基石,因为它允许创建分等级层次的类。运用继承,你能够创建一个通用类,它定义了一系列相关项目的一般特性。该类可以被更具体的类继承,每个具体的类都增加一些自己特有的东西。

      在Java 术语学中,被继承的类叫超类(superclass ),继承超类的类叫子类(subclass )。因此,子类是超类的一个专门用途的版本,它继承了超类定义的所有实例变量和方法,并且为它自己增添了独特的元素。

     继承一个类,只要用extends 关键字把一个类的定义合并到另一个中就可以了。为了理解怎样继承,让我们从简短的程序开始。下面的例子创建了一个超类A和一个名为B的子类。注意怎样用关键字extends 来创建A的一个子类。


// A simple example of inheritance. 
// Create a superclass.
class A {
 int i, j; 
 void showij() {
   System.out.println("i and j: " + i + " " + j); 
  }
 } 
class B extends A {
  int k; 
  void showk() { 
     System.out.println("k: " + k);
  }
  void sum() { 
    System.out.println("i+j+k: " + (i+j+k));
  }
} 
class SimpleInheritance {
   public static void main(String args[]) { 
    A superOb = new A(); 
    B subOb = new B();
    System.out.println("Contents of superOb: "); 
    superOb.showij(); 
    System.out.println(); 
    subOb.i = 7; 
    subOb.j = 8;
    subOb.k = 9;
    System.out.println("Contents of subOb: ");
    subOb.showij();
    subOb.showk();
    System.out.println(); 
    System.out.println("Sum of i, j and k in subOb:"); 
    subOb.sum();
   }
} 
该程序的输出如下:

 

Contents of superOb:
i and j: 10 20

Contents of subOb:
i and j: 7 8
k: 9

Sum of i, j and k in subOb:
i+j+k: 24

       像你所看到的,子类B包括它的超类A中的所有成员。这是为什么subOb 可以获取i和j 以及调用showij( ) 方法的原因。同样,sum( ) 内部,i和j可以被直接引用,就像它们是B的一部分。

      尽管A是B的超类,它也是一个完全独立的类。作为一个子类的超类并不意味着超类不能被自己使用。而且,一个子类可以是另一个类的超类。声明一个继承超类的类的通常形式如下:

class subclass-name extends superclass-name {
     // body of class
}

      你只能给你所创建的每个子类定义一个超类。Java 不支持多超类的继承(这与C++ 不同,在C++中,你可以继承多个基础类)。你可以按照规定创建一个继承的层次。该层次中,一个子类成为另一个子类的超类。然而,没有类可以成为它自己的超类。

成员的访问和继承
      尽管子类包括超类的所有成员,它不能访问超类中被声明成private 的成员。例如,考虑下面简单的类层次结构:

/* In a class hierarchy, private members remain private to their class.

This program contains an error and will not compile.
*/

// Create a superclass.

 

class A {
  int i; 
  private int j; // private to A 
  void setij(int x, int y) {
     i = x; j = y; 
  }
} 
// A's j is not accessible here. class B extends A { int total; void sum() { total = i + j; // ERROR, j is not accessible here } }
class Access { public static void main(String args[]) { B subOb = new B(); subOb.setij(10, 12); subOb.sum(); System.out.println("Total is " + subOb.total); } }

该程序不会编译,因为B中sum( ) 方法内部对j的引用是不合法的。既然j被声明成private,它只能被它自己类中的其他成员访问。子类没权访问它。

注意:一个被定义成private 的类成员为此类私有,它不能被该类外的所有代码访问,包括子类。

更实际的例子
       让我们看一个更实际的例子,该例子有助于阐述继承的作用。新的类将包含一个盒子的宽度、高度、深度。

// This program uses inheritance to extend Box.

 

class Box { 
  double width; double height; double depth;
  // construct clone of an object 
  Box(Box ob) { // pass object to constructor
    width = ob.width;
    height = ob.height; 
    depth = ob.depth; 
  } 
  // constructor used when all dimensions specified 
  Box(double w, double h, double d) {
    width = w;
    height = h; 
    depth = d; 
  } 
  // constructor used when no dimensions specified 
   Box() {
    width = -1; // use -1 to indicate
    height = -1; // an uninitialized
     depth = -1; // box
   } 
  // constructor used when cube is created 
  Box(double len) {
     width = height = depth = len;
  }
  // compute and return volume double 
  volume() { 
    return width * height * depth; 
  }
 } 
 
 BoxWeight extends Box {
    double weight; // weight of box 
    // constructor for BoxWeight 
    BoxWeight(double w, double h, double d, double m) { 
      width = w; 
      height = h;
      depth = d; 
      weight = m; 
   }
 }
class DemoBoxWeight {
  public static void main(String args[]) { 
    BoxWeight mybox1 = new BoxWeight(10, 20, 15, 34.3);
    BoxWeight mybox2 = new BoxWeight(2, 3, 4, 0.076);
     double vol; 
     vol = mybox1.volume();
     System.out.println("Volume of mybox1 is " + vol); 
     System.out.println("Weight of mybox1 is " + mybox1.weight);
     System.out.println(); 
     vol = mybox2.volume();
     System.out.println("Volume of mybox2 is " + vol);
     System.out.println("Weight of mybox2 is " + mybox2.weight); 
   }
} 
 

 

该程序的输出显示如下:

Volume of mybox1 is 3000.0
Weight of mybox1 is 34.3

Volume of mybox2 is 24.0
Weight of mybox2 is 0.076

BoxWeight 继承了Box 的所有特征并为自己增添了一个weight 成员。没有必要让BoxWeight 重新创建Box 中的所有特征。为满足需要我们只要扩展Box就可以了。

继承的一个主要优势在于一旦你已经创建了一个超类,而该超类定义了适用于一组对象的属性,它可用来创建任何数量的说明更多细节的子类。每一个子类能够正好制作它自己的分类。例如,下面的类继承了Box并增加了一个颜色属性:

// Here, Box is extended to include color.
class ColorBox extends Box {
    int color; // color of box
    ColorBox(double w, double h, double d, int c) {
     width = w;
     height = h;
     depth = d;
      color = c;
   }
}

记住,一旦你已经创建了一个定义了对象一般属性的超类,该超类可以被继承以生成特殊用途的类。每一个子类只增添它自己独特的属性。这是继承的本质。

超类变量可以引用子类对象
     超类的一个引用变量可以被任何从该超类派生的子类的引用赋值。你将发现继承的这个方面在很多条件下是很有用的。例如,考虑下面的程序:

 

class RefDemo {
  public static void main(String args[]) { 
   BoxWeight weightbox = new BoxWeight(3, 5, 7, 8.37); 
   Box plainbox = new Box(); double vol; 
   vol = weightbox.volume();
   System.out.println("Volume of weightbox is " + vol); 
   System.out.println("Weight of weightbox is " + weightbox.weight); 
   System.out.println(); 
    // assign BoxWeight reference to Box reference 
   plainbox = weightbox; 
   vol = plainbox.volume(); // OK, volume() defined in Box 
   System.out.println("Volume of plainbox is " + vol); 
   /* The following statement is invalid because plainbox does not define a weight member. */ 
   // System.out.println("Weight of plainbox is " + plainbox.weight); 
  }
}
 

 

   这里,weightbox 是BoxWeight 对象的一个引用,plainbox 是Box对象的一个引用。既然BoxWeight 是Box的一个子类,允许用一个weightbox 对象的引用给plainbox 赋值。

    当一个子类对象的引用被赋给一个超类引用变量时,你只能访问超类定义的对象的那一部分。这是为什么plainbox 不能访问weight 的原因,甚至是它引用了一个BoxWeight 对象也不行。仔细想一想,这是有道理的,因为超类不知道子类增加的属性。这就是本程序中的最后一行被注释掉的原因。Box的引用访问weight 域是不可能的,因为它没有定义。

继承是面向对象编程技术的一块基石,因为它允许创建分等级层次的类。运用继承,你能够创建一个通用类,它定义了一系列相关项目的一般特性。该类可以被更具体的类继承,每个具体的类都增加一些自己特有的东西。

      在Java 术语学中,被继承的类叫超类(superclass ),继承超类的类叫子类(subclass )。因此,子类是超类的一个专门用途的版本,它继承了超类定义的所有实例变量和方法,并且为它自己增添了独特的元素。

     继承一个类,只要用extends 关键字把一个类的定义合并到另一个中就可以了。为了理解怎样继承,让我们从简短的程序开始。下面的例子创建了一个超类A和一个名为B的子类。注意怎样用关键字extends 来创建A的一个子类。


// A simple example of inheritance. 
// Create a superclass.
class A {
 int i, j; 
 void showij() {
   System.out.println("i and j: " + i + " " + j); 
  }
 } 
class B extends A {
  int k; 
  void showk() { 
     System.out.println("k: " + k);
  }
  void sum() { 
    System.out.println("i+j+k: " + (i+j+k));
  }
} 
class SimpleInheritance {
   public static void main(String args[]) { 
    A superOb = new A(); 
    B subOb = new B();
    System.out.println("Contents of superOb: "); 
    superOb.showij(); 
    System.out.println(); 
    subOb.i = 7; 
    subOb.j = 8;
    subOb.k = 9;
    System.out.println("Contents of subOb: ");
    subOb.showij();
    subOb.showk();
    System.out.println(); 
    System.out.println("Sum of i, j and k in subOb:"); 
    subOb.sum();
   }
} 

该程序的输出如下:

 

Contents of superOb:
i and j: 10 20

Contents of subOb:
i and j: 7 8
k: 9

Sum of i, j and k in subOb:
i+j+k: 24

       像你所看到的,子类B包括它的超类A中的所有成员。这是为什么subOb 可以获取i和j 以及调用showij( ) 方法的原因。同样,sum( ) 内部,i和j可以被直接引用,就像它们是B的一部分。

      尽管A是B的超类,它也是一个完全独立的类。作为一个子类的超类并不意味着超类不能被自己使用。而且,一个子类可以是另一个类的超类。声明一个继承超类的类的通常形式如下:

class subclass-name extends superclass-name {
     // body of class
}

      你只能给你所创建的每个子类定义一个超类。Java 不支持多超类的继承(这与C++ 不同,在C++中,你可以继承多个基础类)。你可以按照规定创建一个继承的层次。该层次中,一个子类成为另一个子类的超类。然而,没有类可以成为它自己的超类。

成员的访问和继承
      尽管子类包括超类的所有成员,它不能访问超类中被声明成private 的成员。例如,考虑下面简单的类层次结构:

/* In a class hierarchy, private members remain private to their class.

This program contains an error and will not compile.
*/

// Create a superclass.

 

class A {
  int i; 
  private int j; // private to A 
  void setij(int x, int y) {
     i = x; j = y; 
  }
} 
// A's j is not accessible here. class B extends A { int total; void sum() { total = i + j; // ERROR, j is not accessible here } }
class Access { public static void main(String args[]) { B subOb = new B(); subOb.setij(10, 12); subOb.sum(); System.out.println("Total is " + subOb.total); } }

该程序不会编译,因为B中sum( ) 方法内部对j的引用是不合法的。既然j被声明成private,它只能被它自己类中的其他成员访问。子类没权访问它。

注意:一个被定义成private 的类成员为此类私有,它不能被该类外的所有代码访问,包括子类。

更实际的例子
       让我们看一个更实际的例子,该例子有助于阐述继承的作用。新的类将包含一个盒子的宽度、高度、深度。

// This program uses inheritance to extend Box.

 

class Box { 
  double width; double height; double depth;
  // construct clone of an object 
  Box(Box ob) { // pass object to constructor
    width = ob.width;
    height = ob.height; 
    depth = ob.depth; 
  } 
  // constructor used when all dimensions specified 
  Box(double w, double h, double d) {
    width = w;
    height = h; 
    depth = d; 
  } 
  // constructor used when no dimensions specified 
   Box() {
    width = -1; // use -1 to indicate
    height = -1; // an uninitialized
     depth = -1; // box
   } 
  // constructor used when cube is created 
  Box(double len) {
     width = height = depth = len;
  }
  // compute and return volume double 
  volume() { 
    return width * height * depth; 
  }
 } 
 
 BoxWeight extends Box {
    double weight; // weight of box 
    // constructor for BoxWeight 
    BoxWeight(double w, double h, double d, double m) { 
      width = w; 
      height = h;
      depth = d; 
      weight = m; 
   }
 }
class DemoBoxWeight {
  public static void main(String args[]) { 
    BoxWeight mybox1 = new BoxWeight(10, 20, 15, 34.3);
    BoxWeight mybox2 = new BoxWeight(2, 3, 4, 0.076);
     double vol; 
     vol = mybox1.volume();
     System.out.println("Volume of mybox1 is " + vol); 
     System.out.println("Weight of mybox1 is " + mybox1.weight);
     System.out.println(); 
     vol = mybox2.volume();
     System.out.println("Volume of mybox2 is " + vol);
     System.out.println("Weight of mybox2 is " + mybox2.weight); 
   }
} 

 

 

该程序的输出显示如下:

Volume of mybox1 is 3000.0
Weight of mybox1 is 34.3

Volume of mybox2 is 24.0
Weight of mybox2 is 0.076

BoxWeight 继承了Box 的所有特征并为自己增添了一个weight 成员。没有必要让BoxWeight 重新创建Box 中的所有特征。为满足需要我们只要扩展Box就可以了。

继承的一个主要优势在于一旦你已经创建了一个超类,而该超类定义了适用于一组对象的属性,它可用来创建任何数量的说明更多细节的子类。每一个子类能够正好制作它自己的分类。例如,下面的类继承了Box并增加了一个颜色属性:

// Here, Box is extended to include color.
class ColorBox extends Box {
    int color; // color of box
    ColorBox(double w, double h, double d, int c) {
     width = w;
     height = h;
     depth = d;
      color = c;
   }
}

记住,一旦你已经创建了一个定义了对象一般属性的超类,该超类可以被继承以生成特殊用途的类。每一个子类只增添它自己独特的属性。这是继承的本质。

超类变量可以引用子类对象
     超类的一个引用变量可以被任何从该超类派生的子类的引用赋值。你将发现继承的这个方面在很多条件下是很有用的。例如,考虑下面的程序:

 

class RefDemo {
  public static void main(String args[]) { 
   BoxWeight weightbox = new BoxWeight(3, 5, 7, 8.37); 
   Box plainbox = new Box(); double vol; 
   vol = weightbox.volume();
   System.out.println("Volume of weightbox is " + vol); 
   System.out.println("Weight of weightbox is " + weightbox.weight); 
   System.out.println(); 
    // assign BoxWeight reference to Box reference 
   plainbox = weightbox; 
   vol = plainbox.volume(); // OK, volume() defined in Box 
   System.out.println("Volume of plainbox is " + vol); 
   /* The following statement is invalid because plainbox does not define a weight member. */ 
   // System.out.println("Weight of plainbox is " + plainbox.weight); 
  }
}

 

 

   这里,weightbox 是BoxWeight 对象的一个引用,plainbox 是Box对象的一个引用。既然BoxWeight 是Box的一个子类,允许用一个weightbox 对象的引用给plainbox 赋值。

    当一个子类对象的引用被赋给一个超类引用变量时,你只能访问超类定义的对象的那一部分。这是为什么plainbox 不能访问weight 的原因,甚至是它引用了一个BoxWeight 对象也不行。仔细想一想,这是有道理的,因为超类不知道子类增加的属性。这就是本程序中的最后一行被注释掉的原因。Box的引用访问weight 域是不可能的,因为它没有定义。

阅读更多
个人分类: JAVA
上一篇Tree控件的方法
下一篇JAVA适配器的作用
想对作者说点什么? 我来说一句

java 继承泛型类示例

2010年06月21日 59KB 下载

java 面向对象 继承 PDF格式

2010年07月22日 304KB 下载

java 继承非泛型类示例

2010年06月21日 59KB 下载

继承和多态的相关Java源码下载

2010年08月06日 25KB 下载

JAVA中的继承学习总结

2009年12月15日 181KB 下载

没有更多推荐了,返回首页

关闭
关闭