您的位置:首页 > 编程语言 > Java开发

java中复用技术(继承和组合)

2013-08-05 14:40 579 查看
1.继承和组合的概念

在新类里简单地创建原有类的对象。我们把这种方法叫作“组合”,因为新类由现有类的对象合并而成。我们只是简单地重复利用代码的功能,而不是采用它的形式。

第二种方法是创建一个新类,将其作为现有类的一个“类型”。我们可以原样采取现有类的形式,并在其中加入新代码,同时不会对现有的类产生影响。这种魔术般的行为叫作“继承”(Inheritance),涉及的大多数工作都是由编译器完成的。对于面向对象的程序设计,“继承”是最重要的基础概念之一。对于组合和继承这两种方法,大多数语法和行为都是类似的(因为它们都要根据现有的类型生成新类型)。

2.组合也就是一个类的对象是另外一个类的成员,一般的程序都有组合的意味,只不过是基本数据类型是成员变量,下面请看具体的例子

class Head

{

Head(){

System.out.println(" head ");

}

}

class Body

{

Body(){

System.out.println(" body ");

}

}

class Person()

{

Head h=null;

Body b=null;

Person() //人是由头和身体组成的,Head和Body的对象是Person的一部分

{

h=new Head();

b =new Body();

}

}

3.继承作为面向对象的三个重要特性的一个方面,在面向对象的领域有着及其重要的作用,好像没听说哪个面向对象的语言不支持继承

class Person

{

private String name=null;

private int age=0;

public Person(String n,int a)

{

name=n;

age=a;

}

int getAge()

{

return age;

}

String getName()

{

return name;

}

void getDescription()

{

System.out.println("name: "+name+"/t"+"age: "+age);

}

}

class Student extends Person

{

private String studno=null;

public Student(String n,String no,int a)

{

super(n,a);

studno=no;

}

}

说明:Student类中有三个成员变量name,age,studno和一个方法getDescription();

注意:子类继承了父类的所有变量和函数,只是子类不能访问父类的private类型的变量和函数,其实privae类型的变量还是继承到子类中的

4.

无论还是继承,都允许我们将子对象置于自己的新类中。大家或许会奇怪两者间的差异,以及到底该如何选择。

如果想利用新类内部一个现有类的特性,而不想使用它的接口,通常应选择组合。也就是说,我们可嵌入一个对象,使自己能用它实现新类的特性。但新类的用户会看到我们已定义的接口,而不是来自嵌入对象的接口。考虑到这种效果,我们需在新类里嵌入现有类的private对象。

有些时候,我们想让类用户直接访问新类的组合。也就是说,需要将成员对象的属性变为public。成员对象会将自身隐藏起来,所以这是一种安全的做法。而且在用户知道我们准备合成一系列组件时,接口就更容易理解。car(汽车)对象便是一个很好的例子:

class Engine { public void start() {} public void rev() {} public void stop() {}}class Wheel { public void inflate(int psi) {}}class Window { public void rollup() {} public void rolldown() {}}class Door { public Window window = new Window(); public
void open() {} public void close() {}}public class Car { public Engine engine = new Engine(); public Wheel[] wheel = new Wheel[4]; public Door left = new Door(), right = new Door(); // 2-door Car() { for(int i = 0; i < 4; i++) wheel[i] =
new Wheel(); } public static void main(String[] args) { Car car = new Car(); car.left.window.rollup(); car.wheel[0].inflate(72); }} ///:~

由于汽车的装配是故障分析时需要考虑的一项因素(并非只是基础设计简单的一部分),所以有助于客户程序员理解如何使用类,而且类创建者的编程复杂程度也会大幅度降低。

如选择继承,就需要取得一个现成的类,并制作它的一个特殊版本。通常,这意味着我们准备使用一个常规用途的类,并根据特定的需求对其进行定制。只需稍加想象,就知道自己不能用一个车辆对象来组合一辆汽车——汽车并不“包含”车辆;相反,它“属于”车辆的一种类别。“属于”关系是用继承来表达的,而“包含”关系是用组合来表达的。

5. protected

现在我们已理解了继承的概念,protected这个关键字最后终于有了意义。在理想情况下,private成员随时都是“私有”的,任何人不得访问。但在实际应用中,经常想把某些东西深深地藏起来,但同时允许访问衍生类的成员。protected关键字可帮助我们做到这一点。它的意思是“它本身是私有的,但可由从这个类继承的任何东西或者同一个包内的其他任何东西访问”。也就是说,Java中的protected会成为进入“友好”状态。

我们采取的最好的做法是保持成员的private状态——无论如何都应保留对基 础的实施细节进行修改的权利。在这一前提下,可通过protected方法允许类的继承者进行受到控制的访问:

import java.util.*;class Villain { private int i; protected int read() { return i; } protected void set(int ii) { i = ii; } public Villain(int ii) { i = ii; } public int value(int m) { return m*i; }}public class Orc extends Villain { private int j; public
Orc(int jj) { super(jj); j = jj; } public void change(int x) { set(x); }} ///:~

可以看到,change()拥有对set()的访问权限,因为它的属性是protected(受到保护的)。

6. 再论合成与继承

在面向对象的程序设计中,创建和使用代码最可能采取的一种做法是:将数据和方法统一封装到一个类里,并且使用那个类的对象。有些时候,需通过“组合”技术用现成的类来构造新类。而继承是最少见的一种做法。因此,尽管继承在学习OOP的过程中得到了大量的强调,但并不意味着应该尽可能地到处使用它。相反,使用它时要特别慎重。只有在清楚知道继承在所有方法中最有效的前提下,才可考虑它。为判断自己到底应该选用组合还是继承,一个最简单的办法就是考虑是否需要从新类上溯造型回基础类。若必须上溯,就需要继承。但如果不需要上溯造型,就应提醒自己防止继承的滥用。但只要记住经常问自己“我真的需要上溯造型吗”,对于组合还是继承的选择就不应该是个太大的问题

class Rectangle//矩形类

{

private double x, y, height, width;//定义矩形的私有变量

Rectangle(){}//矩形类的构造函数

public double getX() {//得到矩形左上角的横坐标

return x;

}

public void setX(double x) {//设置矩形左上角的横坐标

this.x = x;

}

public double getY() {//得到矩形左上角的纵坐标

return y;

}

public void setY(double y) {//设置矩形左上角的纵坐标

this.y = y;

}

public double getHeight() {//得到矩形的高度

return height;

}

public void setHeight(double height) {//设置矩形的高度

this.height = height;

}

public double getWidth() {//得到矩形的宽度

return width;

}

public void setWidth(double width) {//设置矩形的宽度

this.width = width;

}

}

class Circle//圆类

{

private double x, y, radius;//定义圆类的私有变量

Circle(){}//圆类的构造函数

public double getX() {//得到圆心的横坐标

return x;

}

public void setX(double x) {//设置圆心的横坐标

this.x = x;

}

public double getY() {//得到圆心的纵坐标

return y;

}

public void setY(double y) {//设置圆心的纵坐标

this.y = y;

}

public double getRadius() {//得到圆的半径

return radius;

}

public void setRadius(double radius) {//设置圆的半径

this.radius = radius;

}

}

class Geometry//几何类

{

private Rectangle rect;//定义一个Rectangle类的对象作为自己的成员变量

private Circle circle;//定义一个Circle类的对象作为自己的成员变量

Geometry(Rectangle rect,Circle circle)//该类的构造函数

{

this.rect=rect;

this.circle=circle;

}

public void setRectangleposition(double x,double y)//设置矩形在坐标轴上的位置

{

rect.setX(x);

rect.setY(y);

}

public void setRectangleHeightAndWidth(double x,double y)//设置矩形的高度和宽度

{

rect.setHeight(x);

rect.setWidth(y);

}

public void setCircleposotion(double x, double y)//设置圆心在坐标轴上的位置

{

circle.setX(x);

circle.setY(y);

}

public void setCircleRadius(double radius)//设置圆的半径

{

circle.setRadius(radius);

}

public void show(Rectangle rect,Circle circle)//显示圆与矩形的位置

{

if(circle.getX()-rect.getX()>=rect.getWidth())//比较圆的X坐标和矩形左上角X坐标的大小,从而判断位置

{

System.out.println("圆在矩形的右边……");

}

else if(rect.getX()-circle.getX()>=circle.getRadius())

{

System.out.println("圆在矩形的左边……");

}

}

}

public class MainClass {

public static void main(String []args)//主函数

{

Rectangle rect1 = new Rectangle();//创建自己的对象

Circle circle1 = new Circle();

Geometry gmy = new Geometry(rect1,circle1);//初始化对象

gmy.setCircleposotion(150, 30);//设置圆心的位置

gmy.setCircleRadius(60);//设置圆的半径

gmy.setRectangleposition(30, 40);//设置矩形左上角的位置

gmy.setRectangleHeightAndWidth(120, 80);//设置矩形的高和宽

gmy.show(rect1, circle1);//显示圆和矩形的相对位置

}

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: