六、java的面向对象程序设计(类和对象)
/**
* 面向对象之一
* 类与对象
*/
/**
* 对象的实例化过程:
* 1,java中所有类型在内存的分配情况
* a,基本类型"变量"char,byte,short,int,long,float,double,boolean存储在堆栈中
* 堆栈是通过堆栈指针按照先进先出的读取方式存储数据,存取速度快.
* 堆栈位于RAM(随机访问存储器,可读可写)
* b,"常量"(主要指通过final static关键字定义的常量)存储在ROM(只读存储器)中
* c,"对象"存储在堆中
* 堆按照先进后出的存储方式存储数据,存储速度较慢.堆同样位于RAM.
* d,"引用"存储在堆栈中,存储的是对象的首地址,并通过地址指针指向位于堆中的对象.
*
* 2,对象的实例化过程
* 创建一个类的引用时,如Person p1这时将在堆栈中创建一个引用p1,
* 当p1 = new Person()时,在堆中创建了一个Person类型的对象,并且将该对象在堆中的首地址赋值给p1这个引用.
*
* 3,引用的比较
* 我们创建两个对象:
* Person p1 = new Person(); Person p2 = new Person();
* 这时,堆内存中存放了两个Person类型的对象,这两个对象的首地址不相同,
* 所以,第一个对象的引用p1和第二个对象的引用p2(p1,p2存储着对象的首地址)的值不相同.
*
* 4,对象和引用的生命周期:
* 大体来说,创建对象的引用和创建一个变量一样,都是分配在堆栈中的,
* 在方法中我们按照先后顺序定义的变量和引用,将在该方法结束后,同样按照先定义先释放的方式结束其生命周期.
* 但是对于一个引用,由于存放的是堆中对象的首地址,所以,在方法中当我们将null赋值给这个引用时,例如p1 = null,同样可以提前结束p1的生命周期.
* 当p1 = null后,结束的是引用的生命,但是堆中的对象并没有结束,而这个对象将等待java的垃圾回收器,在一个特殊的时间将其清除.
*/
class Person
{
private int age;
public void setAge(int age)
{
this.age = age;
}
public void shout()
{
int age = 23;//方法中定义的局部变量会覆盖类中定义的同名的成员变量;
/*
{
int age = 30;//错误,java中不允许在方法中定义与全局变量同名的局部变量.
}
*/
/*
for(int age = 0; age<10; age++){}//错误,同上面
*/
/*
while(true){ int age = 50;}//错误,同上面
*/
System.out.println(age);
}
public void shout2()
{
System.out.println("My age is " + age);
}
public String toString()//通过覆盖父类的toString方法,只打印引用的十六进制哈希值.
{
return '@' + Integer.toHexString(hashCode());
}
}
public class ClassType {
/**
* @param args
*/
public static void main(String[] args) {
/*创建对象*/
System.out.println("创建对象");
Person p1;//这里创建的是一个类的引用,没有对象.
p1 = new Person();//通过new关键字将类的引用指向这个对象.
Person p2 = new Person();//创建Person类的引用p2并指向Person对象.
/*对象的赋值*/
System.out.println("对象赋值");
p1.setAge(20);p2.setAge(30);//为两个对象分别赋值
p1.shout();p2.shout();//打印23,局部变量覆盖了类成员变量
p1.shout2();p2.shout2();//分别打印20,30(说明两个对象的成员age虽然同属同一个类,但它们是两个引用的不同变量)
/*引用的生命周期*/
System.out.println("引用的生命周期");
p1 = null;//提前结束该引用的生命周期,
System.out.println(p1);//打印null
System.out.println(p2);//打印@a90653
try
{
p1.shout();
p1.shout2();
}
catch(Exception e){}
//我们这里是通过异常处理才让程序继续执行下去的,并且会报告一个空引用的错误.
//也就是说由于我们在让引用为null后,不能再通过这个引用调用Person对象的方法了
/*引用的比较*/
System.out.println("引用的比较");
String str1 = new String("abc");//我们为string对象赋相同的初始值.
String str2 = new String("abc");
System.out.println(str1 == str2);//结果为false
//由于str1和str2是两个不同的引用,他们的首地址不相同.所以打印的结果是false
System.out.println(str1.equals(str2));//结果是true
//通过equals方法比较类型的内容.内容都是abc所以是true.
str1 = str2;
System.out.println(str1 == str2);//true
System.out.println(str1.equals(str2));//true
}//在右花括号后,堆栈中的引用p1,p2按照先定义先结束的方式结束其生命周期.
}
/* ~~Console output~~
创建对象
对象赋值
23
23
My age is 20
My age is 30
引用的生命周期
null
@a90653
引用的比较
false
true
true
true
*/