java-类和对象

注意
本文档属于个人笔记,个人水平有限,请酌情采纳,有任何错误可在评论区指出
  1. 依赖(Dependency)
  • (“use a”)
  • 依赖关系使用虚线加箭头表示
  • 如果一个类 A 的方法操纵了类 B 的对象,我们就说类 A 依赖于类 B
/images/all/image-20221106204439110.png

解释:学生编写程序需要使用电脑,因此学生对电脑产生了依赖

2.关联(Association)

  • (“has a”)
  • 关联关系使用实线加箭头表示
  • 聚合关系意味着类 A 的成员变量中包含类 B
/images/all/image-20221106205101968.png

解释:一个老师可以有多名学生

3.继承(inheritance)

  • (“is a”)
  • 继承关系使用实线加三角形表示
/images/all/image-20221106182849835.png

4.聚合(Aggregation)

  • 聚合关系使用实线加空心菱形表示
  • 聚合是一种特殊的关联关系,它是较强的一种关联关系
  • 强调集体和个体的关系
/images/all/image-20221106203657063.png

解释:一个班级有多个学生,类 Student 将成为类 Classes 的成员变量

5.组合(Composition)

  • 组合是一种特殊的关联关系,它是较强的一种关联关系
  • 强调整体和局部的关系
/images/all/image-20221106205417583.png
 1import java.time.LocalDate;
 2
 3public class Main  {
 4    public static void main(String[]args) {
 5        LocalDate localDate = LocalDate.now();
 6        // plusDays会产生一个新对象,原对象不变, 100天后是哪一天
 7        System.out.println(localDate.plusDays(100));
 8        int year = localDate.getYear();
 9        int month = localDate.getMonthValue();
10        int day = localDate.getDayOfMonth();
11        // 当前日期
12        System.out.println(year + "/" + month + "/" + day);
13
14        // 设置为本月1号
15        LocalDate start = localDate.minusDays(day - 1);
16        // 1号是星期几
17        System.out.println(start.getDayOfWeek().getValue());
18    }
19}

不要在构造方法和其他方法中定义和成员变量同名的变量

 1public class Main {
 2    public static void main(String[] args) {
 3        Test t = new Test(1,"111");
 4        // Error
 5        System.out.println(t.id);
 6        // Error
 7        System.out.println(t.name);
 8    }
 9}
10
11class Test {
12    private int id;
13    private String name;
14
15    public Test(int a,String b) {
16        // 在构造方法中定义和成员变量相同的局部变量会使成员变量失效
17        // Error
18        int id = 11;
19        String name = "ok";
20        this.id = 10;
21        this.name = "okk";
22    }
23}
  • 只访问对象而不修改对象的方法有时称为访问器方法(accessor method)
  • 访问对象并且修改对象的方法称为更改器方法(mutator method)

静态方法:只需要访问静态变量时使用

 1public class Main {
 2    public static void main(String[] args) {
 3        Test t = new Test();
 4        Test t1 = new Test();
 5        Test t2 = new Test();
 6        Test t3 = new Test();
 7        System.out.println(t.getId());
 8        System.out.println(t1.getId());
 9        System.out.println(t2.getId());
10        t3.setId(10);
11        System.out.println(t3.getId());
12        System.out.println(Test.getNextId());
13        System.out.println(Test.NUMBER);
14    }
15}
16
17class Test {
18    public static final int NUMBER = 10;
19    private static int nextId = 1;
20    private int id;
21
22    public Test(){
23        id = nextId;
24        nextId++;
25    }
26    public void setId(int id) {
27        this.id = id;
28    }
29    public int getId() {
30        return id;
31    }
32
33    public static int getNextId() {
34        return nextId;
35    }
36}

Java程序设计语言总是采用按值调用

 1public class StaticTest {
 2    public static void main(String[] args)
 3    {
 4        /*
 5         * Test 1: Methods can't modify numeric parameters
 6         */
 7        System.out.println("Testing tripleValue:");
 8        double percent = 10;
 9        System.out.println("Before: percent=" + percent);
10        tripleValue(percent);
11        System.out.println("After: percent=" + percent);
12
13        /*
14         * Test 2: Methods can change the state of object parameters
15         */
16        System.out.println("\nTesting tripleSalary:");
17        Employee harry = new Employee("Harry", 50000);
18        System.out.println("Before: salary=" + harry.getSalary());
19        tripleSalary(harry);
20        System.out.println("After: salary=" + harry.getSalary());
21
22        /*
23         * Test 3: Methods can't attach new objects to object parameters
24         */
25        System.out.println("\nTesting swap:");
26        Employee a = new Employee("Alice", 70000);
27        Employee b = new Employee("Bob", 60000);
28        System.out.println("Before: a=" + a.getName());
29        System.out.println("Before: b=" + b.getName());
30        swap(a, b);
31        System.out.println("After: a=" + a.getName());
32        System.out.println("After: b=" + b.getName());
33    }
34
35    public static void tripleValue(double x) // doesn't work
36    {
37        x = 3 * x;
38        System.out.println("End of method: x=" + x);
39    }
40
41    public static void tripleSalary(Employee x) // works
42    {
43        x.raiseSalary(200);
44        System.out.println("End of method: salary=" + x.getSalary());
45    }
46
47    public static void swap(Employee x, Employee y)
48    {
49        Employee temp = x;
50        x = y;
51        y = temp;
52        System.out.println("End of method: x=" + x.getName());
53        System.out.println("End of method: y=" + y.getName());
54    }
55}
56
57class Employee // simplified Employee class
58{
59    private String name;
60    private double salary;
61    public Employee(String n, double s)
62    {
63        name = n;
64        salary = s;
65    }
66
67    public String getName()
68    {
69        return name;
70    }
71
72    public double getSalary()
73    {
74        return salary;
75    }
76
77    public void raiseSalary(double byPercent)
78    {
79        double raise = salary * byPercent / 100;
80        salary += raise;
81    }
82}

方法签名:包括方法名和参数类型

注意返回类型不是方法签名的一部分,所以方法签名相同但是返回值不同不构成重载!

1indexof(int)
2indexof(int,int)
3indexof(int,int,int)
4indexof(String)
5indexof(String,int)

如果多个方法有相同的名字、不同的参数,便产生了重载

重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。

重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

区别点 重载方法 重写方法
参数列表 必须修改 一定不能修改
返回类型 可以修改 一定不能修改
异常 可以修改 可以减少或删除,一定不能抛出新的或者更广的异常
访问 可以修改 一定不能做更严格的限制(可以降低限制)

静态初始化代码块(只调用 1 次)->选择指定构造函数->成员变量默认赋值->对象初始化代码块->构造函数执行完毕

 1public class Main {
 2    public static void main(String[] args) {
 3        // fill the staff array with three Employee objects
 4        Employee[] staff = new Employee[3];
 5
 6        staff[0] = new Employee("Harry", 40000);
 7        staff[1] = new Employee(60000);
 8        staff[2] = new Employee();
 9
10        // print out information about all Employee objects
11        for (Employee e : staff) {
12            System.out.println("name=" + e.getName() + ",id=" + e.getId() + ",salary="
13                    + e.getSalary());
14        }
15
16    }
17}
18
19class Employee {
20    // three overloaded constructors
21    public Employee(String n, double s) {
22        name = n;
23        salary = s;
24    }
25
26    public Employee(double s) {
27        // calls the Employee(String, double) constructor
28        this("Employee #" + nextId, s);
29    }
30
31    // the default constructor
32    public Employee() {
33        // name initialized to ""--see below
34        // salary not explicitly set--initialized to 0
35        // id initialized in initialization block
36    }
37
38    public String getName() {
39        return name;
40    }
41
42    public double getSalary() {
43        return salary;
44    }
45
46    public int getId() {
47        return id;
48    }
49
50    private static int nextId;
51
52    private int id;
53    private String name = ""; // instance field initialization
54    private double salary;
55
56    // static initialization block
57    static {
58        Random generator = new Random();
59        // set nextId to a random number between 0 and 9999
60        nextId = generator.nextInt(10000);
61    }
62
63    // object initialization block
64    {
65        id = nextId;
66        nextId++;
67    }
68}