JAVA面向对象编程(孙卫琴)读书笔记(二)

九、抽象
抽象是指从特定的角度出发,把以及存在的事物抽取我们所关注的东西,形成一个新的事物的思维过程。

抽象思维在艺术和科学领域上得到了广泛的运用,例如:一幅在干旱大地突然下起大雨的抽象画,其对真实世界中的下雨场景进行了抽象,着力表现了雨下得突然和人们欢呼雀跃的场面,而这幅画却没有展示人物的相貌,年龄服装等其他的的东西,因为这些信息与主题无关。

抽象是一种由具体到抽象,由复杂到简单的思维方式而在面向对象的开发过程中,抽象主要体现在以下方面:(由下到上)

对象模型中的父类
      |   把具有相同属性和行为的类中抽象为父类
对象模型中的类
      |   把具有相同属性和行为的对象抽象为类
对象模型中的对象
      |   抽取与问题领域相关的事物的属性和行为,抽象为对象
问题领域的事物

以上3个抽象过程,前2个比较简单,主要说下第三个抽象过程
当一些类之间具有相同的属性和功能的时候,可以把这一部分功能抽象到一个父类中
而从子类到父类的抽象又有两种情况:

1.不同的子类之间具有相同的功能,并且功能的实现方式也是一样的。
例如:自行车和三轮车 他们都具有刹车功能,且实现的方式也是一样的。这样的话,把这个功能的实现放在父类中实现,而不是放在子类中实现。这样可以提高代码的重用性和可维护性。

2.不同的子类之间具有相同的功能,功能的实现方式不一样。
例如:日光灯和电灯,他们都有照明的功能,但是这两者的照明功能实现的方式却不同,在这种情况下,父类只声明了照明这种功能而不提供具体的实现。这种方式与面向对象的多态性结合,有助于提高系统之间的耦合性。(可以在后面的多态、动态绑定中再进行参考)

小结一下:
在java中,抽象有两种意思
1.当抽象作为动词时,就是指上述的抽象思维。

2.当抽象作为形容词时,用类修饰类和方法。方法被修饰为abstract修饰,表示这个方法没有具体实现;类被修饰为abstract时候,表示这个类不能被实例化。刚刚上面提到了日光灯和电灯的父类,这个父类就是抽象类,而其中的照明的这个方法也是个抽象方法,仅仅描述了这个功能,而没有具体实现这个功能,只有在他的子类中具体实现这个方法。

public abstract class Lighting{
   public abstract void light();
}

十、继承、扩展、覆盖
父类和子类之间同时存在这继承和扩展关系,子类不但可以继承父类的属性和方法还可以扩展出新的属性和方法,还可以覆盖父类中方法的实现方式(准确的说,父类中用private修饰的属性和方法对子类是透明的)

继承和扩展提高了系统的可重用性和可扩展性。

继承和扩展导致面向对象的软件开发领域中构架类软件系统的发展。从头构建一个负责软件系统的工作量巨大,为了提高开发效率,有一些组织开发了一个通用的软件架构。有了这些软件架构,新的软件系统不必从头开发,之需要在这些通用软件构架的基础之上进行扩展即可。

如何在这些通用的软件构架的基础上进行扩展呢?这些通用软件构架中都提供了一些儿扩展点,具体地说这些扩展点就专门让你继承和扩展的类,这些类已经具有了一些功能,并且能和软件构架中其他的类紧密协作,用户只要创建这些类的子类,在子类中增加或者重新实现某些功能,而这些子类能和谐地融入到软件到构架中,顺利和软件构架中其他的类协作。

而如何保证现有的软件构架和用户自定义的类相互协作呢?这就涉及到接口和多态的概念。

目前在java领域比较流行的架构软件包括:
1.j2ee —— sun公司制定的分布式的企业应用架构,他把企业应用分为 客户层、javaWeb层、应用服务层和数据库层。 而javaWeb的扩展主要是servlet和jsp,应用服务层的扩展点是ejb组件。

2.struts —— 是javaWeb应用层的通用框架,主要采用mvc模式,而他的扩展点是Action类。
3.jsf —— 也是javaWeb应用层的通用框架。(在网看到过这方面的东西,不过好像不怎么普及,还是struts用户多一点,我也是多用struts。)
4.spring —— 是企业应用的服务层的通用框架。

(NND 这章的概念性的东西太多了,有些东西没见过,很难体会到他的意义,先把他全部整理了,等日后再慢慢消化。)

 现在就以j2ee架构为例:javaweb层规划了servlet/servlet容器的架构,servlet(说白了,他就是为了方便,从最下面的基础类,扩展上来的的一些通用类,而我们就再在这通用类的基础上再进行扩展。)是供用户扩展的组件,他运行于servlet容器中,servlet容器负责接受用户的请求和发送响应,而servlet负责提供服务。
至于那个什么servlet容器,具体如何实现的,呵呵 都是底层的东西,现在不是我们了解的时候,你只要知道把你创建的servlet类放进去,就好了。

十、组合
组合是用多个简单的子系统来组装出复杂系统。
在组合系统与子系统之间为聚集关系,子系统和子系统之间是关联或者依赖关系。

下面就以台灯为例子,介绍如何实现组合系统。

台灯ReadingLamp 由灯泡Bulb和电源线路Circuit组成。
现在就模拟下用户开灯的过程:
1.用户打开台灯,调用台灯对象的on()方法。
2.台灯接通电源线路,即台灯对象调用电源线路对象的switchOn()方法。
3.电源通过灯泡,灯泡发光,即电源电路对象调用灯泡的light()方法。
4.灯泡从电源电路中获得电力,即灯泡对象调用电路对象的transportPower()方法。

关灯:
1.用户打开台灯,调用台灯对象的off()方法。
2.台灯接通电源线路,即台灯对象调用电源线路对象的switchOff()方法。
3.电源通过灯泡,灯泡发光,即电源电路对象调用灯泡的off()方法。
4.灯泡从电源电路中获得电力,即灯泡对象调用电路对象的notTransportPower()方法。

//台灯类
public class ReadingLamp {
 private Circuit circuit;
 private Bulb bulb;

 public ReadingLamp (Circuit circuit,Bulb bulb)
  {
    this.circuit=circuit;
    this.bulb=bulb;
    //建立电源和灯泡的关联关系
    circuit.setBulb(bulb);
    bulb.setCircuit(circuit);
  }

 public void setBulb(Bulb bulb)//换灯泡
   {
    this.bulb=bulb;
    circuit.setBulb(bulb);
    bulb.setCircuit(circuit);
    }

  public void on (){circuit.switchOn();}
  public void off(){circuit.switchOff();}
 
  public staitc void main(String args[])
  {
    Circuit circuit=new Circuit();
    Bulb bulb=new Bulb();
    ReadingLamp readingLamp =new ReadingLamp(circuit,bulb);
  }
}

//电源类
 public class Circuit{
 private Bulb bulb;
 //与灯泡进行关联
 pubic void setBulb(Bulb bulb)
 {
  this.bulb=bulb;
 }
 
 public void switchOn()
 {
   bulb.light();
 }

 public void switchOff()
 {
   bulb.off();
 }

 public void transportPower()
 {
  //提供电能
 }

public void notTransportPower()
 {
  //停止提供电能
 }

}

//灯泡类
 public class Bulb{
 private Circuit circuit;
 //确定与电源的关联
 public void setCircuit ()
 {
  this.circuit=circuit;
 }
 
 public void light()
 {
  circuit.transportPower();
 }

 public void off()
 {
  circuit.notTransportPower();
 }
}

以前之间写类的时候,从来不写带参数的构造函数,现在就看到了好处了
在台灯类的main函数中是这样写的
    Circuit circuit=new Circuit();
    Bulb bulb=new Bulb();
    ReadingLamp readingLamp =new ReadingLamp(circuit,bulb);
  而没有带参数构造函数的话就要写成这样
    Circuit circuit=new Circuit();
    Bulb bulb=new Bulb();
    ReadingLamp readingLamp =new ReadingLamp;
    readingLamp.circuit=circuit;
    readingLamp.bulb=bulb;
  呵呵 麻烦多了

 从上面的代码中能很好体现了 组合系统和子系统,还有子系统和子系统之间的关系。
 同时在前面说到过的类的属性和方法什么时候封装和公开要注意的几点的在这也有体现。

十一、多态、动态绑定
多态?呵呵,他和多态性又有什么区别吗?好像有关系,都是说到了方法的不同实现(方法重写),体现的是父类和子类之间的多态性。
多态是指当系统A访问系统B的服务时,系统B可以通过多种实现方式来提供服务,而这一切对系统A是完全透明的。

例如剃须刀Shaver,其包含一个电力供应子系统Power类,而电力供应可以是用干电池Battery或者是直流电AcPower,这样的话,就把电源类写成一个抽象类,他有一个抽象方法providePower(),他是电源子系统对外提供的接口,而其他的两个类继承这个抽象类。

//剃须刀类
 public class Shaver{
 private Power power;
 
 public Shaver(Power power)
 {
  this.power=power;
 }
 
 public  void setPower()
 {
  this.power=power;
 }

 public void shaver()
 {
  power.providPower();
 }
}

在上面的代码中剃须刀的shaver()方法调用了电源的providPower(),
此处的电源既可能是干电池Battery或者是直流电AcPower
所以在剃须刀的main()函数中代码可以是这样
 Shaver shaver=new shaver();
 shaver.setPower(new Battery());
 shaver.shaver();

或者是
 Shaver shaver=new shaver();
 shaver.setPower(new AcPower());
 shaver.shaver();

当运行时,如果shaver对象中的Power引用的是Battery对象,那么将调用Battery中的providPower()方法,如果引用的是AcPower,则调用的是AcPower对象的providPower()方法,
这种java虚拟机运行机制被称为动态绑定。

抽象机制和动态绑定共同提高了系统之间的松耦合性,在剃须刀类的代码中,访问的始终是power这个抽象类,而没有涉及到power的具体子类,也就是说,剃须刀类访问的只是电源的接口,而具体实现则对剃须刀类是透明的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值