假设您先前已经撰写了一些2D绘图相关类别,现在您想要将之扩充为适用于3D绘图,3D的观念是2D的延伸,许多 2D绘图时所使用的功能都可以留下来加以扩充,在Java中您不用重写所有的类别,您可以「扩充」(extend)原先已定义好的类别,增加新的定义。
Java中使用"extends"作为其扩充父类别的关键词,其实就相当于我们一般所常称的继承(Inherit),只不过"extends"除了继承之外,还有将继承下来的类别予以新增定义的意思。
例如绘图中最基本的「点」类别,您原先已定义好一个Point2D类别,您继承它并将之扩充为Point3D类别,在扩充的关系中,称被扩充的类别为「父类别」(Parent class)或「基础类别」(Base class),而扩充父类别的类别就称之为「子类别」(Child class)或「衍生类别」(Derived class),在扩充时您使用"extends" 关键词,并指定要被扩充的类别。
直接使用一个实际例子来说明好了:
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;} }
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;} }
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成员的方法:
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;} }
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;} }
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()等方法。