Lecture 2 编写类与单元测试

  1. 类的基础:

    类是一种自定义的数据类型,包含数据以及操作数据的方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class Person{
    // 属性:定义类要管理的数据
    private final int age;
    private final String name;

    // 方法:定义类要提供的行为
    public void printBasicInfo() {
    System.out.printf("Hi, my name is %s, I am %d",name , age);
    }
    }

    Java程序有多个类,拥有main方法的被称为主类,一般不设置属性

    1
    2
    3
    public static void main(String[ ] args){
    // 程序入口
    }

    main方法是程序入口,main方法一般不做具体的业务处理,而是把输入请求交给业务类进行处理,业务类按照业务类别封装了业务数据和处理行为;

  2. 类的构造:

    (1)类,属性,方法:

    • 考虑我们整个业务需求可以回答我们的程序中需要定义那些类,对于每个类来说,它需要管理和维护哪些数据决定了该类的属性,而程序需要我们对这些数据进行怎样的操作决定了该类的方法;

    (2)构造方法:

    • 构造方法是类中一种特殊的方法,它用来实例化类的对象,即初始化对象的属性。Java语言为每个类默认一个无参数的构造方法,该构造方法把类中所有属性都初始化为其默认值,一旦用户自定义了构造方法,默认构造方法就会失效;

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      public class Person{
      // 属性
      private final int age;
      private final String name;

      // 构造方法
      public person(int age, String name){
      this.age = age;
      this.name = name;
      }
      }
  3. 重载:Java允许在一个类中定义多个重名方法

    • 这些方法的参数列表必须有差异

    • 多个方法重名说明这些方法具有相近但又有差异的功能

    • 重载实现了多态的效果

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      public class BankAccount {
      String ID;
      int balance;
      public BankAccount(String id) { //构造函数的重载
      this.ID = id;
      this.balance = 0;
      }
      //参数数量不同
      public BankAccount(String id, int balance) {
      this.ID = id;
      this.balance = balance;
      }
      //参数类型不同
      public BankAccount(String balanceStr) {
      this.balance = Integer.parseInt(balanceStr);
      }
      }

  4. 方法调用的参数传递:

    在参数传递时我们要考虑一个问题:程序中调用参数传递的是值还是引用?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    public class Point { //定义一个含有两个整型数字的类
    private int x;
    private int y;
    public point(int x, int y) { //构造方法
    this.x = x;
    this.y = y;
    }
    //getter方法
    public int getx() { return x;}
    pubilc int gety() { return y;}
    //setter方法
    public void setx(int x) { this.x = x;}
    public void sety(int y) { this.y = y;}
    }

    public class MainClass {
    public static void swap_1(int x, int y){
    int temp=x; x=y; y=temp;
    }
    public static void swap_2(Point p){
    int temp=p.getx(); p.setx()=p.gety(); p.sety()=temp;
    }
    public static void main(String[] args){
    Point p = new Point(1, 2);
    swap_1(p.getx(), p.gety());
    swap_2(p);
    }
    }

    很显然,在上述代码中swap_1采取的策略是传递值,即是把p.xp.y的值复制了一份作为参数传入swap_1,这样做并不能达到我们希望的交换p.xp.y的值的效果。而swap_2中采取的策略是传递引用本身(用C语言的话说就是传递的是p这个对象的指针),这样就实现了两个地址上的内容的交换;

    Java中所有使用复合类型所声明的变量都是引用,任意类型声明的数组变量也是引用;

  5. ArrayList容器:相当于一个变长数组。容器中的元素实际上是对象(也就是说,容器其中的元素类型不能是int char等这样的基本类型),一些常见的基本类型可以使用它的包装类。
    基本类型对应的包装类表如下:

    | 基本类型 | 引用类型 |
    | ———— | ————- |
    | boolean | Boolean |
    | int | Integer |
    | char | Character |
    | float | Float |
    | double | Double |

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    import java.util.ArrayList; // 引入 ArrayList 类

    public class ArrayListSample {
    public void sample() {
    /* 1. 创建ArrayList */
    /* ArrayList+<类名>+数组名 = new ArrayList<>() */
    ArrayList<Bottle> bottles = new ArrayList<>();

    /* 2. 向ArrayList内加入一个元素(此外, 还可以向任意位置插入元素, 在add方法中新增参数即可) */
    Bottle bottle1 = new Bottle(/*parameters*/);
    Bottle bottle2 = new Bottle(/*parameters*/);
    /* 数组名ArrayName.add(元素名elementaryName) */
    bottles.add(bottle1);
    bottles.add(bottle2);

    /* 3. 访问ArrayList中下标为i的元素 */
    /* 数组名ArrayName.get(i) */
    Bottle bottle = bottles.get(0); // == bottle1

    /* 4. 判断元素是否在容器内 */
    if (bottles.contains(bottle)) { // true
    System.out.println("We have such a bottle!");
    }

    /* 5. ArrayList大小 */
    /* 数组名ArrayName.size() */
    int size = bottles.size();

    /* 6. 遍历ArrayList中的所有元素 */
    for (Bottle item : bottles) {
    System.out.println(item.getName()); // getName方法是Bottle类中用于获取其name属性的方法
    }

    for (int i = 0; i < bottles.size(); i++) {
    System.out.println(bottles.get(i).getName());
    }

    /* 7. 删除一个元素 */
    /* 数组名ArrayName.remove(对象名) */
    bottles.remove(bottle1);
    /* 数组名ArrayName.remove(i) */
    bottles.remove(0); // 删除了bottle2
    }
    }

    ArrayList中,元素是存储在动态数组中的,这意味着它们是通过索引(或下标)来访问的。当你使用 remove(int index) 方法移除指定索引位置的元素时,该位置及之后的所有元素都会向前移动一位,以填补被移除元素留下的空白。因此,原本位于被移除元素之后的所有元素的下标都会减少1;