第一章 1.2数据抽象

来源:互联网 发布:360极速浏览器mac版 编辑:程序博客网 时间:2024/06/05 14:52
第一章      1.2 数据抽象

       
      数据类型指的是一组值和一组对这些值操作的集合。对于原始数据类型,如int 则取值范围是-2^31 到2^31-1之间的整数,int的操作包括+、*、-、/、%、<和>。我们也可以在更高的层次的抽象上编写程序,对于重点学习定义和使用数据类型,这个过程也被称为数据抽象。
      要开发出给定数据类型的用例,我们需要:
  • 声明该类型的变量,以用来引用对象;
  • 使用关键字new触发能够创建该类型的的对象的一个构造函数;
  • 使用变量名在语句或表达式中调用实例方法;        
     java编程的基础主要是使用class关键字构造被称为引用类型的数据类型。这种编程风格也称为面向对象编程,因为它的核心概念是对象,即保存了某个数据类型的值得实体。java编程中的数据类型的种类是无限的,因为你能够定义自己的数据类型来抽象任意的对象。
       抽象数据类型(ADT)是一种能够对使用者隐藏数据表示的数据类型。用Java类来实现抽象数据类型和一组静态方法实现一个函数库并没有什么不同,抽象数据类型的不同在于将数据和函数的实现关联。并将数据的表示方式隐藏起来。在使用抽象数据类型时,我们的注意力集中在API描述的操作上  。
     抽象数据类型的定义和静态方法库之间有许多共同之处:
              相同:两者实现均为java类;实例方法可能接受0个或多个指定类型的参数,由括号表示并由逗号分隔;它们可能返回一个指定类型的值,也可能不会。
               不同:API中可能会出现几个若干个名称和类型相同且没有返回值得函数。这些特殊的函数被称为构造函数; 实例方法不需要static关键字,它们不是静态方法-它们的目的就是操作该数据类型中的值;某些实例方法的存在是为了尊重java的习惯--我们将此类方法称为继承的方法并在API中将它们显示为灰色。

 

     抽象数据类型(ADT):Counter
         (1)   一般来说,可声明一个变量heads 并将它通过以下代码和Counter类型的数据关联起来: Counter heads;
      如何为抽象数据类型赋值或是对它进行操作?????
              答:数据抽象中有一个基本概念:对象是能够承载数据类型的值得实体。对象有三大特征:状态,标示,行为; 
                         对象的状态即数据类型中的值,对象的标识就是将一个对象区别于另一个对象,可以说是对象在内存中的位置。 对象的行为就是数据类型的操作。数据类型的唯一职责就是维护一个对象的身份。引用是访问对象的一种方式。java使用术语引用类型以示和原始数据类型的区别。
           


在本书中所用到的或是开发的数据类型包括
  • java.lang.* 中的标准系统抽象数据类型,可以被java程序任意调用
  • Java 标准库中的抽象数据类型,如java.swt等等,但需要import语句
  • I/O处理类抽象数据类型,和StdIn和StdOut类似,允许我们处理多个输入输出流。
  • 面向数据类数据类型,它们的主要作用是通过封装数据的表示简化数据的组织和处理。
  • 集合类抽象数据类型,它们的主要用途是简化对同一类型的一组数据的操作。如本书中简单介绍的Bag、Stack和Queue类,以及第2章中介绍的优先队列及其相关的类,在第三章和第五章分别介绍符号表(ST)和集合(SET)以及相关的类
  • 面向操作的抽象数据类型,我们用它们分析各种算法。
  • 图算法相关的抽象数据类型,它们包括一些来封装各种图的表示的面向数据的抽象数据类,和一些提供图的处理算法的面向操作的抽象数据类型。






          (2) 创建对象
            创建一个对象,我们使用关键字new 并紧跟类名以及()来触发它的构造函数。构造函数没有返回值,因为它总是返回它的数据类型的对象的引用。
           每次用例调用了new(),系统都会:1.为新的对象分配内存空间;2.调用构造函数初始化对象中的值;3.返回该对象中的一个引用(内存);
       
           (3)调用实例方法
             方法的每一次触发都是和一个对象相关的。实例方法的意义在于操作数据类型中的值,静态方法的主要作用是实现函数。
                 
           (4)使用对象
            1.  声明该类型的变量,以用来引用对象;2.使用关键字new触发能够创建该类型的对象的一个构造函数;3.使用变量名在语句或表达式中调用实例方法;
    
             (5)赋值语句
                对象中的赋值语句指的是不会创建新的对象,而只是创建另一个指向某个已经存在的对象的引用。这种情况称为别名:两个变量同时指向同一个对象。

             (6)将对象作为参数
                如果将对象作为参数传递给方法,则会传递对象的引用,如果是原始数据类型,则只是按值传递。
             
              (7)将对象作为返回值
                 方法也可以将它的参数对象返回,也可以创建一个对象并返回它的引用,因为java只能返回一个值,有了对象,我们实际上就能返回多个值。
 
               (8)数组也是对象
               在java中所有非原始数据类型的值都是对象,也就是说数组也是对象。像其他对象一样,当我们将数组传递给一个方法时或是将一个数组变量放在赋值语句的右侧时,我们都是在创建该数组引用的一个副本,而非数组的副本。
 
                (9)对象的数组
                 数组元素可以是任意类型的数据,创建一个对象的数组需要以下两个步骤:
                         1.使用方括号语法调用数组的构造函数创建数组;
                         2.对于每一个数组元素调用它的构造函数创建相应的对象。

           总结:运用数据抽象的思想编写代码(定义和使用数据类型,将数据类型的值封装在对象中)的方式称为面向对象编程。


     抽象数据类型的实现
                    
          (1)实例变量
             实例变量为该类的对象保存了数据类型的值。它们的作用域是整个类。 要定义数据类型的值,我们需要声明实例变量,声明的方式和局部变量差不多。每一时刻每个局部变量只会有一个值,,每个实例变量对应着无数值(数据类型的每个实例对象都会有一个)。这并不会产生二义性,因为我们在访问实例变量时,都需要通过一个对象----我们是访问的这个对象的值。

,       (2)构造函数
              每个java类都至少含有一个构造函数以创建一个对象的标识,构造函数类似于一个静态方法,但它能够直接访问实例变量且没有返回值。构造函数的作用就是初始化实例变量。如果没有定义构造函数,类将会隐式定义一个默认情况下不接受任何参数的构造函数并将所有实例变量初始化为默认值。如原始数据类型的实例变量默认值为0,布尔类型变量为false,引用类型变量为null,而对于重载构造函数一般用于将实例变量由默认值初始化为用例提供的值。
                    
           (3)实例方法
               实现数据类型的实例方法的代码和实现静态方法的代码完全相同。但是只有一点关键不同:它们可以访问并操作实例变量。

               通过触发一个实例方法来操作该对象的值

            (4)作用域
               参数变量,局部变量,实例变量
       
              

API 、用例与实现
      
  1. 开发每种数据类型的步骤
  • 定义一份API:API的作用是将作用和实现分离,以实现模块化编程。我们制定API目标有二:第一,我们希望用例的代码清晰而正确,事实上,最终确定API之前就编写一些用例代码来确保所设计的数据类型操作正是用例所需要的是很好的注意;第二,我们希望能够实现这些操作,定义一些无法实现的操作是没有意义的。
  • 用一个Java类实现API的定义:首先,我们选择适当的实例变量,然后在编写构造函数和实例方法。
  • 实现多个测试用例来验证前两步做出的设计决定。        

 


更多抽象数据类型的实现

    使用数据抽象的一个关键优势是我们可以将一种实现替换为另一种而无需改变用例的任何代码。 







数据类型的设计

      抽象数据类型是一种向用例内部表示的数据类型