Java中组合、继承与代理之间的关系。
在Java中如何将一个已经定义好的类尽可能多的重复使用是提高开发效率和质量的关键。而下面我们要讲述的三种方式便是涉及到怎样去复用类让代码更优雅。
一、组合
定义:在新的类中产生现有类的对象。
组合的例子其实随处可见,比如说我们在类中定义一个String类型的变量时就使用了组合,因为String本身就是类。
public class FuUse {
/*
* 添加一个String类型的对象s
* */
private String s;
public FuUse(String s){
this.s = s;
}
}
二、继承
定义:通过extends关键字绑定子父类关系。
继承在这一层面来说,就是令子类继承父类所允许的(公共的或者受保护的)属性和方法。如果子类仅需要实现父类中所含的方法,那么对于子类来说在继承父类后就可以什么都不做了(子类是父类的扩展),如下面的代码:
/*
* 定义父类Father
* */
class Father{
public void fun1(){
System.out.println("fun1");
}
public void fun2(){
System.out.println("fun2");
}
public void fun3(){
System.out.println("fun3");
}
}
/*
* 定义子类Son
* 继承父类Father
* */
class Son extends Father{
/*
* 啥也不做
* */
}
public class FuUse {
public static void main(String[] args) {
Son son = new Son();
son.fun1();
son.fun2();
son.fun3();
}
}
/*
* output:
* fun1
* fun2
* fun3
* */
三、代理
定义:代理是组合和继承的中庸之道,即像组合那样在新类中定义了现有类的对象,又像继承那样拥有了现有类所有的可用方法。
可能有的人刚开始不理解,组合和代理不是一个道理吗?哪里来的区别?但是这两者确实有区别,只不过不像继承那样明显,让我们一起来看看。
/*
* 定义一个Tree类
* */
class Tree{
/*
* 定义树的浇水方法
* */
public void getWater(){
System.out.println("water");
}
/*
* 定义树的光照方法
* */
public void getSun(){
System.out.println("Sun");
}
/*
* 定义树的施肥方法
* */
public void getManure(){
System.out.println("Manure");
}
}
/*
*定义Flower类
*在Flower类中使用了代理
*/
class Flower{
private Tree tree = new Tree();
/*
* 定义花的浇水方法
* */
public void getWater(){
tree.getWater();
}
/*
* 定义花的光照方法
* */
public void getSun(){
tree.getSun();
}
/*
* 定义花的施肥方法
* */
public void getManure(){
tree.getManure();
}
}
通过查看上面的代码相信你也看出了端倪。没错,在组合中虽然也在新类中定义了现有类的对象,但是新类说到底并不能直接调用现有类的方法,还是得依靠现有类对象的引用来调用方法。
而在代理中我们虽然也是使用了现有类对象的引用,但是我们写出了新类的方法并封装了现有类所有的方法,就好像继承一样。我们可以通过调用新类自己的方法去执行现有类的方法,相当于在新类中代理了现有类的方法。