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
import java.time.LocalDate;

public class Main  {
    public static void main(String[]args) {
        LocalDate localDate = LocalDate.now();
        // plusDays会产生一个新对象,原对象不变, 100天后是哪一天
        System.out.println(localDate.plusDays(100));
        int year = localDate.getYear();
        int month = localDate.getMonthValue();
        int day = localDate.getDayOfMonth();
        // 当前日期
        System.out.println(year + "/" + month + "/" + day);

        // 设置为本月1号
        LocalDate start = localDate.minusDays(day - 1);
        // 1号是星期几
        System.out.println(start.getDayOfWeek().getValue());
    }
}

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

public class Main {
    public static void main(String[] args) {
        Test t = new Test(1,"111");
        // Error
        System.out.println(t.id);
        // Error
        System.out.println(t.name);
    }
}

class Test {
    private int id;
    private String name;

    public Test(int a,String b) {
        // 在构造方法中定义和成员变量相同的局部变量会使成员变量失效
        // Error
        int id = 11;
        String name = "ok";
        this.id = 10;
        this.name = "okk";
    }
}
  • 只访问对象而不修改对象的方法有时称为访问器方法(accessor method)
  • 访问对象并且修改对象的方法称为更改器方法(mutator method)

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

public class Main {
    public static void main(String[] args) {
        Test t = new Test();
        Test t1 = new Test();
        Test t2 = new Test();
        Test t3 = new Test();
        System.out.println(t.getId());
        System.out.println(t1.getId());
        System.out.println(t2.getId());
        t3.setId(10);
        System.out.println(t3.getId());
        System.out.println(Test.getNextId());
        System.out.println(Test.NUMBER);
    }
}

class Test {
    public static final int NUMBER = 10;
    private static int nextId = 1;
    private int id;

    public Test(){
        id = nextId;
        nextId++;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getId() {
        return id;
    }

    public static int getNextId() {
        return nextId;
    }
}

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

public class StaticTest {
    public static void main(String[] args)
    {
        /*
         * Test 1: Methods can't modify numeric parameters
         */
        System.out.println("Testing tripleValue:");
        double percent = 10;
        System.out.println("Before: percent=" + percent);
        tripleValue(percent);
        System.out.println("After: percent=" + percent);

        /*
         * Test 2: Methods can change the state of object parameters
         */
        System.out.println("\nTesting tripleSalary:");
        Employee harry = new Employee("Harry", 50000);
        System.out.println("Before: salary=" + harry.getSalary());
        tripleSalary(harry);
        System.out.println("After: salary=" + harry.getSalary());

        /*
         * Test 3: Methods can't attach new objects to object parameters
         */
        System.out.println("\nTesting swap:");
        Employee a = new Employee("Alice", 70000);
        Employee b = new Employee("Bob", 60000);
        System.out.println("Before: a=" + a.getName());
        System.out.println("Before: b=" + b.getName());
        swap(a, b);
        System.out.println("After: a=" + a.getName());
        System.out.println("After: b=" + b.getName());
    }

    public static void tripleValue(double x) // doesn't work
    {
        x = 3 * x;
        System.out.println("End of method: x=" + x);
    }

    public static void tripleSalary(Employee x) // works
    {
        x.raiseSalary(200);
        System.out.println("End of method: salary=" + x.getSalary());
    }

    public static void swap(Employee x, Employee y)
    {
        Employee temp = x;
        x = y;
        y = temp;
        System.out.println("End of method: x=" + x.getName());
        System.out.println("End of method: y=" + y.getName());
    }
}

class Employee // simplified Employee class
{
    private String name;
    private double salary;
    public Employee(String n, double s)
    {
        name = n;
        salary = s;
    }

    public String getName()
    {
        return name;
    }

    public double getSalary()
    {
        return salary;
    }

    public void raiseSalary(double byPercent)
    {
        double raise = salary * byPercent / 100;
        salary += raise;
    }
}

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

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

indexof(int)
indexof(int,int)
indexof(int,int,int)
indexof(String)
indexof(String,int)

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

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

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

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

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

public class Main {
    public static void main(String[] args) {
        // fill the staff array with three Employee objects
        Employee[] staff = new Employee[3];

        staff[0] = new Employee("Harry", 40000);
        staff[1] = new Employee(60000);
        staff[2] = new Employee();

        // print out information about all Employee objects
        for (Employee e : staff) {
            System.out.println("name=" + e.getName() + ",id=" + e.getId() + ",salary="
                    + e.getSalary());
        }

    }
}

class Employee {
    // three overloaded constructors
    public Employee(String n, double s) {
        name = n;
        salary = s;
    }

    public Employee(double s) {
        // calls the Employee(String, double) constructor
        this("Employee #" + nextId, s);
    }

    // the default constructor
    public Employee() {
        // name initialized to ""--see below
        // salary not explicitly set--initialized to 0
        // id initialized in initialization block
    }

    public String getName() {
        return name;
    }

    public double getSalary() {
        return salary;
    }

    public int getId() {
        return id;
    }

    private static int nextId;

    private int id;
    private String name = ""; // instance field initialization
    private double salary;

    // static initialization block
    static {
        Random generator = new Random();
        // set nextId to a random number between 0 and 9999
        nextId = generator.nextInt(10000);
    }

    // object initialization block
    {
        id = nextId;
        nextId++;
    }
}