java复习纲要(2)

第9章 对象和类

9.2 为对象定义类

  • 一个对象的状态特征属性)是有具有当前值的数据域来表示。
  • 一个对象的行为动作)是由方法定义的。调用对象的一个方法就是要求对象完成一个动作。

9.4 使用构造方法构造对象

  1. 构造方法是一种特殊的方法。它们有以下三个特殊性:
    • 构造方法必须具有的所有类相同的名字。
    • 构造方法没有返回值类型,void也没有。
    • 构造方法是在创建一个对象使用new操作符是调用的。构造方法的作用是初始化对象。
  2. 一个类会提供一个没有参数的构造方法。该构造方法称为无参构造方法
  3. 一个类可以不定义构造方法。在这种情况下,类中隐含定义一个方法为空的无参构造方法。这个构造方法称为默认构造方法,当且仅当类中没有明确定义任何构造方法时才会自动提供它。

9.6 使用Java库中的类

9.6.1 Date类

  • 可以使用Date类中的无参构造方法为当前的日期创造一个实例,它的getTime()方法返回自从GMT时间1970年1月1日算起至今流逝的时间,它的toString()方法返回日期和时间的字符串。

    java.util.Date date = new java.util.Date();
    System.out.println("The elapsed time since Jan 1, 1970 is " + date.getTime() + "milliseconds");
    System.out.println("date.toString()");

    显示输出为:

    The elapsed time since Jan 1, 1970 is 1324903419651 milliseconds;
    Mon Dec 26 07:43:39 EST 2011

9.6.2 Random类

  • 可以使用Math.Random()获取一个0.0到1.0(不包括1.0)之间的随机double值。

9.6.3 Point2D类

  • Java API在javafx.geometry包中有一个便于使用的Point2D类,用于表示二维平面的点。

  • 可以为给定的x和y坐标的点来创建一个Point2D类,使用disdance方法计算该点到另外一个点的距离,并使用toString()方法来返回该点的字符串表示。

    import java.util.Scanner;
    import javafx.geometry.Point2D;
    
    public class point {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("Enter point1's x-, y-coordinates: ");
        double x1 = input.nextDouble();
        double y1 = input.nextDouble();
        System.out.println("Enter point2's x-, y-coordinates: ");
        double x2 = input.nextDouble();
        double y2 = input.nextDouble();
        Point2D p1 = new Point2D(x1,y1);
        Point2D p2 = new Point2D(x2,y2);
        System.out.println("p1 is " + p1.toString());
        System.out.println("p2 is " + p2.toString());
        System.out.println("The disdance between p1 and p2 is " + 
                            p1.distance(p2));
    }
    }
    //运行:
    Enter point1's x-, y-coordinates: 1 6
    Enter point2's x-, y-coordinates: 2 1
    p1 is Point2D [x = 1.0, y = 6.0]
    p2 is Point2D [x = 2.0, y = 1.0]
    The disdance between p1 and p2 is 5.0990195135927845

9.7 静态变量、常量和方法

  • 如果想让一个类的所有实例共享数据,就得使用静态变量类变量)。静态变量将变量值储存在一个公共的内存地址。

  • 要声明一个静态变量或定义一个静态方法,就要在这个变量或方法的声明中加上修饰符static

  • 类中常量是被该类的所有对象所共享。因此,常量应该声明为final static

    final static double PI = 3.14159265358979323846;

9.8 可见修饰符

​ 可在类、方法和数据域前使用public修饰符,表示它们可以被任何其他的类访问。如果没有使用可见修饰符,则默认类、方法和数据域是可以被同一个包中的任何一个类访问。这称为包私有包内访问)。

    1. 包可以用来组织类。此时,需要在程序中首先出现下面这句语句,在这行语句前不能有注释也不能有空白:package packageName;
    2. 如果定义类时没有声明包,就表示把它放在默认包中。
    3. Java建议最好将类放入包中,而不要使用默认包。
  • 除了public和默认可见修饰符,Java还为类成员提供privateprotected修饰符。
    1. private修饰符限定方法和数据域只能在它自己的类中被访问。
    2. 私有修饰符将访问权限限定在它自己的类中,默认修饰符将访问权限限定在包内,公共修饰符可以无限制的访问。
  • 修饰符private只能应用在类的成员上。修饰符public可以应用在类和类的成员上。在局部变量上使用修饰符public和private都会导致编译错误。

9.9 数据域封装

  • 为了避免对数据域的直接修改,应该使用private修饰符将数据域声明为私有的,这称为数据域封装

  • 为了能够访问私有数据域,可以提供一个get方法返回数据域的值。为了能够更新一个数据域,可以提供一个set方法给数据域设置新值。get方法称为访问器,set方法称为修改器

    1. get方法签名:public returnType getPropertyName()

      如返回值为boolean型:public boolean isPropertyName()

    2. set方法签名:public void setPropertyName(dataType propertyValue)

9.10 向方法传递对象参数

  • Java只有一种参数传递方式:值传递
  • 传递引用类型的参数时,传递的是对象的引用。引用上的传值在语义上最好描述为传共享,即在方法中引用的对象和传递的对象是一样的。

9.11 对象数组

  • 数组既可以存储基本类型值,也可以存储对象。
  • 对象的数组实际上是引用变量的数组

9.12 不可变对象和类

  • 可以定义不可变类来产生不可变对象。不可变对象的内容不能被改变。

  • 通常创建一个对象后它的内容是允许之后改变的。有时候需要创建一个其内容不可改变的对象,这种对象称为不可变对象,它的类就称为不可变类

  • 如果一个类是不可变的,那么它的所有数据域必须都是私有的,而且没有对任何一个数据域提供公共的set方法。一个类的所有数据域都是所有的且没有修改器并不意味着它一定是不可变类。

    public class Student {
      private int id;
      private String name;
      private java.util.Date dataCreated;
    
      public Student(int ssn, String newName) {
          id = ssn;
          name = newName;
          dateCreated = new java.util.Date();
      }
    
      public int getId() {
          return id;
      }
    
      public String getName() {
          return name;
      }
    
      public java.util.Date getDateCreaned() {
          return dateCreaned;
      }
    }
    
    //如下代码,使用getDateCreaned()方法返回数据域dateCreaned。它是对Date对象的一个引用。通过这个引用可以改变dateCreaned的值。
    public class Test {
      public static void main(String[] args) {
          Student student = new Student(111223333, "John");
          java.util.Date dateCreaned = student.getDateCreaned();
          dateCreaned.setTime(200000); //Now dateCreaned field is changed!
      }
    }
  • 要使一个类成为不可变的,它必须满足以下要求:

    1. 所有数据域都是私有的。
    2. 没有修改器方法。
    3. 没有一个返回指向可变数据域的引用的访问器方法。

9.13 变量的作用域

  • 实例变量和静态变量的作用域是整个类,无论变量是在哪里声明的。
  • 一个类的实例变量和静态变量称为类变量数据域。在方法内部定义的变量称为局部变量
  • 类变量只能声明一次,但在一个方法内不同的非嵌套块中,可以多次声明相同的变量名。
  • 如果局部变量和一个类变量具有相同的名字,那么局部变量优先,而同名的类变量将被隐藏。

9.14 this引用

  • 关键字this引用对象自身。它也可以在构造方法内部用于调用同一个类的其他构造方法。

9.14.1 使用this引用隐藏数据域

  1. 关键字this可以用于引用类的隐藏数据域。

    public class F {
       private int i = 5;
       private static double k = 0;
       public void setI(int i) {
           this.i = i;
       }
       public static void setK(double k) {
           F.k = k;
       }
    }
  2. 关键字this给出一种引用调用实例方法的对象的方法。

    Suppose that f1 and f2 are two objects of F.
    
    Invoking f1.setI(10) is to execute
    this.i = 10, where this refers f1
    
    Invoking f2.setI(45) is to execute
    this.i = 45, where this refers f2
    
    Invoking F.setK(33) is to execute
    F.k = 33. setK is a static method

9.14.2 使用this调用构造方法

  • 关键字this可以用于调用同一个类的另一个构造方法。

    public class Circle {
      private double radius;
    
      public Cricle(double radius) {
          this.radius = radius; //this关键字用于引用所构建的对象的隐藏数据域radius
      }
    
      public Cricle() {
          this(1.0); //this关键字用于调用另外一个构造方法
      }
    }
    • Java要求在构造方法中,语句this(参数列表)应在任何其他可执行语句之前出现。
    • 无参数或参数少的构造方法可以用this调用参数多的构造方法

第10章 面对对象思考

10.2 类的抽象和封装

  • 类的抽象是指将类的实现和使用分离。
  • 类的封装是指实现细节经过封装,对用户隐藏起来。

10.4 类的关系

  • 为了设计类,需要探究类之间的关系。类中间的关系通常是关联、聚合、组合、以及继承。

10.4.1 关联

  • 关联是一种常见的二元关系,描述两个类之间的活动。

10.4.2 聚合和组合

  • 聚合是关联度一种特殊形式,代表了两个对象之间的归属关系。所有者对象称为聚集对象,它的类称为聚集类。从属对象称为被聚集对象,它的类称为被聚集类
  • 如果一个对象只归属一个聚集对象,那么它和聚集对象之间的关系就称为组合
  • 聚集关系通常被表示为聚集类中的一个数据域。

10.7 将基本数据类型值作为对象处理

  • 基本数据类型值不是一个对象,但是可以使用Java API 中的包装类来包装成一个对象。

  • 将基本数据类型并入对象或包装成对象(将int包装成integer类,将double包装成Double类,将char包装成character类)。通过使用包装类,可以将基本数据类型值作为对象处理。

  • 包装类没有无参构造方法。所有的包装类的实例都是不可变的,这意味着一旦创建对象后,它们的内部值就不能再改变。

  • 每一个数值包装类都有常量MAX_VALUEMIN_VALUE。MAX_VALUE表示对应的基本数据类型的最大值,MIN_VALUE表示对应的基本数据类型的最小值。

    System.out.println(Integer.MAX_VALUE); //显示最大整数
    System.out.println(Float.MIN_VALUE); //显示最小正浮点数
    System.out.println(Double.MAX_VALUE); // 显示双精度浮点数的最大值
  • 每个数值包装类都会包含方法doubleValue()floatValue()intValue()longValue()shortValue()

    new Double(12.4).intValue(); //return 12;
    new Integer(12).doubleValue(); //return 12.0;
  • 数值包装类中包含compareTo方法用于比较两个数值,并且如果该数值大于、等于或小于另外一个数值时,分别返回1、0、-1。

    new Double(12.4).compareTo(new Double(12.3)); //return 1;
    new Double(12.3).compareTo(new Double(12.3)); //return 0;
    new Double(12.3).compareTo(new Double(12.4)); //return -1;
  • 数值包装类有一个有用的静态方法valueOf(String s),该方法创建一个新对象,并将它初始化为指定字符串表示的值。

    Double doubleObject = Double.valueOf("12.4");
    Integer integerObject = Integer.valueOf("12");
  • Integer类中的parseInt方法将一个数值字符串转换为一个int值,double类中的parseDouble方法将一个数值字符串转换为一个double值。

    (还有parseByteparseShortparseLongparseFloat等)

    Integer.parseInt("11", 2); //return 3;
    Integer.parseInt("12", 8); //return 10;
    Integer.parseInt("13", 10); //return 13;
    Integer.parseInt("1A", 16); //return 26;
    • Integer.parseInt("12", 2)会引起一个运行错误,因为12不是二进制数。

    • format方法将一个十进制数转换为十六进制数。

    String.format("%x", 26); //return 1A;

10.8 基本类型和包装类类型之间的自动转换

  • 将基本类型值转换为包装类对象的过程称为装箱,相反的转换过程称为开箱

  • 如果一个基本类型值出现在需要对象的环境中,编译器会将基本类型值进行自动装箱;如果一个对象出现在需要基本类型值的环境中,编译器会将对象自动开箱

    Integer intObject = new Integer(2); <等价于> Integer intObject = 2;[^1]

10.9 BigInteger和BigDecimal类

  • BigInteger类BigDecimal类可以用于表示任意大小和精度的整数或者十进制数。

  • 使用new BigInteger(String)new BigDecimal(String)来创建BigInteger和BigDecimal的实例,使用add、subtract、multiple、divide和remainder方法完成算术运算。

    BigInteger a = new BigInteger("9223372036854775807");
    BigInteger b = new BigInteger("2");
    BigInteger c = a.multiply(b);
    System.out.println(c);
    //输出为18446744073709551614
  • 对BigInteger对象的精度没有限制。可以使用重载的divide(BigDecimal d, int scale, int roundingMode)方法来指定尺度和舍入方式。

    BigDecimal a = new BigDecimal(1.0);
    BigDecimal b = new BigDecimal(3);
    BigDecimal c = a.divide(b, 20, BigDecimal.ROUND_UP);
    System.out.println(c);
    //输出为0.33333333333333333334
  • EP: 求一个整数的阶乘

    import java.math.*;
    public class LargeFactorial {
      public static void main(String[] args) {
          Scanner input = new Scanner(System.in);
          System.out.println("Please input a number: ");
          int n = input.nextInt();
          System.out.println(n + "! is " + factorial(n));
      }
      public static BigInteger factorial(long n) {
          BigInteger result = BigInteger.ONE;
          for(int i = 1; i <= n; i++)
              result = result.multiply(new BigInteger(i + ""));
          return result;
      }
    }
    
    //运行如下:
    Please input a number: 50
    50! is 30414093201713378043612608166064768844377641568960512000000000000

10.10 String类

  • String对象是不可改变的。字符串一旦创建,内容不能再改变。

10.10.1 构造字符串

String newString = new String(stringLiteral); //字符串创建语法
String message = new String("Welcome to Java"); //为字符串直接量创建一个String对象
String message = "Welcome to Java"; //将字符串直接量看作String对象

char[] charArray = {'G', 'o', 'o', 'd', ' ', 'D', 'a', 'y'};
String message = new String(charArray); //用字符数组创建一个字符串

10.10.3 字符串的替换和分隔

  • 一旦创建了字符串,它的内容就不能改变了。但方法replacereplaceFirstreplaceAll会返回一个源自原始字符串的新字符串。如:

    "Welcome".replace('e', 'A')~返回一个新的字符串,~ WAlcomA.

    "Welcome".replaceFirst('e', 'AB')~返回一个新的字符串,~ WABlcome.

    "Welcome".replace('e', 'AB')~返回一个新的字符串,~ WABlcomAB.

    "Welcome".replace('eL', 'AB')~返回一个新的字符串,~ WABcome.

10.10.4 依照模式匹配、替换和分隔

  • 正则表达式是一个字符串,用于描述匹配一个字符串集的模式。可以通过指定某个模式来匹配、替换或分隔一个字符串。

  • matches方法和equals方法相似,下面两条语句值均为true:

    "Java".matches("Java");
    "Java".equals("Java");
    • matches不仅能匹配定长的字符串,还能匹配一套遵从某种模式的字符串,下面语句值为true:
    "Java is fun".matches("Java.*");
    "Java is cool".matches("Java.*");
    "Java is powerful".matches("Java.*");
    • “Java.*”是一个正则表达式。它描述的字符串模式是以字符串Java开始的,后面紧跟任意0或多个字符,下面语句值为true:


猜你喜欢

转载自blog.csdn.net/Heimdall_vata/article/details/80861713