所谓面向抽象编程是指当设计某种重要的类时,不让该类面向具体的类,而是面向抽象类,及所设计类中的重要数据是抽象类声明的对象,而不是具体类声明的对象。就是利用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. MySQL 5.7.9的多源复制

    什么是多源复制? 首先,我们需要清楚 multi-master 与multi-source 复制不是一样的. Multi-Master 复制通常是环形复制,你可以在任意主机上将数据复制给其他主机. M ...

  2. php微型mvc框架创建步骤

    创建数据库和表结构,并且添加模拟数据: 新建models.views.controllers.utilities和include五个文件夹:models:模型层     model.php:模型基类  ...

  3. Python之回调魔法

    Python中魔法(前后又下划线)会在对象的生命周期被回调. 借助这种回调, 可以实现AOP或者拦截器的思想. 在Python语言中提供了类似于C++的运算符重在功能:一下为Python运算符重在调用 ...

  4. 从零开始学ios开发(十):Multiview Applications(多个xib之前的切换)

    这篇学习的主要内容是Multiview,在我们学习iphone旋转的时候,介绍过多个view的使用方法,不过这里的view和旋转屏幕中所指的多个view是不同的,旋转屏幕中涉及到的多个view是在一个 ...

  5. 高精度计算的类(BigInteger和BigDecimal)

    这两个类 在Java中没有对应的基本类型.不过,这两个类包含的方法,提供的操作与对基本类型所能执行的操作差不多. 也就是说,能对基本类型 int float 等的操作,也同样能作用于这两个类,只不过必 ...

  6. Notes of the scrum meeting(10/28)

    meeting time:4:00~6:00p.m.,October 28th,2013 meeting place:雕刻时光 attendees: 顾育豪                       ...

  7. vim插件介绍

    代码补全 http://blog.sina.com.cn/s/blog_a6559d920101acv3.html这个牛逼.************************************** ...

  8. 【POJ】【3071】Football

    概率DP kuangbin总结中的第10题 简单的画个比赛图,会发现是一颗完全二叉树,且同一层的子树之间各自独立,只有在合并得到更高一层结果时才结合. 所以我们可以按比赛轮数进行DP,f[i][j]表 ...

  9. NYOJ-469 擅长排列的小明 II AC 分类: NYOJ 2014-01-02 22:19 159人阅读 评论(0) 收藏

    最初的第一印象是和组合数一个性质的题目.所以用了回溯法,结果,你懂的... #include<stdio.h> #include<math.h> void dfs(int n, ...

  10. Oracle中的 UPDATE FROM 解决方法

    转:http://www.cnblogs.com/JasonLiao/archive/2009/12/23/1630895.html Oracle中的 UPDATE FROM 解决方法 在表的更新操作 ...