共计 3669 个字符,预计需要花费 10 分钟才能阅读完成。
1、对象存储
对象的存储是在内存中有地址与值,那么地址与值是使用栈与堆的形式存储。
1.1、案例
需求:生成一个人的对象
Person p1=new Person();
当我们声明完 p1 对象后,在内存栈中,我们可以查看到 p1 的地址,在内存堆中,我们可以看到我们类中的属性与方法。在使用对象时,我们是先找到对象的栈地址,在找到堆中的实际内容。
1.2、基本数据类型
需求:定义一个整型变量
int a=100;
当我们声明变量 a 时,只是在内存栈中开辟了一个直接存放内容的空间。
1.3、引用数据类型
需求:定义一个人类对象,并初始化
Person p=new Person();
p.name="小明";
p.sex="boy";
当我们声明 p 对象时,在我们的内存栈中,我们存入了对象的地址,而这个地址,指向的是我们内存堆中的实际属性,name 和 sex,也就是说,我们通过内存栈中的地址也就是对象,可以找到内存堆中的 name 和 sex 这二个属性的值“小明”和“boy”
2、对象使用
创建新的对象之后, 我们就可以使用“对象名. 对象成员”的格式,来访问对象的成员(包括属性和方法)。
2.1、案例
public class Person{int age=23;
public void shout(){System.out.println(age);
}
}
public class PersonDemo{public static void main(String[] args){Person p1 = new Person();
Person p2 =new Person();
p1.age = -30;
// 不同的对象打印,不同的值
p1.shout();
p2.shout();}
}
运行结果:
在我们的主函数里,声明了 p1,p2 二个对象,p1,p2 对象分别在我们的内存中开辟了二个不同的空间,那么当 p1 中的属性 age 发生变化的时候,p2 里面的 age 是不会受到影响的。那么最后调用 shout() 方法的时候,我们输出的结果是 p1 的 age 是 -30 和 p2 的 age 是 23。
2.2、对象创建
格式:
类名 对象名称 = null; // 声明对象
对象名称 = new 类名 (); // 实例化对象
案例:
public class Person
{String name; // 声明姓名属性
int age; // 声明年龄属性
public void tell() // 取得信息的方法
{System.out.println("姓名:" + name + ",年龄:" + age);
}
}
public class PesronDemo
{public static void main(String[] args)
{Person per = new person(); // 创建并实例化对象
}
}
2.3、属性与方法的访问
格式:
** 访问属性:** 对象名称. 属性名
** 访问方法:** 对象名称. 方法名 ()
public class Person
{String name; // 声明姓名属性
int age; // 声明年龄属性
public void tell() // 取得信息的方法
{System.out.println("姓名:" + name + ",年龄:" + age);
}
}
public class PersonDemo
{public static void main(String args[])
{Person per = new Person(); // 创建并实例化对象(非常重要)
per.name = "张三"; // 为 name 属性赋值
per.age = 30; // 为 age 属性赋值
per.tell(); // 调用类中的方法
}
}
3、对象的生命周期
3.1、程序结束时,所有对象都回收
产生了一个 p1 对象,当整个程序结束执行时,p1 对象变成了垃圾,结束了他的生命周期。
3.2、当对象为 null 时,对象变成垃圾
产生了一个 p1 对象,在程序的运行过程当中,p1 赋值了 null, 那么 p1 在内存栈中的地址就消失了,失去了地址的对象就变成了垃圾,等待着 JVM 的垃圾回收。
产生了一个 p1 对象,将 p1 对象的地址给了 p2, 表示的是 p1 和 p2 同时拥有了同一个地址,他们同时指向了我们内存堆中的内容,当我们把 p1 的地址赋值为 null 时,p2 是不受影响的,所以,p1 变成了垃圾对象,而 p2 还是可以正常使用。
4、对象的比较
4.1、== 运算符
“= =”运算符,用于比较两个变量(基本数据类型和引用数据类型变量)的值是否相等。
public class ObjectDemo01{public static void main(String args[]){String s1=new String("abc");// 产生字符串对象
String s2=new String("abc");
String s3=s1;// 将 s1 的地址给了 s3 所以他二地址一样
if(s1==s2){// 比较具体的地址
System.out.println("s1==s2");
}else{System.out.println("s1!=s2");
}
if(s1==s3){System.out.println("s1==s3");
}else{System.out.println("s1!=s3");
}
}
}
运行结果:
4.2、equals() 方法
equals() 方法是 String 类的一个成员方法,用于比较两个引用变量所指向的对象的内容是否相等。
public class ObjectDemo02{public static void main(String args[]){String s1=new String("abc");
String s2=new String("abc");
String s3=s1;
if(s1.equals(s2)){// 比较具体的值
System.out.println("s1==s2");
}else{System.out.println("s1!=s2");
}
if(s1.equals(s3)){System.out.println("s1==s3");
}else{System.out.println("s1!=s3");
}
}
}
运行结果:
5、匿名对象
创建完对象后,在调用该对象的方法时,可以不定义对象的引用变量,而直接调用这个对象的方法。这样的对象叫匿名对象。
5.1、匿名对象定义
** 格式:**new 类名 ()
5.2、匿名对象使用
5.2.1、作为实参传递
将匿名对象作为实参传递给一个函数调用。
** 需求:** 比如程序中有一个 getSomeOne 函数,要接收一个 Person 类对象作为参数,函数定义如下:
public static void getSomeOne(Person p){...}
函数调用:getSomeOne(new Person());
5.2.2、方法只用一次
如果一个对象只需要一次方法调用,那么就可以使用匿名对象。
需求:比如类 Person 中有一个 shout 函数,要求只调用一次
new Person().shout();
5.2.3、案例
需求:将小汽车改装成 3 个轮子的黑车。
1、汽车类
2、汽车修理厂
/*
匿名对象
汽车类
改车厂类
把汽车的改成黑色 3 轮车。*/
// 汽车类
public class Car {String name = "smart"; // 名字
String color = "red"; // 颜色
int num = 4; // 轮胎数量
public void run() {System.out.println(name + ":" + color + ":" + num + ": 跑起来了。。。。");
}
}
// 改车工厂
public class BlackCarFactory {String name; // 工厂名字
String addr; // 工厂地址
public Car repairCar(Car c) {// 将车改成黑色,3 轮
c.num = 3;
c.color = "黑色";
System.out.println("改装成功啦。。。");
return c;
}
}
public class CarDemo{public static void main(String[] args) {BlackCarFactory bcf = new BlackCarFactory(); // 产生一个改车工厂对象
bcf.name = "幸福修理厂";
bcf.addr = "天河区棠东东路御富科贸园 a 栋 206";
// 非匿名对象
Car c = new Car(); // 产生一汽车对象
c.run(); // 运行起来
// 跑到改车工厂,将车传入,进行改装
bcf.repairCar(c);
// 改装完成,取车,在运行
c.run();
System.out.println("--------------------");
// 匿名对象一, 只使用一次:
// 如下创建了 2 个对象
new Car().run();
new Car().run();
System.out.println("--------------------");
// 匿名对象二,作为实际参数传递
Car c2 = bcf.repairCar(new Car()); // 直接将车送进改装工厂
c2.run(); // 改装完后运行
System.out.println();}
}
运行结果: