构造方法与对象的创建
1.构造方法
当程序用类创建对象时需使用它的构造方法。
类中的构造方法的名字必须与它所在的类的名字完全相同,而且没有类型。
1.1 默认构造方法
如果类中没有编写构造方法,系统会默认该类只有一个默认的构造方法。
如:Ladder类的默认的构造方法如下,无参数,方法体中没有语句。
Ladder(){
}
1.2 自定义构造方法
类中可以自定义构造方法,多个构造方法之间的参数不同。
如果类中定义了一个或多个构造方法,则 Java 不提供默认的构造方法。
例如,下列Point类中有两个构造方法。
class Point{
int x,y;
Point(){
x = 1;
y = 1;
}
Point(int a,int b){
x = a;
y = b;
}
}
==注:==构造方法没有类型。
void Point() 不是构造方法
int Point(int a, int b) 不是构造方法
2. 创建对象
2.1 对象声明
类的名字 对象名字;
Point point;
2.2 为声明的对象分配变量
new运算符 + 类的构造方法为声明的对象分配变量,即创建对象。
- 调用默认的构造方法创建对象
class XiyoujiRenwu{
float height, weight;
String head, ear;
void speak(String s){
System.out.println(s);
}
}
public class Example{
public static void main(String[] args){
XiyoujiRenwu zhubajie;
zhubajie = new XiyoujiRenwu(); //为对象分配变量
}
}
- 调用自定义的构造方法创建对象
class Point{
int x,y;
Point(int a,int b){
x = a;
y = b;
}
}
public class Example{
public static void main(String[] args){
Point p1,p2;
p1 = new Point(1,2); //为对象分配变量
p2 = new Point(23,35);
// p2 = new Point(); //错误,不提供默认构造方法
}
}
3. 使用对象
使用点访问符 " . " 访问自己的变量和类中的方法。
对象.变量;
对象.方法;
类中的方法可以操作成员变量,当对象调用该方法时,方法中出现的成员变量就是该对象的成员变量。
下面的示例中,对象调用了speak方法,使head的状态也发生了变化。
class XiyoujiRenwu{
float height, weight;
String head, ear;
void speak(String s){
head = "歪着头";
System.out.println(s);
}
}
public class Example4_3 {
public static void main(String[] args) {
XiyoujiRenwu zhubajie,sunwukong;
zhubajie = new XiyoujiRenwu();
sunwukong = new XiyoujiRenwu();
zhubajie.height = 1.80f;
zhubajie.head = "大头";
zhubajie.ear = "一双大耳朵";
sunwukong.height = 1.75f;
sunwukong.weight = 1000f;
sunwukong.head = "秀发飘飘";
System.out.println("猪八戒的身高:"+ zhubajie.height);
System.out.println("猪八戒的头:"+ zhubajie.head);
System.out.println("孙悟空的重量:"+ sunwukong.weight);
System.out.println("孙悟空的头:"+ sunwukong.head);
zhubajie.speak("俺老猪我想娶媳妇");
System.out.println("猪八戒现在的头:"+ zhubajie.head);
sunwukong.speak("老孙我重1000斤,我想骗八戒背我");
System.out.println("孙悟空现在的头:"+ sunwukong.head);
}
}
运行结果如下:
猪八戒的身高:1.8
猪八戒的头:大头
孙悟空的重量:1000.0
孙悟空的头:秀发飘飘
俺老猪我想娶媳妇
猪八戒现在的头:歪着头
老孙我重1000斤,我想骗八戒背我
孙悟空现在的头:歪着头
4. 对象的引用和实体
对象(变量)本身负责存放引用,以确保对象可以操作分配给该对象的变量以及调用类中的方法。分配给对象的变量被习惯地称作对象的实体。
4.1 避免使用空对象
没有实体的对象称作空对象。不能让一个空对象去调用方法产生行为。否则出现异常NullPointerException.
4.2 重要结论
一个类声明的两个对象如果具有相同的引用,两者就具有完全相同的变量(实体)。
在Java中,允许对同一个类的两个对象 object1 和 object2 做如下赋值操作:
object2 = object1;
这样 object2 中存放的将是 object1 的值,即 object1 的引用。
4.3 垃圾收集
这种机制周期地检测某个实体是否已不再被任何对象所拥有(引用),如果发现这样的实体,就释放实体占有的内存。
如果希望 Java 虚拟机立刻进行“垃圾收集”操作,可以让System类调用 gc() 方法。
4.4 输出引用
-
使用System.out.println(object) 输出引用值,会给引用值添加前缀信息类名@,然后输出添加了前缀信息的数据。
-
可以让System 类调用静态方法 int identityHashCode(Object object) 返回对象 object 的引用。
int address = System.identityHashCode(object);
下面的例子将对象p2的引用赋给了对象p1.
class Point{
int x,y;
void setxy(int m,int n){
x = m;
y = n;
}
}
public class Example4_4 {
public static void main(String[] args) {
Point p1 = null;
Point p2 = null;
p1 = new Point();
p2 = new Point();
System.out.println("p1的引用:" + p1);
System.out.println("p2的引用:" + p2);
p1.setxy(1111,2222);
p2.setxy(-100,-200);
System.out.println("p1的x,y坐标:" + p1.x + "," + p1.y);
System.out.println("p2的x,y坐标:" + p2.x + "," + p2.y);
p1 = p2;
System.out.println("将p2的引用值赋给p1后:");
int address = System.identityHashCode(p1);
System.out.printf("p1的引用:%x\n",address);
address = System.identityHashCode(p2);
System.out.printf("p2的引用:%x\n",address);
System.out.println("p1的x,y坐标:" + p1.x + "," + p1.y);
System.out.println("p2的x,y坐标:" + p2.x + "," + p2.y);
}
}
运行结果如图:
p1的引用:classExample.Point@10f87f48
p2的引用:classExample.Point@4e50df2e
p1的x,y坐标:1111,2222
p2的x,y坐标:-100,-200
将p2的引用值赋给p1后:
p1的引用:4e50df2e
p2的引用:4e50df2e
p1的x,y坐标:-100,-200
p2的x,y坐标:-100,-200