4 对象与类

4.1 面向对象程序设计概述

4.1.1 类

类构造对象的过程为创建类的实例。

封装。实例域。方法。状态。

4.1.2 对象

对象的行为。对象的状态。对象的标识。

4.1.3 识别类

4.1.4 类之间的关系

  • 依赖 uses-a
  • 聚合 has-a
  • 继承 is-a

uml 统一建模语言。

4.2 使用预定义类

4.2.1 对象与对象变量

在Java中,使用构造器构造新实例。

一个对象变量并没有实际包含一个对象,而仅仅引用一个对象。

4.2.2 Java类库中的GregorianCalendar类

Date类表示时间点;日历表示法GregorianCalendar类;更加通用的Calendar类。

4.2.3 更改器方法与访问器方法

public class CalendarTest
{
   public static void main(String[] args)
   {
      // construct d as current date
      GregorianCalendar d = new GregorianCalendar();

      int today = d.get(Calendar.DAY_OF_MONTH);
      int month = d.get(Calendar.MONTH);

      // set d to start date of the month
      d.set(Calendar.DAY_OF_MONTH, 1);

      int weekday = d.get(Calendar.DAY_OF_WEEK);

      // get first day of week (Sunday in the U.S.)
      int firstDayOfWeek = d.getFirstDayOfWeek();

      // determine the required indentation for the first line
      int indent = 0;
      while (weekday != firstDayOfWeek)
      {
         indent++;
         d.add(Calendar.DAY_OF_MONTH, -1);
         weekday = d.get(Calendar.DAY_OF_WEEK);
      }

      // print weekday names
      String[] weekdayNames = new DateFormatSymbols().getShortWeekdays();
      do
      {
         System.out.printf("%4s", weekdayNames[weekday]);
         d.add(Calendar.DAY_OF_MONTH, 1);
         weekday = d.get(Calendar.DAY_OF_WEEK);
      }
      while (weekday != firstDayOfWeek);
      System.out.println();

      for (int i = 1; i <= indent; i++)
         System.out.print("    ");

      d.set(Calendar.DAY_OF_MONTH, 1);
      do
      {
         // print day
         int day = d.get(Calendar.DAY_OF_MONTH);
         System.out.printf("%3d", day);

         // mark current day with *
         if (day == today) System.out.print("*");
         else System.out.print(" ");

         // advance d to the next day
         d.add(Calendar.DAY_OF_MONTH, 1);
         weekday = d.get(Calendar.DAY_OF_WEEK);

         // start a new line at the start of the week
         if (weekday == firstDayOfWeek) System.out.println();
      }
      while (d.get(Calendar.MONTH) == month);
      // the loop exits when d is day 1 of the next month

      // print final end of line if necessary
      if (weekday != firstDayOfWeek) System.out.println();
   }
}

4.3 用户自定义类

4.3.1 Employee类

import java.util.Date;
import java.util.GregorianCalendar;

public class EmployeeTest {
    public static void main(String[] args) {
        Employee[] staff = new Employee[3];
        staff[0] = new Employee("Kate", 74000, 1987, 2, 1);
        staff[1] = new Employee("Lucy", 13000, 1984, 2, 12);
        staff[2] = new Employee("Ann", 12000, 1990, 4, 21);

        for (Employee e :
                staff) {
            System.out.println("name =" + e.getName() + ", salary = " + e.getSalary()
                    + ", hireDay = " + e.getHireDay());
        }
    }
}

class Employee {
    private String name;
    private double salary;
    private Date hireDay;

    public Employee(String n, double s, int year, int month, int day) {
        name = n;
        salary = s;
        GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day);
        hireDay = calendar.getTime();
    }

    public String getName() {
        return name;
    }

    public void setName(String n) {
        name = n;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double s) {
        salary = s;
    }

    public Date getHireDay() {
        return hireDay;
    }

    public void setHireDay(int year, int month, int day) {
        GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day);
        hireDay = calendar.getTime();
    }
}
View Code

4.3.2 多个源文件的使用

两种编译源文件的方法:

javac Employee*.java;

java EmplyeeTest.java;

4.3.3 剖析Employee类

4.3.4 从构造器开始

  • 构造器与类同名;
  • 每个类可以有一个以上的构造器;
  • 构造器可以有0,1,或多个参数;
  • 构造器没有返回值;
  • 构造器总是伴随着new操作一起调用

4.3.5 隐式参数与显式参数

在每一个方法中,关键词this表示隐式参数。

4.3.6 封装的优点

设置实例域,需要提供下面三项内容

  • 一个私有的数据域;
  • 一个公有的域访问方法;
  • 一个公有的域更改器方法;

4.3.7 基于类的访问权限

if(harry.equals(boss)).

同类的方法可以访问任何一个类实例的私有域。

4.3.8 私有方法

在Java 中,实现一个私有方法,只需将public改成private;

4.3.9 final实例域

在每一个构造器执行以后,这个域的值将被设置,并且在后面的操作中,不能够对它进行修改。

class Employee{
 private final String name;
...
}

4.4 静态域与静态方法

4.4.1 静态域

将域定义为static,这个域属于类,而不属于任何独立的对象。

4.4.2 静态常量

public static final double PI = 3.1415926;

4.4.3 静态方法

静态方法是一种不能向对象实施操作的方法。

可以认为静态方法是没有this参数的方法。

在下面两种情况下使用静态方法:

  • 一个方法不需要访问对象状态,其所需要的参数都是通过显式参数提供的。
  • 一个方法只需要访问类的静态域。

4.4.4 工厂方法

静态方法还有一种常见的用途,使用工厂方法产生不同风格的格式对象。

  • 无法命名构造器,希望得到的实例采用不同的名称;
  • 当使用构造器,无法改变所构造的对象类型。

4.4.5 main方法

main方法也是一个静态方法。

4.5 方法参数

 按值调用,call by value,方法接受的是调用者提供的值。按引用调用,call by reference,表示方法接受的是调用者提供的变量地址。一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。

  • 一个方法不能修改一个基本数据类型的参数。
  • 一个方法可以改变一个对象参数的状态。
  • 一个方法不能让对象参数引用一个新的对象。

4.6 对象构造

4.6.1 重载

一个类有多个构造器,这种特征叫重载。跳出具体的执行方法,称之为重载解析。

4.6.2 默认域初始化

如果构造器没有显式的赋予初值,那么就会自动赋予默认值,数值为0,布尔值为false,对象引用为null。

4.6.3 无参数的构造器

如果没有编写构造器,系统会提供一个无参数构造器。

如果至少编写了一个构造器,没有提供参数会被认视为不合法。

4.6.4 显式域初始化

当一个类的所有构造器都希望把相同的值赋予某个特定的实例域时,这个方法特别有用。

初始值不一定是常量。

4.6.5 参数名

public Employee(String aName, double aSalary) {
name = aName;
scary = aSalary;}

4.6.6 调用另外一个构造器

用关键词this调用同一个类的另一个构造器。

4.6.7 初始化块

Java还有第三种机制,称为初始化块。

  • 所有数据域被初始化为默认值(0,false或者null)
  • 按照类声明中出现的次序,依次执行所有域初始化语句和初始化块。
  • 如果构造器第一行调用了第二个构造器,则执行第二个构造器主体。
  • 执行这个构造器的主体。

静态的初始化块

static
{
 Random generator = new Random();
 nextId = generator.nextInt(10000);}

4.6.8 对象构析与finalize方法

可以给任何一个类添加finalize方法,在垃圾回收器清除对象之前调用。

4.7 包

允许用包将类组织起来。使用包的主要原因是确保类名的唯一性。

4.7.1 类的导入

import java.util.*;

4.7.2 静态导入

import static java.lang.System.*;

4.7.3 将类放入包中

package com.ayor.corejava;

4.7.4 包作用域

没有指定private或者public,这个部分(类,方法或者变量)可以被同一个包中所有方法访问。

4.8 类路径

jar,Java归档文件。

4.9文档注释

javadoc,可以由源文件生成一个HTML文档。联机文档api,就是通过对标准类库的源代码运行javadoc生成的。

4.9.1 注释的插入

javadoc从下面几个特性中抽取信息

  • 公有类及接口
  • 公有的和受保护的构造器及方法
  • 公有的和受保护的域

4.9.2 类注释

类注释必须在import语句之后,类定义之前。

4.9.3 方法注释

@param 变量描述

@return描述

@throws类描述

4.9.4 域注释

4.9.5 通用注释

@author姓名

@verison文本

@since文本

@deprecated文本

@see引用

4.9.6 包与概述注释

4.9.7 注释的抽取

javadoc -d docDirectory nameOfPackage;

javadoc -d docDirectory *.java;

省略docDirectory选项,html文件会被提取到当前目录下,不推荐。

使用 -author ,-version 选项,可以提取@author,@version标记。

4.10 类设计技巧

  1.  一定要保证数据私有;
  2. 一定要对数据初始化;
  3. 不要在类中使用过多的基本数据类型;
  4. 不是所有域都需要独立的域访问器和域更改器;
  5. 将指责过多的类进行分解;
  6. 类名和方法名要体现它们的职责;
posted @ 2020-04-20 20:18  ayor  阅读(88)  评论(0)    收藏  举报