一、介绍
对象(object)是一件事、一个实体、一个名词,可以获得的东西,可以想象有自己的标识的任何东西。对象是类的实例化。一些对象是活的,一些对象不是。比如这辆汽车、这个人、这间房子、这张桌子、这株植物、这张支票、这件雨衣。 概括来说就是:万物皆对象。对象需要由两部分来描述:第一部分是它的“数据”,包括对象的特性、状态等静态信息;第二部分是它的“行为”,包括该对象的操作、功能等能动信息。
那么这节课呢,我们来了解的是对象的相关应用,告诉我们如何去使用我们对象的属性与方法,比如我们有一个人类,他产生了一个对象张三,那么我们就可以通过张三去使用张三的名字,年龄等他的一些特性,除了这个以外,我们还会对张三的行为进行引用,如:唱歌,踢球,玩游戏等。
二、知识点介绍
1、对象存储
2、对象使用
3、对象生命周期
4、对象比较
5、匿名对象
三、上课对应视频的说明文档
1、对象的存储
对象的存储在内存中有地址与值,那么地址与值是使用栈与堆的形式存储。那么我们先了解一下堆,栈。
栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同, Java自动管理栈和堆,程序员不能直接地设置栈或堆。
栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享。
堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
案例:
//堆是先进先出,栈是先进后出
Person p1=new Person();
如上图:当我们声明完p1对象后,在内存栈中,我们可以查看到p1的地址,在内存堆中,我们可以看到我们类中的属性与方法。在使用对象时,我们是先找到对象的栈地址,在找到堆中的实际内容。
(1) 基本类型
如上图:当我们声明变量a时,只是在内存栈中开辟了一个直接存放内容的空间。
(2) 引用类型
如上图:当我们声明p对象时,在我们的内存栈中,我们存入了对象的地址,而这个地址,指向的是我们内存堆中的实际属性,name和sex,也就是说,我们通过内存栈中的地址也就是对象,可以找到内存堆中的name和sex这二个属性的值“小明”和“boy”
2、对象的使用
创建新的对象之后,我们就可以使用“ 对象名.对象成员 ”的格式,来访问对象的成员(包括属性和方法)。
案例:
class TestPerson{
public static void main(String[] args){
Person p1 = new Person();
Person p2 =new Person();
p1.age = -30;
//不同的对象打印,不同的值
p1.shout();
p2.shout();
}
}
class Person{
int age=23;
public void shout(){
System.out.println(age);
}
}
如上例:在我们的主函数里,声明了p1,p2二个对象,p1,p2对象分别在我们的内存中开辟了二个不同的空间,那么当p1中的属性age发生变化的时候,p2里面的age是不会受到影响的。那么最后调用shout()方法的时候,我们输出的结果是p1的age是-30和p2的age是23。
(1) 对象创建
格式:
类名 对象名称 = null; //声明对象
对象名称 = new 类型(); //实例化对象
class Person
{
String name; //声明姓名属性
int age; //声明年龄属性
public void tell() //取得信息的方法
{
System.out.println("姓名:" + name + ",年龄:" + age);
}
}
public class ClassDemo02
{
public static void main(String[] args)
{
Person per = new person(); //创建并实例化对象
}
}
(2) 访问属性与方法
格式:
访问属性:对象名称.属性名
访问方法:对象名称.方法名()
class Person
{
String name; //声明姓名属性
int age; //声明年龄属性
public void tell() //取得信息的方法
{
System.out.println("姓名:" + name + ",年龄:" + age);
}
}
public class ClassDemo03
{
public static void main(String args[])
{
Person per = new Person(); //创建并实例化对象(非常重要)
per.name = "张三"; //为name属性赋值
per.age = 30; //为age属性赋值
per.tell(); //调用类中的方法
}
}
3、对象的生命周期
(1)程序结束时,所有对象都回收
如上图:产生了一个p1对象,当整个程序结束执行时,p1对象变成了垃圾,结束了他的生命周期。
(2)当对象为null时,对象变成垃圾
A、
如上图:产生了一个p1对象,在程序的运行过程当中,p1赋值了null,那么p1在内存栈中的地址就消失了,失去了地址的对象就变成了垃圾,等待着JVM的垃圾回收。
B、
如上图:产生了一个p1对象,将p1对象的地址给了p2,表示的是p1和p2同时拥有了同一个地址,他们同时指向了我们内存堆中的内容,当我们把p1的地址赋什为null时,p2是不受影响的,所以,p1变成了垃圾对象,而p2还是可以正常使用。
4、对象的比较
A、“= =”运算符 ,用于比较两个变量(基本数据类型和引用数据类型变量)的值是否相等。
public class Test1{
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.pirntln("s1==s2");
}else{
System.out.println("s1!=s2");
}
if(s1==s3){
System.out.println("s1==s3");
}else{
System.out.println("s1!=s3");
}
}
}
B、equals()方法是String 类的一个成员方法,用于比较两个引用变量所指向的对象的内容是否相等。
public class Test1{
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、匿名对象
创建完对象后,在调用该对象的方法时,可以不定义对象的引用变量,而直接调用这个对象的方法。这样的对象叫匿名对象。
Person p=new Person();
P. shout();
<=====>
new Person().shout();
匿名对象使用:
如果一个对象只需要一次方法调用,那么就可以使用匿名对象。
将匿名对象作为实参传递给一个函数调用,比如程序中有一个getSomeOne 函数,要接收一个Person类对象作为参数,函数定义如下:
public static void getSomeOne(Person p){
...
}
函数调用:
getSomeOne(new Person());
案例:
需求:将小汽车改装成3个轮子的黑车。
1:汽车类。
2:汽车修理厂
/*
匿名对象
匿名信
修黑车
汽车类
黑车厂类
把汽车的改成黑色3轮车。
*/
//汽车类
class Car {
String name = "smart"; //名字
String color = "red"; //颜色
int num = 4; //轮胎数量
void run() {
System.out.println(name + ":" + color + ":" + num + ":跑起来了。。。。");
}
}
//改车工厂
class BlackCarFactory {
String name; //工厂名字
String addr; //工厂地址
Car repairCar(Car c) { //将车改成黑色,3轮
c.num = 3;
c.color = "黑色";
System.out.println("改装成功啦。。。");
return c;
}
}
//主函数
class Demo1 {
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();
// 匿名对象一,只使用一次:
// 如下创建了2个对象
/*
* new Car().run();
*
* new Car().run();
*/
// 匿名对象二,作为实际参数传递
Car c2 = bcf.repairCar(new Car()); //直接将车送进改装工厂
c2.run(); //改装完后运行
System.out.println();
}
}
总结:
1. 匿名对象设置的属性永远无法获取? 没有引用变量指向那个对象。
2. 任何两个匿名对象使用==比较,永远返回false。
3. 匿名对象主要应用于实参。