其实实现的两种方法就是java中经常听到的——组合和继承。
(1)组合
has-a的作用。
1 public class TV {
2 Show show;
3 public String toString(){
4 return "showgirl";
5 }
6 }
7
8 class Show{
9 }
View Code
提一下toString方法,当你需要String而你是一个对象的时候,编译器会调用对象的toString方法。
TV里有Show,现在的show没有初始化,为null,不能调用show的方法。
组合的作用强大,以面向对象看,假如你在造一个Car类,那么你可以用组合轻易的将Glass,Light,Engine等等的Car这些部件组合起来。
(2)继承
is-a
1 package com.myown.iaiti;
2
3 public class Father {
4 public int i;
5 void get(){
6 System.out.println("father");
7 }
8 }
9
10 package son;
11 import com.myown.iaiti.*;
12
13 public class Son extends Father{
14 Father f = new Father();
15 int j = f.i;
16 Son son = new Son();
17 son.get();
18 }
19
20 public void get(){
21 super.get();
22 System.out.println("son");
23 }
24 }
25
View Code
这里有个包访问权限的问题,假如没有加public的时候,默认是包内成员访问,不同包访问,即Son中的Father成员访问get方法是不可见的。而public的话是可见的,所以i访问得到。
private部分是不能继承,属于父类私有,而public的部分,将继承,需要修改的方法,可以进行重写。要添加的属性可以单独添加。
而且继承的方法,如果原本的father的public方法重写之后没将public加上,会有Cannot reduce the visibility of the inherited method from Father,也就是不能减少父类中继承方法的可见性。super指的是父类,即Father。
还有一点是,其实java中所有的类都隐式地继承了Object类。Object是父类,其他类是子类
老外喜欢讲为基类。子类也叫导出类或者派生类。
(3)代理
设计模式里面有个比较难懂的——代理模式,作者讲的很有趣,代理是组合和继承的中庸之道。
1 package son;
2 class Father{
3 public void get(){
4 System.out.println("father");
5 }
6 }
7 public class Son extends Father{
8 public static void main(String[] args) {
9 Father f = new Father();
10 f.get();
11 }
12 }
13
14 class FatherProxy{
15 private Father f = new Father();
16 public void get(){
17 f.get();
18 }
19 }
View Code
像直接把Father当做成员,那么father的方法就暴露给这个类了,那我们可以使用FatherProxy这样的代理类,我自己定义好get方法是怎么拿的,我自己知道是调用father的get方法,但是使用我这个代理的人不知道,我只告诉他你要用就用代理的get的方法就可以了。封装性就体现出来了。上面只是随便敲的一个简单例子。
(4)对比
组 合 关 系 | 继 承 关 系 |
优点:不破坏封装,整体类与局部类之间松耦合,彼此相对独立 | 缺点:破坏封装,子类与父类之间紧密耦合,子类依赖于父类的实现,子类缺乏独立性 |
优点:具有较好的可扩展性 | 缺点:支持扩展,但是往往以增加系统结构的复杂度为代价 |
优点:支持动态组合。在运行时,整体对象可以选择不同类型的局部对象 | 缺点:不支持动态继承。在运行时,子类无法选择不同的父类 |
优点:整体类可以对局部类进行包装,封装局部类的接口,提供新的接口 | 缺点:子类不能改变父类的接口 |
缺点:整体类不能自动获得和局部类同样的接口 | 优点:子类能自动继承父类的接口 |
缺点:创建整体类的对象时,需要创建所有局部类的对象 | 优点:创建子类的对象时,无须创建父类的对象 |