My Blog

Java面向对象三

学习笔记,仅供参考

参考B站Mirco_Frank - java与生活

本文重点:toString(); | 构造方法 | static


toString();

toString(); 方法用于返回以一个字符串表示的 Number 对象值。

比如,当直接输出某对象时,System.out.println(zhangDog), 它会调用 zhangDog 的 toString(); 方法,得到的值为 类所在的包名.类名 + @ + 哈希值。虽然并没有写 toString(); 方法,但能调用它,是因为 toString(); 继承于 Object 类。而默认的 toString(); 程序为

public String toString() {
    return getClass().getName()+'@'+Integer.toHexString(hashCode());

}

而所输出的这些值是人看不懂的,所以为了让人能知道输出对象的信息,就用重写 toString(); 方法。

重写的方法有:

  1. 自己手写,将返回哈希值修改为对象信息

  2. 利用 IDEA 自动生成,Alt+Insert -> 选择 toString -> 选择变量生成即可

  3. 直接调用 Lombok 包中写好的程序,只需在类上引入注解 ‘@ToString’ or ‘@Data

toString(); 方法重写前后对比图如下

对比图


构造方法

之前提到过,构造函数相当于注册生成一个账号。Dogs zhangDog = new Dogs(); 其中 Dogs() 就是构造方法或者叫构造器。

之前的过程是先注册再填信息,还可以在注册时就填写信息,这种就叫做初始化,即初始化是定义和使用一次完成。就好像数组一样有两种常见的初始方法。

// 第一种 先定义后使用
int[] arr = new int[4];
arr[0] = 0;

// 第二种 初始化
int[] arr = {0, 1, 2, 3};

所以想要利用初始化的方法一次完成,就要在 Dogs 类中重新写一个构造方法。之所以是重写,是因为每当类被创建时,就会自带一个看不见的构造方法,因此可以像 new Dogs() 直接使用。

构造方法有两种类型,无参构造方法和有参构造方法

// 无参构造方法
public Dogs() {

}

// 有参构造方法
public Dogs(String name, int age, String variety) {
    this.name = name;
    this.age = age;
    this.variety = variety;
}

当然构造方法也可用 IDEA 自动生成,Alt+Insert,选择 Constructor,选择参数即可。

注意: 当写了有参构造方法后一定要写一个无参构造方法,使构造方法达到了方法重载的效果,这样在用时既可用无参的又可用有参的。

若要不写无参构造方法,就会达到方法的重写,将默认的覆盖掉,这样在使用时就只能用有参的。


static

之前故事中,小伙通过变量的封装解决了变量被任意修改的风险。随后,小区的居委会找到小伙,想让小伙在程序中加入小区通告的功能和能让用户能查到狗属于哪个小区,以便能通知到小区住户关于狗狗的管理措施。于是,小伙开始新的挑战。

小伙发现可以使用 static 修饰变量,以使得变量属于类,不再被对象所使用。

public class() {
    // 之前的内容...

    // 添加小区的名字
    public static String plot = "NanG";

    // 添加小区通知打针的功能
    public static void inject() {
        System.out.println("所有用户,月底打针!");
    }
}

/*******分割线***********/

public class Test() {
    public static void main(String args[]) {
        // 使用新功能, 直接调用类名来使用
        // 使用静态变量
        System.out.println("Plot name = "+Dogs.plot);

        // 调用静态方法 
        System.out.println(Dogs.inject());
    }
}

与之前相同,若是将成员变量公开,则会被任意对象调用修改。故上述的静态变量也要是私有的。让用户通过调用类的公开方法来间接读写。

// 将静态变量修改为私有的
private static String plot = "NanG";

// 给出外部获取变量值的方法
public static String getPlot() {
    // 因为变量属于类,故直接返回静态变量即可
    return plot;    
}

static 用法中,设置静态变量是一种,还有就是 static 单例设计模式

经查阅,单例模式用于一个类只能实例一次对象,而且实例的对象可以对外提供访问。例如生活中的太阳、月亮、地球等独一无二的对象,都是要用单例模式去实现。

然而为了让类只能实例一次对象,就不能在提供构造方法去实例对象,即该类的构造方法是私有的,外部要实例化对象就要通过类的方法去间接实例化。我认为,这种单例模式就像是将该类的构造方法封装为私有,在类的内部先实例化对象,再通过公开的方法将对象传出去。

public class Earth() {
    // 1. 在类中先实例一个对象,且设为静态私有的
    private static Earth earth = new Earth();

    // 2. 将该类的构造方法设为私有,使得外部不在能通过构造方法来实例化
    private Earth() {

    }

    // 3. 给出外部间接实例化的方法
    public static Earth getInstance() {
        return earth;
    }
}

单例模式获取的对象与构造方法创建的对象

单例模式创建的对象,所有的变量名均指向同一块区域。

构造方法创建的对象,每一个变量名均指向各自的区域。

区别

所以单例模式可以减小对内存空间的消耗