class Car
{
String color = "红色";
int num = 4;// 成员变量定义在类中,整个类都可以被访问。
void run()
{
System.out.println(color+".."+num);
}
}
class CarDemo
{
public static void main(String[] args)
{
Car c = new Car();//建立一个c的类类型变量,当c作为对象建立时,c的颜色和轮胎数有了默认初始化的值,这两个成员变量随着c对象的建立,在堆内存中一起建立。示例图1
c.color = "blue";//将对象c中成员变量color变为blue。这是在堆内存中改变的。
c.run();//运行c的run函数,这是输出的color是blue和4
Car c1 = new Car();//建立c1类类型变量,栈内存中有个c1,但是堆内存有new Car(),已经初始的Car内部的成员变量,c1指向new Car()的地址。示例图2.
c1.run();//输出的是red..4
c.num = 5;
Car c1=c;
c1 .color = green;
c.run();//这个是出的是green和5,因为c的num是5,而c1指向了c的地址,c1的color改变成green的时候,也就是改变c的color,这样输出c.run()就是green和5。示例图3
/*
new Car().num = 5;//对匿名对象的成员变量赋值,为5。
new Car().color = "blue";//对匿名函数的成员变量赋值,blue
new Car().run();//运行匿名函数的成员函数,输出为红色和4.虽然有前面两条指令,但是匿名函数使用即为垃圾,第三条指令运行的仍然是堆内存中Car的初始成员变量值。不会因为上面两条指令而更改。上面两条指令会各自在堆内存中建立匿名函数。用完后会在某个时间段由java虚拟机自动垃圾回收器来管理。
//基本上可以总结为,匿名对象调用属性基本没有什么意义,调用方法有意义。
Car c = new Car();
c.run();
c.num = 4;
new Car().run();
如果对一个对象进行多个成员调用,必须给这个对象起个名字。
*/
//需求:汽车修配厂。对汽车进行改装,将来的车够改成黑车,三个轮胎。
Car q = new Car();//建立q类类型变量,栈内存中有个q,但是堆内存有new Car(),已经初始的Car内部的成员变量,q指向new Car()的地址。
show(q);// 局部变量没有默认初始化值,当作用范围结束,局部变量在栈内存中的的空间会自动释放。
//上面的两条指令用匿名函数表示即为 show(new Car());因为没有对象,new Car()所以只在堆内存中存在,当要调用show()函数时,show中的返回对象c指向了new Car()的内存地址。而且使用完以后show在栈内存中的空间随即被释放示例图4
}
public static void show(Car c)//建立一个局部函数,show,返回值为汽车类型,因为这个函数的作用就是对汽车进行改装,对象是车。所以show()后面括号内部的为Car c
//若这个c改为q,那么q与上面那条指令中的q是不是同一个呢?答案是不是,
//show(Car c),当q调用此函数时,c对象在堆内存中的地址赋予了q,不论字母是否相同,两者都是两个对象。见示例图5,(重点掌握)
{
c.num = 3;//这个局部变量存在于成员函数show中,存在于栈内存中
c.color = "black";//存在于栈内存中
c.run();//局部成员函数调用成员函数。
}
}