关于java:详解Java的对象创建

41次阅读

共计 5054 个字符,预计需要花费 13 分钟才能阅读完成。

1. 前言

在《还不分明怎么面向对象?》和《面向对象再探索》两篇文章中,都介绍了对于面向对象程序设计的概念和特点。其中也波及到了许多代码,比方:

Dog dog = new Dog();

这篇文章就次要来谈谈创建对象时的具体操作。

2. 引入例子

上面是一个 Dog 类:

/**
 * @author Xing Xiaoguan (xingrenguanxue)
 */

public class Dog {
    private String name;
    private int age;
    private String address;
    
    public void say() {System.out.println("我叫" + name + ",往年" + age + "岁了,家住" + address + ",汪汪汪...");
    }

    //getters 和 setters
}

上面是一个 Test 类,创立了一个 Dog 对象,而后进行相干操作:

public class Test {public static void main(String[] args) {Dog dog = new Dog();
        dog.setName("哮天犬");
        dog.setAge(1);
        dog.setAddress("光明小区")
        dog.say();}
}

输入:

我叫小黑,往年 1 岁了,家住光明小区,汪汪汪...

3. 对象和对象变量

对象是依据类发明进去的,咱们应用的是具体的对象,而不是类。要想应用对象,那对象必须得先被创立进去才行。上面一行代码是创建对象的语句:

Dog dog = new Dog();

咱们将其分成三局部来看:

(1)new :如果你想创立一个对象,那么必须应用 new 操作符。

(2)Dog():这是一个结构器,结构器是一个非凡的办法。通过调用该结构器,咱们能够创立并初始化一个对象进去。

new Dog()连起来就能正确地创立出一个对象了。然而咱们发明进去的对象并不只会应用一次,而会应用许多次,所以咱们须要给该对象 “取一个名字”,保障它“随叫随到”。这就须要第三局部了:

(3)Dog dog:申明一个 Dog 类型的、名为 dog 的变量。它就相似于 int number,申明一个int 类型的 number 变量。

而后咱们应用 = 进行赋值(援用),便给创立出的对象 “取一个名字”dog,当前能够称它为dog 对象。

这里可能会呈现一个误区,认为:Dog dog局部便能创立出一个 dog 对象,这是谬误的。该当明确:dog从头到尾都只是一个 变量 而已。这个变量和应用 int numberString str 等形式申明的变量,除了类型不同之外并无差别。

真正创立出对象的是 new Dog() 局部。

上面解释一下 “取一个名字” 是什么意思。

在 Java 中,对象变量中存储的并不是对象,真正的变量在内存的某个中央躺着呢。该变量记录的是对象在内存中的地位,咱们有了对象变量,就有了对象的地位,有了地位,就能找到真正的对象。

看上面的代码:

public class Test {public static void main(String[] args) {Dog dog = new Dog();// 创立出一个 dog 对象
        System.out.println(dog);// 打印 dog
    }
}
打印后果:basic.Dog@1b6d3586

1b6d3586便是 dog 对象在内存中的地址。

4. 结构器

后面提到,创立一个对象的关键在于应用 new 操作符和结构器。结构器是一个非凡的办法,通过调用结构器,咱们能够创立并初始化一个对象进去。

结构器的特点:

  1. 有一个拜访修饰符
  2. 结构器的名字和类名雷同
  3. 结构器没有返回值
  4. 结构器要和 new 操作符一起应用
  5. 结构器能够有 0 个、1 个或多个结构器
  6. 一个类中能够有多个结构器

4.1. 无参结构器

即没有参数的结构器,如Dog()。无参结构器是 Java 默认的结构器,如果你在编写类时没有写结构器,那么 Java 会在类中默认提供一个无参结构器。

Dog 类中并没有写结构器,Dog类默认领有上面的无参结构器:

public Dog() {}

4.2. 有参结构器

有参结构器,即有参数的结构器。例如:

public Dog(String n, int a, String addr) {
    name = n;
    age = a;
    address = addr;
}

这个有参结构器非常简单,别离给 na 参数传值,而后给对象的属性赋值。美中不足的是参数的变量名获得不够“见名知意”,所以咱们通常这样写:

public Dog(String name, int age, String address) {
    this.name = name;
    this.age = age;
    this.address = address;
}

参数的名字和对象的成员变量名一样,这样,参数的意义就很清晰了。在赋值的时候,应用 this 关键字辨别二者,因为 this 代表咱们所创立的对象,this.name即对象的成员变量。

有了有参结构器,咱们就能够在创建对象时初始化对象的属性,比方:

public static void main(String[] args) {Dog dog = new Dog("小狗有参", 1, "地球");
    dog.say();}

输入:

我叫小狗有参,往年 1 岁了,家住地球,汪汪汪...

4.3. 多个结构器的应用

先理解一个概念——重载 (overloading)。重载是指在一个类中,有几个办法的办法名字雷同,而参数不同。返回值类型能够雷同也能够不雷同。留神: 每个重载的办法的参数列表必须举世无双

留神:参数列表的举世无双是指 参数列表的类型的举世无双

千万不要认为 func(String name)func(String address)这两个办法的参数列表是不同的。它俩应该这样看:func(String)func(String),所以 这俩办法是雷同的

下图是 String 类中的局部办法的重载状况,可从中领会参数列表的举世无双:

为什么要求参数列表必须举世无双呢?

这就得介绍另一个概念——办法的签名。办法的签名是指要残缺地形容一个办法,须要指出 办法名 参数类型。留神:办法的返回类型不是签名的一部分。

所以在 Java 中,办法名和参数列表能确定一个办法。不存在办法名和参数列表雷同,而返回类型不同的办法们。

而重载要求的是办法名雷同,参数列表不同。从办法的签名角度来看,重载办法之间本就是不同的办法。

因为重载的存在,咱们能够在一个类中编写多个参数列表不同的结构器,使该类具备多种创建对象的模式。比方:

public class Dog {
    private String name;
    private int age;
    private String address;
    
    public Dog() {// 无参结构器,有其余结构器存在,零碎不会默认提供}

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Dog(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
    
    public void say() {System.out.println("我叫" + name + ",往年" + age + "岁了,家住" + address + ",汪汪汪...");
    }

    //getters 和 setters
}

写了三种结构器,便有三种创建对象的形式:

Dog dog = new Dog("小狗", 1, "太阳系");
Dog dog1 = new Dog("小狗 1", 2);
Dog dog2 = new Dog();

编译器会依据咱们提供的参数匹配到适合的结构器。

留神:无参结构器只有在咱们没有编写任何结构器时,零碎才会默认提供。所以当一个类中有其余结构器时,如果咱们须要无参结构器,那么必须手动编写进去,零碎不会默认提供。

4.4. 结构器之间的关系

在类中,一个结构器能够调用另一个结构器。如下例:

/**
 * @author Xing Xiaoguan (xingrenguanxue)
 */

public class Dog {
    private String name;
    private int age;
    private String address;

    public Dog(String name, int age) {this(name, age, "银河系");// 调用另一个结构器
        System.out.println("两个参数的结构器");
    }

    public Dog(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
        System.out.println("三个参数的结构器");
    }
    
    public void say() {System.out.println("我叫" + name + ",往年" + age + "岁了,家住" + address + ",汪汪汪...");
    }

    //getters and setters...
}

应用 Dog(String, int) 创建对象:

public class Test {public static void main(String[] args) {Dog dog = new Dog("小狗有参", 1);
        dog.say();}
}

输入:

三个参数的结构器
两个参数的结构器
我叫小狗有参,往年 1 岁了,家住银河系,汪汪汪...

咱们在结构器的 第一行语句 中应用 this(...) 来调用另一个结构器。留神:肯定要是第一行语句。

5. 对象属性的初始化

所谓初始化,就是咱们在创建对象同时设置对象的属性值。

5.1. 默认的属性值

当咱们创建对象时如果不显式地设置属性值,对象的属性值会被初始化为默认值。

数值的默认值为0,布尔值的默认值为false,对象援用的默认值为null

如下例中的 Dog 类的属性值:

public class Dog {
    private String name;
    private int age;
    private String address;
    
    public void say() {System.out.println("我叫" + name + ",往年" + age + "岁了,家住" + address + ",汪汪汪...");
    }
} 

创建对象:

public static void main(String[] args) {Dog dog = new Dog();
    dog.say();}

输入:

我叫 null,往年 0 岁了,家住 null,汪汪汪...

5.2. 间接设置属性值

咱们能够在类中间接设置类的属性值,这样一来,依据该类创立的对象的属性值就确定了。

如下例中 Dog 类的属性值:

public class Dog {
    private String name = "小黑";
    private int age = 2;
    private String address = "太阳系";
    
    public void say() {System.out.println("我叫" + name + ",往年" + age + "岁了,家住" + address + ",汪汪汪...");
    }
} 

这时再创建对象:

public static void main(String[] args) {Dog dog = new Dog();
    dog.say();}

输入:

我叫小黑,往年 2 岁了,家住太阳系,汪汪汪...

5.3. 应用结构器初始化

(一) 当结构器中没有显式地设置对象的属性值时,这些属性值会被初始化为默认值。如上面的无参结构器:

public Dog() {}

创建对象:

public static void main(String[] args) {Dog dog = new Dog();
    dog.say();}

输入:

我叫 null,往年 0 岁了,家住 null,汪汪汪...

(二)能够在无参结构器的办法体中初始化属性值:

public Dog() {
    name = "小黑";
    age = 2;
    address = "宇宙";
}

创建对象:

public static void main(String[] args) {Dog dog = new Dog();
    dog.say();}

输入:

我叫小黑,往年 2 岁了,家住宇宙,汪汪汪...

(三)也能够应用有参结构器,对象会依照咱们传入的变量初始化属性值:

public Dog(String name, int age, String address) {
    this.name = name;
    this.age = age;
    this.address = address;
}

创建对象:

public static void main(String[] args) {Dog dog = new Dog("小黑", 3, "南极");
    dog.say();}

输入:

我叫小黑,往年 3 岁了,家住南极,汪汪汪...

如有谬误,还请斧正。

正文完
 0