大可制作:QQ群:31564239(asp|jsp|php|mysql)

Java Gossip: 继承(extends)父类

假设您先前已经撰写了一些2D绘图相关类,现在您想要将之继承为适用于3D绘图,3D的观念是2D的延伸,许多 2D绘图时所使用的功能都可以留下来加以继承,在Java中您不用重写所有的类,您可以“继承”(extend)原先已定义好的类,增加新的定义。

Java中使用"extends"作为其继承父类的关键字,其实就相当于我们一般所常称的继承(Inherit),只不过"extends"除了继承之外,还有将继承下来的类予以新增定义的意思。

例如绘图中最基本的“点”类,您原先已定义好一个Point2D类,您继承它并将之继承为Point3D类,在继承的关系中,称被继承的类为“父类”(Parent class)“基础类”(Base class),而继承父类的类就称之为“子类”(Child class)“衍生类”(Derived class),在继承时您使用"extends" 关键字,并指定要被继承的类。

直接使用一个实际例子来说明好了:

  • Point2D.java
public class Point2D { 
private int x, y;

public Point2D() {}
public Point2D(int x, int y) {this.x = x; this.y = y;}
public int getX() {return x;}
public int getY() {return y;}
}
  • Point3D.java
public class Point3D extends Point2D { // 继承Point2D类 
private int z; // 新增私用数据

public Point3D() {
super();
}

// 构造函数,同时指定调用父类构造函数
Point3D(int x, int y, int z) {
super(x, y);
this.z = z;
}

// 新增函数
public int getZ() {return z;}
}
  • UseExtend.java
public class UseExtend { 
public static void main(String[] args) {
Point3D p1 = new Point3D(1, 3, 4);
Point3D p2 = new Point3D();

System.out.printf("p1: (%d, %d, %d) \n",
p1.getX(), p1.getY(), p1.getZ());
System.out.printf("p2: (%d, %d, %d) \n",
p2.getX(), p2.getY(), p2.getZ());
}
}

执行结果:
p1: (1, 3, 4)
p2: (0, 0, 0) 


当您继承某个类时,该类的所有public成员都可以在衍生类中被调用使用,而private成员则不可以直接在衍生类中被调用使用;在这个例子 中,Point2D中已经有x, y两个成员,您新增z成员,而方法上您新增一个public的getZ()方法,而getX()与getY()直接继承父类中已定义的内容。

在继承某个类之后,您可以一并初始父类的构造方法,以完成相对应的初始动作,这可以使用super()方法来达到,它表示调用基底类的构造方法。

父类的public成员可以直接在衍生类中使用,而private成员则不行,private类只限于定义它的类来存取,如果想要与父类的 private成员沟通,就只能透过父类中继承下来的public函数成员,例如上例中的getX()与getY()方法。

下面这个程序是另一个示范存取父类private成员的方法:

  • Point2D.java
public class Point2D { 
private int x, y;

public Point2D() {x = 0; y = 0;}
public Point2D(int x, int y) {this.x = x; this.y = y;}
public int getX() {return x;}
public int getY() {return y;}
public void setX(int x) {this.x = x;}
public void setY(int y) {this.y = y;}
}
  • Point3D.java
public class Point3D extends Point2D { // 继承Point2D类 
private int z; // 新增私用数据

public Point3D() {
z = 0;
}

// 构造函数,同时指定调用父类构造函数
Point3D(int x, int y, int z) {
super(x, y);
this.z = z;
}

// 新增函数
public int getZ() {return z;};
public void setZ(int z) {this.z = z;}
}
  • UseExtend.java
public class UseExtend { 
public static void main(String[] args) {
Point3D p1 = new Point3D(1, 3, 4);
Point3D p2 = new Point3D();

System.out.printf("p1: (%d, %d, %d) \n",
p1.getX(), p1.getY(), p1.getZ());

p2.setX(2);
p2.setY(4);
p2.setZ(6);
System.out.printf("p2: (%d, %d, %d) \n",
p2.getX(), p2.getY(), p2.getZ());
}
}

执行结果:
p1: (1, 3, 4)
p2: (2, 4, 6)


父类的private成员并非无法在衍生类中使用,而是必须看父类本身是否提供有可继承使用的管道来存取它们,就如同上例中的public成员 getX()、setX()等方法。