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岁了,家住南极,汪汪汪...
如有谬误,还请斧正。