构造方法
构造方法也称之为构造函数,构造器,是面向对象编程中的一个重要概念。
我们经常会使用构造方法来完成对象初始化的相关设置。构造方法在调用的时候必须配合new关键字,是不能被单独调用的。
注意:构造方法与类同名且没有返回值。构造方法只能在对象实例化的时候被调用
构造器本身是一个比较特殊的方法,方法名就是类名,没有返回值(和void是有区别的),构造器是类创建对象的唯一途径。
构造器的最大用处就是创建对象
无参构造方法
前面我们在定义对象时,发现并没有创建构造方法,但是我们依然可以使用构造方法去创建对象。
Cat one = new Cat();
这是因为,当没有指定构造方法时,系统(jvm)会自动添加无参构造方法。也就是说在一个类中至少会存在一个构造方法。便于我们的程序能够正常的执行,对象能够正常的进行实例化操作。
一个类中可以有多个构造方法,当有指定构造方法、无论是有参、无参的构造方法,都不会自动添加无参的构造方法。
有参构造方法
通过构造器为成员变量定义初始化值,这也是构造器的最最最重要的用途之一
比如:
public Cat(String name, int month, double weight, String species) {
name = name;
month = month;
weight = weight;
species = species;
}
但是若按照上述方法来写的话,实际上是有问题的,此处的代码逻辑发生了错误,遵循了一种就近原则 ——赋值过程中先优先的去找同一个作用范围内的成员进行赋值操作。只有找不到的情况下才会扩大作用范围,去类里面找。通俗来讲,上面的只是将参数的值重新覆盖了一遍,并没有按照我们想要的那样去赋值。
针对于这样的问题,我们可以有两种解决方案。
第一种,修改参数名,如:
public Cat(String name1, int month1, double weight1, String species1) {
name = name1;
month = month1;
weight = weight1;
species = species1;
}
第二种,用this.属性名=参数名
public Cat(String name, int month, double weight, String species) {
this.name = name;
this.month = month;
this.weight = weight;
this.species = species;
}
构造器小结
- 在栈内存中,会存储对象名, 在没有执行构造器创建对象并赋值时,此时对象名对应的值应为null
- 通过new关键字调用类的构造器在堆内存中分配了一块对象区域;
- 通过赋值运算符 = ,将堆内存中的对象地址赋给栈内存中的变量名;
- 例如再次给对象的属性赋值: 通过栈内存中的地址定位到对象在堆内存中的地址,找到相应的成员变量,进行一个赋值操作
this关键字
Java中使用this关键字,指向调用该方法的对象。根据this所在的位置,大致分为两种情况
- 出现在构造器中:引用该构造器正在初始化的对象
- 出现在普通方法中: 正在调用该方法的对象
this用在类定义中,获取当前对象的属性,或者调用当前对象的方法。
public Cat(String name, int month, double weight, String species) {
this.name = name;//this代表对象,只有对象才能调用成员属性和方法
this.month = month;
this.weight = weight;
this.species = species;
}
说明:
- 在类定义中,可以省略this关键字去调用属性或者方法,但是在类被编译的时候,编译器还是会加上this关键字。所以我们强烈建议在类定义的时候如果要调用该类中的普通成员变量或者方法,还是要把this给加上去
- 用static修饰的方法是不能使用this关键字的
构造方法的调用
构造方法可以出现重载的情况。
public Cat() {}
public Cat(String name) {
this.name = name;
}
public Cat(String name,int age) {
this(name);
this.age = age;
}
如上我们看出可以通过this()调用重载的构造器。
说明:
- 构造方法的调用,只能在构造方法之间来完成
- 构造方法内可以使用this()来调用构造方法(有参、无参均可,只要是申明过的),且必须放在方法体内第一行。而且不允许出现两条this()语句。
- 构造方法在类内,普通方法不能调用构造方法
- 构造方法在类外进行调用时,只能配合new关键字
类中的普通方法之间可以互相调用,如
public void run(){
Cat(); //出错,普通方法不能调用构造方法
eat();//可以调用普通方法
System.out.println("aaa");
}
总结
一个Java类中可以包含的内容
public class 类名() {
//属性
访问修饰符 数据类型 属性名;
//方法
访问修饰符 返回类型 方法名(参数列表) {
}
//构造方法
访问修饰符 类名() {
}
访问修饰符 类名(参数) {
}
}
相关练习
一、选择
B
A
D
A
C
AC
A
D
BC
二、编程
public class Person {
//名字
String name;
//年龄
int age;
//年级
int grade;
/**
* 无参无返回值的student方法
*/
public void student() {
System.out.println("我是一名学生!");
}
/**
* 带参数(性别sex)的方法
* @param s
*/
public void sex(String s) {
System.out.println("我是一个" + s + "孩!");
}
/**
* 无参无返回值的mySelf方法
*/
public void mySelf() {
System.out.println("我的名字叫" + name);
System.out.println("我今年" + age + "岁了");
System.out.println("我上" + grade + "年级了");
}
}
public class Test {
public static void main(String[] args) {
Person person = new Person();
person.name = "李梅";
person.age = 7;
person.grade = 2;
person.student();
person.sex("女");
person.mySelf();
}
}
public class Monkey {
//名称
String name;
//特征
String feature;
/**
* 无参的构造方法
*/
public Monkey() {
this.name = "长尾猴";
this.feature = "尾巴长";
System.out.println("我是使用无参构造产生的猴子:");
System.out.println("名称:" + this.name);
System.out.println("特征:" + this.feature);
System.out.println("=====================");
}
/**
* 带参的构造方法
* @param name
* @param feature
*/
public Monkey(String name,String feature) {
this.name = name;
this.feature = feature;
System.out.println("我是使用带参构造产生的猴子:");
System.out.println("名称:" + this.name);
System.out.println("特征:" + this.feature);
}
}
public class Test {
public static void main(String[] args) {
Monkey monkey1 = new Monkey();
Monkey monkey2 = new Monkey("白头叶猴","头上有白毛,喜欢吃树叶");
}
}