You have no choice about the necessity to integrateyour observations,

your experiences, your knowledge into abstractideas, i.e., into principles.

——Ayn Rand, 《Philosophy: Who Needs It》 1974

数据抽象(Data abstraction)是将数据类型的抽象特征与事实上现的详细细节清晰地分离。

当中数据类型的“抽象特征”是指对用户代码而言可见的、怎样使用该数据类型的接口。数据抽象是接口与实现分离原则在类型层面以及对象技术中的推广

本章将介绍作为数据抽象的Java基本数据类型、抽象类、Java接口;重点讨论抽象类、接口的作用。

下一章继续介绍数据抽象——作为抽象数据类型的线性表及事实上现。


4.1数据抽象的含义

内存中保存的数值被称为数据或操作数,对数据进行分类是为了方便程序猿识别和操作它们。在[2.2.2 Java数据类型] 中,介绍了若干的概念:数据类型——定义一个值的集合以及处理这个值集的一组操作。Java语言的类型包含基本类型和程序猿自己定义的数据类型(引用类型)。

在[3.2.2 操作符]中,介绍了基本类型的各种操作;而在[2.4.1 引用的涵义]中列举了引用类型的7种操作。须要注意的是。上述全部的介绍均处于Java语言的层面[而非JVM层面]。

或者说,一直讨论的是Java数据类型的抽象特征——接口。

4.1.1 基本类型的实现

基本类型的接口/抽象特征包含该类型的取值范围和适用操作符。这里以最经常使用的int和boolean为例,说明数据抽象的含义。



1. int类型的接口和实现

    【这里先介绍int使用的一些注意事项】整数类型int是对数学整数的模拟。int与数学整数的区别在于int不是无限的。int类型逻辑上拥有32位内存空间,依照[0.1.2 二进制补码]。int类型的最大值(补码)为(231 -1)即2147483647或0x7FFF_FFFF,或二进制的0b01111111_11111111_11111111_11111111。当它加上1,就变成了0x8000_0000即最小值(-231即-2147483648)。

通常把整型的计算形容为在时钟的钟面上执行。计算时超过最大值或最小值的情况。称为溢出(O
verflow与underflow),当使用大数字时。要小心溢出。由于没有不论什么人或异常机制帮助程序猿防止这样的程序错误的发生,它是一个沉默的杀手。

可用例如以下代码验证:

    void doSth(){

        int x=0x7FFFFFFF;

        System.out.println( x + 1 );

    }

此外,int中什么值能够使i == -i呢?除了零之外,还有最小值0x8000_0000。

因此if(i == -i)的语义不同于if(i == 0)。

对于int的操作。包含了大多数操作符,如算术、比較、位操作、赋值和一元操作的正负号、++、--等等。

上述内容均为int的接口/抽象特征。作为int的用户,说int类型(逻辑上)拥有32位内存空间时。意味着用户知道了int的值域范围

其实。JVM规范中规定了int的值域范围,可是并未定义int类型的内存空间。用于储存int数据的内存空间,由JVM的不同实现者自由设定。

通常,在JVM中使用字(word)作为数据值的基本尺寸单位。要求字的尺寸足够大,以保存byte, short, int, char, float, returnValue(Java程序猿不可用的一种JVM数据类型,用于实现Java程序中的finally子句)和reference。

而两个字足以装下long或double。普通情况下以主机平台的本地指针的尺寸为字的尺寸标准。

假设机器和系统平台是32位的,int值和全部引用(reference) 都被分配了32位内存;假设机器和系统平台是64位的,int值可能被分配了64位空间

通常int的用户并不关心int的实现,int的内存空间无论是32位还是64位,不得影响int的接口。即使系统用64位来保存int值,2147483647+1仍然会(也应该)表现为溢出(变成了最小值)。

练习4-1.:解释int类型的接口和实现的分离。

练习4-2.:编程typeSystem.primitive. IntDemo,验证溢出和i == -i。

2. boolean类型的接口和实现

计算机会做的事情只是是算术操作和逻辑操作。因而布尔表达式在if-else语句、?:操作和循环语句中被广泛使用。关系操作符如5>2、x!=y等取值得到一个boolean值,布尔操作符如p && q进行逻辑运算。

不论什么一个非0的整数值x,表达式x!=0的值为true;不论什么一个非null的引用ref,表达式ref!=null的值为true。

当人们眉开眼笑地讨论Java的布尔表达式、boolean类型时,其实讨论的是boolean接口。然而Java语言中如此重要和基础的boolean类型。并不实质性地存在。嗯,这个玩笑有点大。《JVM规范第2版》中有一节<3.3.4There Is No boolean Type>。其实JVM定义了boolean类型,可是没有提供操作boolean的指令。

《Java
虚拟机规范(Java SE 7 版)》的标题<2.3.4 boolean类型>更加严谨一些。

在JVM中。源码的boolean类型的运算被实现为JVM的int类型运算。

源码的boolean[]类型。其元素的訪问与改动使用JVM的byte类型数组的 baload 和 bastore 指令。

简单地说,boolean类型的实现。JVM定义了boolean这样的数据类型。如以"Z"或" [Z"分别表示boolean和boolean[]。也通过newarray 指令直接支持创建boolean[]。可是对boolean操作转换为int操作。1代表true、0代表false。而boolean[]视为byte数组操作。Sun的JVM实现将boolean[]元素作为8bit的值,其它JVM实现可能採用压缩形式。如一位。

int和boolean两个样例。反应了数据类型的抽象特征与事实上现的详细细节的差异。这就是将数据接口与实现加以清晰地分离的数据抽象的意义所在。

练习4-3:解释boolean类型在Java语言层面、JVM规范层面和JVM实现层面的不同,并由此解释抽象的价值。

4.1.2 类的接口

对于引用类型,不须要如同基本类型那样涉及到JVM。源码中没有对象。仅仅有引用变量和引用值。关于对象的实现參考[7.4.3堆上的对象]。类的接口与实如今[第6章封装]中详述,这里仅概要地说明。

1. 类的API

Parnas原则/接口与实现分离指在模块或方法层面,用户程序猿有意识地忽略方法的实现。而每个方法具有自己的接口。对于一个类A的用户而言,A所定义的(方法)接口唯独可以被訪问时才值得关注。很多方法——典型的如private方法,只被A自己使用,对外界而言,这些方法是否存在无关紧要也不得而知。因而在面向对象技术中,Parnas原则被推广到类层面。

类的接口指外界对象可以訪问的、类所定义的接口的集合。通常。类中声明的public、protected域,也作为类接口的一部分。

由上面的定义可知,随着客户程序与本类的关系的不同,如在或不在一个包中、是或不是本类的子类,类的接口这一集合对客户类而言会有程度上的不同。使用訪问修饰符限定类的接口,这一机制称为封装,在[第6章封装]中具体介绍。

类的接口经常称为该类的API。这是为了与Java中的接口类型相差别。一般而言private和package-private方法不是类的接口。

2. 类和类型

绝大多数情况下,能够视class为一种type。比如,在[2.2.2Java数据类型]中所给出的(数据)类型的概念,将类作为类类型。

在[2.1.1里氏替换原则]中介绍了子类(subclass)与子类型(subtype)的差别。那么,类(class)和类型(type) 又有什么差异呢?

差异表如今接口与实现的分离上。type是一个名称,它标识了类的接口。

假设一个对象可以接受X类的接口的所有操作请求(方法调用),则称对象具有X类型

正是由于Java的子类可以满足父类的接口(虽然可以改写),所以子类的对象可以同一时候具有类层次中的多个类型

类(class)则是接口和实现的综合体。类不只定义了一种类型,也定义了对象的内部状态和方法的实现,以及不是接口的方法(如private方法)。简言之。类型是类的接口,类是类型+实现。

练习4-4.:一个对象能够有多个类型。

这些类型构成了一个____,如同生物学分类。

练习4-5:不同类的对象能够具有同样的类型,这个共同的类型被称为____ 。

练习4-6:子类继承父类的接口。请讨论这一命题。

练习4-7.:解释类(class)和类型(type)的差异。

《编程导论(Java)&#183;4.1数据抽象的含义》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. Java证书通信

    一.概念介绍:   加密是将数据资料加密,使得非法用户即使取得加密过的资料,也无法获取正确的资料内容,所以数据加密可以保护数据,防止监听攻击.其重点在于数据的安全性.身份认证是用来判断某个身份的真实性 ...

  2. sqlserver 运行正則表達式,调用c# 函数、代码

    --1.新建SqlServerExt项目,编写 C# 方法生成 SqlServerExt.dll 文件 using System; using System.Data; using System.Da ...

  3. Pig源代码分析: 简析运行计划的生成

    摘要 本文通过跟代码的方式,分析从输入一批Pig-latin到输出物理运行计划(与launcher引擎有关,通常是MR运行计划.也能够是Spark RDD的运行算子)的总体流程. 不会详细涉及AST怎 ...

  4. shape- 设置虚线

    <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http: ...

  5. GPU-Z:显卡体质、显卡各传感器实时状态的查看

    1. TechPowerUp GPU-Z:查看显卡体质 下载地址:Download TechPowerUp GPU-Z | techPowerUp 点击 bus interface 后的?进行显卡的体 ...

  6. 反序列化xml到treeview

    private void Form1_Load(object sender, EventArgs e) { string xmlPath = System.Environment.CurrentDir ...

  7. Direct2D开发:Direct2D 和 GDI 互操作性概述

    本主题说明如何结合使用 Direct2D 和 GDI(可能为英文网页).有两种方法可以结合使用 Direct2D 和 GDI:您可以将 GDI 内容写入与 Direct2D GDI 兼容的呈现器目标, ...

  8. HTML基础第三讲---字体

    转自:https://i.cnblogs.com/posts?categoryid=1121494 同样我们在这里继续讲一下它的body,因为它能直观的让大家观察到你所学到的成果. 这一讲,我们来学习 ...

  9. 6.CPP风格数组

    //数组初始化 1 #include <iostream> using namespace std; void main() { //C int a[5] = { 1,2,3,4,5 }; ...

  10. PythonNET网络编程4

    本地套接字 Linux 文件 b(块设备文件) c(字符设备文件) d(目录) -(普通文件) l(链接) s(套接字) p(管道) 作用:用于本地不同的程序间进行通信 创建流程 创建本地套接字 so ...