所谓面向抽象编程是指当设计某种重要的类时,不让该类面向具体的类,而是面向抽象类,及所设计类中的重要数据是抽象类声明的对象,而不是具体类声明的对象。就是利用abstract来设计实现用户需求。

比如:我们有一个Circle圆类,计算其面积。

1
2
3
4
5
6
7
8
9
public class Circle extends Geometry{
    double r;
    Circle(double r){
        this.r = r;
    }
    public double getArea(){
        return (3.14*r*r);
    }
}

现在要设计一个Pillar(柱类),getvolume()可以计算柱体的体积。

1
2
3
4
5
6
7
8
9
10
11
public class Pillar{
    Circle bottom;
    double height;
    Pillar(Circle bottom, double height){
        this.bottom = bottom;
        this.height = height;
    }
    public double getVolume(){
        return bottom.getArea() * height;
    }
}

在Pillar(柱类)中,bottom是用具体类Circle声明的对象,如果不涉及用户需求的变化,上面Pillar(柱类)的设计没有什么不妥,但是在某个时候,用户希望Pillar(柱类)能创建出底部是三角形的柱体。显然上面的Pillar(柱类)就无法创建出这样的柱体,即上述设计的Pillar(柱类)不能应对用户的这中需求。

重新修改Pillar(柱类)。注意到柱体的计算体积的关键是计算出底面积,一个柱体在计算底面积是不应该关心他的底是社么形状的具体图案,应该只关心这种图像是否具有计算出面积的方法。因此,在设计Pillar(柱类)的时候不应当让他的底是某个具体类的声明的对象,一旦这么做,Pillar(柱类)就会依赖具体类,缺乏弹性,难以应对需求的变化。

第一步:定义一个抽象类Geometry,类中定义一个抽象的getArea()方法,Geometry类如下。这个抽象类将所有计算面积的方法都抽象为一个标识:getArea()无需考虑算法细节。

1
2
3
public abstract class Geometry{
    public abstract double getArea();
}

第二步:Pillar(柱类)可以面向Geometry类编写代码,即Pillar(柱类)应当把Geometry类作为自己的成员,该成员可以调用Geometry的子类重写的getArea()方法。这样,Pillar(柱类)就将计算底面积的任务指派个Geometry类的子类的实例,不再依赖于某一个具体的类,而是面向Geometry类的,即Pillar(柱类)的bottom是用抽象类Geometry声明的对象,而不是具体的某一类,新的Pillar(柱类)如下:

1
2
3
4
5
6
7
8
9
10
11
public class Pillar{
    Geometry botom;
    double height;
    Pillar(Geometry bottom, double height){
        this.bottom = bottom;
        this.height = height;
    }
    public double getVolume(){
        return bottom.getArea() * height;
    }
}

在新增Geometry的子类时就不需要修改Pillar(柱类)的任何代码,只需要增加一个Triangle类(三角形)。

1
2
3
4
5
6
7
8
9
10
public class Rectangle extends Geometry{
    double a,b;
    Circle(double a, double b){
        this.a = a;
        this.b = b;
    }
    public double getArea(){
        return (a*b);
    }
}

应用:

1
2
3
4
5
6
7
8
9
10
11
12
public class Application{
    public state void main(String args[]){
        Pillar pillar;
        Geometry bottom;
        bottom = new Circle(10);             //子类的上转型对象
        pillar = new Pillar(bottom, 10);
        System.out.println("圆柱体的体积" + pillar.getVolume());
        bottom = new Rectangle(10,10);
        pillar = new Pillar(bottom, 10);
        System.out.println("矩形底的体积" + pillar.getVolume());
    }
}

总结:面向抽象编程目的是为了应对用户需求的变化,将某个类中经常因需求变化而需要改变的代码从类中分离出去。其核心是让类中每种可能的变化对应的交给抽象类的一个子类去负责,从而让该类的设计者不去关心具体的实现,避免所设计的类依赖于具体的实现。

关于抽象类:对于抽象类不能用new创建该类的对象,但可以成为其子类的上转型对象,从而该对象可以调用子类重写的方法。

一个非抽象类是某个抽象类的子类,那么它必须重写父类的抽象方法,给出方法体。

java--面向抽象编程的更多相关文章

  1. java 面向抽象编程的思想

    SIM.java public abstract class SIM { public abstract void setNumber(String n); public abstract Strin ...

  2. java面向抽象编程样例

    import java.util.*; abstract class Geometry{    public abstract double getArea();    }  class Pillar ...

  3. 大型 web 前端架构设计-面向抽象编程入门

    https://mp.weixin.qq.com/s/GG6AtBz6KgNwplpaNXfggQ 大型 web 前端架构设计-面向抽象编程入门 曾探 腾讯技术工程 2021-01-04   依赖反转 ...

  4. Java面向接口编程,低耦合高内聚的设计哲学

    接口体现的是一种规范和实现分离的设计哲学,充分利用接口可以极大的降低程序中各个模块之间的耦合,提高系统的可维护性以及可扩展性. 因此,很多的软件架构设计理念都倡导"面向接口编程"而 ...

  5. Java 面向切面编程(Aspect Oriented Programming,AOP)

    本文内容 实例 引入 原始方法 装饰者模式 JDK 动态代理和 cglib 代理 直接使用 AOP 框架--AspectWerkz 最近跳槽了,新公司使用了 AOP 相关的技术,于是查点资料,复习一下 ...

  6. java面向接口编程

    在oop中有一种设计原则是面向接口编程,面向接口编程有非常多优点,详细百度一大片.我来谈一下详细的使用中的一些不成熟的见解.! 首先面向接口编程能够消除类之间的依赖关系,使得业务仅仅依赖接口. 这样有 ...

  7. C#面向抽象编程第二讲

    抽象编程怎么说呢,以观察者模式为例: 观察者模式有两个对象,一个是观察者,一个是可观察者(字面翻译很别扭observable),消息发布者(提供者). 第一层如下,三个对象A.B.C分别有一个接收消息 ...

  8. java面向切面编程总结-面向切面的本质

    面向切面的本质:定义切面类并将切面类的功能织入到目标类中: 实现方式:将切面应用到目标对象从而创建一个新的代理对象的过程.替换: 使用注解@Aspect来定义一个切面,在切面中定义切入点(@Point ...

  9. 你必须知道的.net读书笔记之第二回深入浅出关键字---对抽象编程:接口和抽象类

    请记住,面向对象思想的一个最重要的原则就是:面向接口编程. 借助接口和抽象类,23个设计模式中的很多思想被巧妙的实现了,我认为其精髓简单说来就是:面向抽象编程. 抽象类应主要用于关系密切的对象,而接口 ...

随机推荐

  1. Arrays.asList方法总结

    import java.util.Arrays; import java.util.List; /** * * 本类演示了Arrays类中的asList方法 * 通过四个段落来演示,体现出了该方法的相 ...

  2. nodejs mongodb

    27017 nodejs指定vsisual studio版本 npm install mongodb --msvs_version=2013 npm install mongoose --msvs_v ...

  3. 使用IE10登录,URL出现SessionId的解决办法

    问题:用户登入之后,URL会出现一长串字符,类似SessionId,把这一长串字符删除之后重新进入页面,页面又会自动地跳转到登录页面,所以,应该是Session没记住用户已经登录的信息. 网站环境: ...

  4. android 讯飞语音识别(离线)注意事项

    讯飞语音识别:使用注意事项:mainfest.xml中一定要记得权限写进去21001:我的情况是没有写SpeechApp类,并且需要在application中注册:20005:无匹配结果23300:本 ...

  5. 1891: 丘比特的烦恼 - BZOJ

    Description 随着社会的不断发展,人与人之间的感情越来越功利化.最近,爱神丘比特发现,爱情也已不再是完全纯洁的了.这使得丘比特很是苦恼,他越来越难找到合适的男女,并向他们射去丘比特之箭.于是 ...

  6. php中的性能挖掘

    搞php以后,感觉总是很别扭,因为我觉得php会很慢,因为array普遍,在Key的循环查找不是很浪费性能么!因为我以前搞.net和java,他们是用的大多是寻址和索引方式,而php中太多是使用Key ...

  7. UVA 12382 Grid of Lamps 贪心

    题目链接: C - Grid of Lamps Time Limit:1000MSMemory Limit: 0KB 问题描述 We have a grid of lamps. Some of the ...

  8. Ext学习-布局介绍

    1.目标    了解ExtJS中的关于布局和组建的相关原理,并学习相关的布局方式 2.内容   1.布局和组件的相关原理   2.常见的布局方式 3.学习流程    1.首先应该学习一下布局和组件的相 ...

  9. <顶>vim快捷键映射Map使用

    问题描述: 使用vim中的快捷键映射map,可以自定义快捷键 问题解决: (1)vim模式 (2)map前缀 (3)删除映射Map (4)使用示例 (5)查看快捷键映射 命令行---:verbose ...

  10. 【BZOJ】【1076】【SCOI2008】奖励关

    状压DP+数学期望 蒟蒻不会啊……看题跑…… Orz了一下Hzwer,发现自己现在真是太水了,难道不看题解就一道题也不会捉了吗? 题目数据范围不大……100*(2^16)很容易就跑过去了…… DP的时 ...