数组与面向对象概述

数组

  • 数组是一种数据结构,用来存储同一类型值的集合.通过一个整型下标可以访问数组中的每一个值,例如:如果a是一个整型数组,a[i]就是数组中下标为i的整数.
  • 在声明数组变量时,需要指出数组类型(数据元素类型紧跟[])和数组变量的名字,下面声明了整型数组a: int[] a;
  • 不过,这条语句只声明了变量a,并没有将a初始化为一个真正的数组.应该使用new运算符创建数组.int[] a = new int[100];,这条语句创建了一个可以存储100个整数的数组.数组长度不要求是常量,new int[n]会创建一个长度为n的数组.
  • 这个数组下标从0~99,一旦创建了数组,就可以给数组元素赋值.例如:使用一个循环
int[] a = new int[100];
for(int i = 0;i < 100;i++)
{
    a[i] = i;
} 
  • 创建一个数字数组时,所有元素都初始化为0,boolean数组的元素会初始化为false.对象数组的元素则初始化为一个特殊值null,这表示这些元素未存放任何对象.例如:String[] names = new String[10];,会创建一个包含10个字符串的数组,所有字符串都为null,如果希望这个数组包含空串,可以为元素指定空串.for(int i=0;i<10;i++) names[i]="";

警告:如果创建了一个100个元素的数组,并且试图访问元素a[100],程序会引发"array index out of bounds"异常而终止执行.

  • 要想获取数组的元素个数,可以使用array.length,例如:for(int i = 0;i < a.length;i++) System.out.println(a[i]);
  • 一旦创建数组,就不能改变大小,如果经常需要在运行过程中扩展数组大小,就应该使用另一种数据结构,即数组列表.

foreach循环

  • Java有一种功能很强的循环结构,可以一次处理每个元素.
  • 这种增强的for循环的语句格式:for(variable:collection) statement;,定义一个变量用于暂存集合中的每一个元素,并执行相应的语句.collection这一集合表达式必须是一个数组或者一个实现了Iterable接口的类对象.例如:
for(int element:a)
{
    System.out.println(element);
}

数组初始化及匿名数组

  • 在Java中,提供了一种创建数组对象并同时赋予初始值的简化书写方式,下面是一个例子:int[] snmallPrimes = {2,3,5,7,11,13};,请注意,在使用这种语句时,不需要调用new.
  • 甚至可以初始化一个匿名的数组:new int[] {17,19,23,29,31,37},这种表示法将创建一个新数组并利用括号中提供的值进行初始化,数组的大小就是初始值的个数.使用这种语法形式可以在不创建新变量的情况下重新初始化一个数组,例如:smallPrimes = new int[] {17,19,23,29,31,37};,这是下列语句的简写形式
int[] annoymous = {17,19,23,29,31,37};
smallPrimes = annoymous;

数组拷贝

  • 在Java中,允许将一个变量拷贝给另一个数组变量,这时,两个变量将引用同一个数组:
int[] luckNumbers = smallPrimes;
luckNumbers[5] = 12; // new smallPrimes[5] is also 12

这时,将两个变量地址指向同一个数组.

  • 如果希望将一个数组的所有值拷贝到一个新的数组中去,要使用Arrays类的copyOf方法:int[] copiedNumbers = Arrays.copyOf(luckyNumbers,luckyNumbers.length)'.第2个参数是新数组的长度,这个方法通常用于增加数组的大小.luckyNumbers = Arrays.copyOf(luckyNumbers,2*luckyNumbers.length);
  • 如果数组元素是数值型,那么多余的元素会被赋值为0,如果数组元素是布尔型,则将赋值为false,相反,如果长度小于原始数组长度,则只拷贝最前面的数据元素.

命令行参数

  • 每一个Java应用程序都有一个String args[]参数的main方法.这个参数表明main方法将接收一个字符串数组,也就是命令行参数.例如,看看下面的程序
public class Message {
    public static void main(String[] args) {
        if(args.length==0 || args[0].equals("-h"))
        {
            System.out.println("Hello");
        }
        else if(args[0].equals("-g"))
        {
            System.out.println("Goodbye");
        }
        for (int i = 0; i < args.length; i++) {
            System.out.println(" "+args[i]);
        }
        System.out.println("!");
    }
}

输出结果默认为Hello,因为命令行参数默认为-h,如果使用java Message -g cruel world,那么args数组将包含内容为args[0]="-g",args[1]="cruel",args[2]="world",输出结果为Goodbye,cruel world!

数组排序

  • 使用Arrays.sort方法,例如:Arrays.sort(a);,这个方法使用了优化的快速排序算法.

数组类Arrays中的常用方法

  • static String toString(type[] a):返回包含a中数据元素的字符串,这些数据元素被放在括号中,并用逗号隔开.
  • static type copyOf(type[] a , int length):返回一个与类型a相同的数组,长度为length,数组元素为a的值.
  • static void sort(type[] a ):采用优化的快速排序对数组进行排序.
  • static itn binarySearch(type[] a,type v):采用二分查找,如果查找成功,返回相应的下标值,否则返回一个负数.
  • static void fill(type[] v,type v):将数组的所有数据元素值设置为v.
  • static boolean equals(type[] a , type[] b):如果两个数组大小相同,并且下标相同的元素都对应相等时,返回true.

多维数组

  • 多维数组将使用多个下标访问数组元素,它适合表示表格或更加复杂的排列形式.
  • 在Java中,声明一个二维数组的方式,例如:double[][] balances,与一维数组一样,在调用new对多维数组进行初始化之前不能使用,在这里可以进行初始化:balances = new double[10][10];
  • 另外如果知道数组元素,就可以不调用new.而直接使用简化的方式进行初始化.
int[][] magic=
{
    {16,3,2,13},
    {5,40,10,8},
    {9,6,7,13};
    {4,15,14,1}
}
  • 在处理二维数组时,使用双层嵌套循环
for(double[] row :a)
{
    for(double vaule : row)
    {
        System.out.print(value+" ");
    }
    System.out.println("");
}

提示:要想快速打印一个二维数组的列表,可以调用:System.out.println(Arrays.deepToString(a)).

面向对象程序设计概述

  • 面向对象程序设计(OOP)是当今主流的程序设计范型.取代了"结构化"过程化程序开发技术.Java是完全面向对象的.
  • 面向对象的程序是由对象组成,"万物皆对象"的思想,每个对象包含对用户公开的特定功能和隐藏的实现部分,程序中的很多对象来自于标准库,还有一些是自己定义的,究竟是自己构造对象,还是从外界购买对象取决于开发的时间和成本,但是从根本上说,只要对象满足要求,就不必关心其功能的具体实现过程.在OOP思想中,只关心对象的具体实现.
  • 传统的结构化程序设计通过设计一系列的过程(即算法)来求解问题,一旦确定了这些过程,就要开始考虑存储数据的方式,这是Pascal语言的设计者将其著作命名为《算法+数据结构=程序》的主要原因.需要注意的是在这本书中,算法是第一位,数据结构是第二位的.这就明确了程序的工作方式,首先确定如何操作数据,然后再决定操作数据,以便于数据操作.而OOP却调换了位置,将数据放在第一位,然后在考虑操作数据的算法.

  • 类是构造对象的模板或蓝图,可以将类想象为制作小甜饼的切割机,将对象想象为小甜饼.由类构造对象的过程称为创建类的实例.
  • 封装是与对象有关的一个重要概念,从形式上看,封装不过是将数据和行为组合在一个包中,并对对象使用者隐藏了数据的实现方式,对象中的数据称为实例域.操纵数据的过程称为方法.对于每一个特定的类实例(对象)都有一组特定的实例域值,这些值的集合就是这个对象的当前状态.无论何时,只要向对象发送一个消息,它的状态就有可能发生改变.
  • 实现封装的关键在于绝对不能让类中的方法直接地访问其他类的实例域.程序仅仅通过对象的方法与对象的数据进行交互,封装给对象赋予了"黑盒"特征,这是提高重用性和可能性的关键.这意味着一个类可以全面地改变存储数据的方式,只要仍旧使用同样的方法操作数据,其他对象就不会知道和介意所发生的变化.

对象

  • 要想使用OOP,一定要清楚对象的3个主要特征
    1. 对象的行为:可以对对象施加哪些操作,或可以对对象施加哪些方法?
    2. 对象的状态:当施加那些方法时,对象如何响应?
    3. 对象的标识:如何辨别具有相同行为与状态不同对象?
  • 同一个类的所有对象实例,由于支持相同的行为而具有家族式的相似性,对象的行为是用可调用的方法定义的.
  • 此外,每个对象都保存着描述当前特征的信息,这就是对象的状态,对象的状态可能会随着时间而发生改变,但这种状态不会自发的,对象状态的改变必须通过调用方法实现.

如果不经过方法调用就可以改变对象状态,只能说明封装性被破坏.

  • 但是对象的状态并不能完全描述一个对象,每个对象都有一个唯一的身份,例如,在一个订单处理系统中,任何两个订单都会存在差异.所以,每个对象的标识永远是不同的,状态常常也存在差异.
  • 对象的这些关键特性在彼此之间相互影响,例如,购买东西时,如果货物的信息对象中显示没有货,那么就不能购买.

猜你喜欢

转载自www.cnblogs.com/acknowledge/p/12929133.html