标签:
7、对象的内存图解和练习(掌握、课下画图)
8、类和对象的区别(了解)
?
?
分析和步骤:
分析求数组中所有数据的和
????????1)定义一个数组
????????2)定义一个变量接收所有数据的和
????????3)使用循环对数组的角标进行遍历
????????4)根据数组的名字和角标取出数组中的每一个数据和定义的变量进行相加,
????????然后重新赋值给定义的变量
????????5)将求和的功能封装到一个函数中,并将数据的返回给调用者
?
class Demo1
{
????public static void main(String[] args)
????{
????????//定义一个数组
????????int[] arr={2,4,1,8};
????????//调用自定义函数,求数组的所有数据的和
????????int sum=getSum(arr);
????????//将所求的结果打印到屏幕上
????????System.out.println("sum="+sum);
????}
????/*
????????为了解决代码的复用性
????????所以将求和的功能封装到函数中
????*/
????public static int getSum(int[] arr)
????{
????????//定义一个变量接收所有数据的和
????????int sum=0;
????????//使用循环对数组的角标进行遍历
????????for (int i=0;i<arr.length;i++ )//i表示角标
????????{
????????????/*根据数组的名字和角标取出数组中的每
????????????一个数据和定义的变量进行相加*/
????????????sum=sum+arr[i];
????????}
????????//将计算的和返回给调用者
????????return sum;
????}
}
?
需求二:在另一个类中定义功能对数组求和 。
?
分析:由于也是求数组中所有数据的和,只不过不是在上面的类Demo1中,而是在另一个类Demo2中实现同样的功能。注意:在开发中是有很多这样的需求的。按照我们所学的知识我们可以在这个类Demo2中写和Demo1类中相同的代码,功能可以实现。
?
总结:虽然上述方法能够实现效果,但是代码的复用性不是很好,当我们有多个程序中都需要对数组进行上述操作的时候,那么就会导致在这些程序都需要书写上述的函数。纵观所有的程序而言,会发现对数组进行求和值的函数在所有的程序中重复。
?
解决上述代码出现的问题,我们可以按照定义函数时的思想来写代码,即可以将相同的代码功能抽离出来,然后存放到某个类中,我们称为这个类为工具类。如果想用工具类中的功能时,我们只是在需要的类中调用下即可。
注意:这里在其他类中调用工具类中的方法时的思想就是面向对象思想。
?
工具类ArrayTools 中的代码:
?
/*
????将在类中定义功能对数组求和。
????这个类可以称为工具类
*/
class ArrayTools
{
????public static int getSum(int[] arr)
????{
????????int sum=0;
????????for (int i=0;i<arr.length;i++ )//i表示角标
????????{
????????????sum=sum+arr[i];
????????}
????????return sum;
????}
}
?
在类Demo3中调用工具类ArrayTools中的方法的代码:
?
/*
????需求:求数组中所有数据的和
*/
class Demo3
{
????public static void main(String[] args)
????{
????????//定义一个数组
????????int[] arr={2,4,1,8};
????????/*
????????????调用工具类中的求和方法
????????????1.在Demo3类中引入工具类
????????*/
????????//找到可以帮我们完成功能的程序
????????//然后通过new关键字创建出这个程序的对象
????????ArrayTools????tools=new ArrayTools();
????????//通过该程序的对象tools就可以调用工具类ArrayTools中的方法了
????????int sum=tools.getSum(arr);//调用工具类ArrayTools中的函数,求数组的所有数据的和
????????//将所求的结果打印到屏幕上
????????System.out.println("sum="+sum);
????}
}
?
?
面向对象:
当我们在程序如果需要使用某些功能的时候,这时先不要自己盲目的去想这个功能的代码自己应该使用什么语句,以及其他什么逻辑结构,而是先思考有没有已经写好的功能存在,而直接去找那些存在的功能,然后在自己的程序通过new关键字,创建出具备指定功能的程序对象, 然后直接调用具体自己需要的功能,传递参数进去,最后得到自己想要的结果。
?
面向对象的举例引入:
我们先定义了Demo1 和 Demo2两个程序,但是在这个两个程序都书写了相同的getSum方法,于是我们把相同的函数进行了抽取。保存到的第三个程序ArrayTools程序中。
?
如下图所示:
?
?
说明:把多个类中相同的功能代码进行抽取,然后保存在统一类中,当前的程序需要这些功能的时候,在其他的程序引用当前这个类中的功能即可。
?
总结:在Demo1和 Demo2 这两个程序中直接使用new 关键字 创建 ArrayTools的实例(对象),然后通过对象直接可以调用到ArrayTools中的getSum方法。这样可以方便的保证我们在任何程序中都可以引入其他程序中已经存在的功能。
?
学习面向对象,首先我们要先学习面向过程。
面向过程和面向对象都是生活中解决问题的两种思维方式。
面向:就是关注的意思
面向过程:在整个事情的执行过程中,自己至始至终都是其中的参与者,并且要自己亲力亲为所有的步骤。
?
面向过程的生活中举例:
吃饭:
?
1.先思考吃什么?
????2.去菜市场买菜。
????3.回家摘菜,洗菜,切菜。
????4.炒菜,焖饭。
????5.吃饭。
????6.洗刷。
?
面向过程,在程序中真正的体现就是开发人员自己所书写的函数。
?
?
?
生活中理解面向对象的思想:
面向对象:我们需要完成某个事情,需要具体的一个结果。这时我们不会自己去参与其中,而是找具备这些功能的对象,然后调用它们的功能,帮助我们来完成我们的要求。(面向对象只关注结果,不关注过程)
对象:其实就是一个实体(个体)。在生活中,实体就是真实存在的一个事物。
?
面向对象的生活中举例:
?
吃饭:
?
?
第二种方式更加符合我们的思考习惯,自己不要那么辛苦,而我们仅仅只需要指挥或者找具备相应功能的对象帮助我们做事即可。
?
Java中理解面向对象的思想:
面向对象:其实也是一种解决问题的方案。在开发中,遇到需求时,先不要去分析怎么样去解决需求中的功能,而是去找有没有已经实现的解决需求中功能的封装类(类中封装了解决需求中功能的代码[函数])。有,就直接调用现成的功能解决问题; 没有,新建一个类,在新建的类书写解决需求中功能的代码(把解决问题的代码书写在新建的类中,可以在以后遇到相似的需求时,就可以直接使用)。使用面向对象的方式来解决开发中的问题,可以把开发人员从参与者(劳动者)转为调用者(指挥者)
?
面向对象,在程序中真正的体现就是一个一个的类(类中封装了解决问题的函数)。
?
?
所有的计算机语言它们的诞生,基本都是用来解决生活中的问题:
计算机语言也进行分类:
面向过程的语言:C
面向对象的语言:Java、C++、C#等
?
小结:
面向过程:在程序中的组成单位就是函数。是由若干个函数组成
面向对象:在程序中的组成单位就是类(类中封装了函数)。是由若干个类组成。
面向对象是基于面向过程基础之上的。在开发中,面向对象和面向过程是配合使用的
?
?
面向过程:
?
?
在整个解决问题的过程中,购买电脑的人需要参与到整个过程的每一步,需要亲力亲为,购买过程比较累。
?
面向对象:
1、找一个懂电脑的老手--->黑旋风。
2、告诉他可以接受的价格
3、给钱让黑旋风帮忙去购买电脑
4、等待黑旋风把电脑扛回来
?
对比着使用面向过程解决的方式,整个过程瞬间变得简单了。
?
?
面试官您面试我们,这个时候您就在使用面向对象的思想解决问题。面试官您本身就具备了丰富开发经验,咱们公司现在有相应的项目需要开发,您本身就可以完成这项任务,但是可能会需要较长的时间完成,而这时您就需要找一批具备专业开发能力的人员,而正好这时您找到了我们。而我们就是那些具备专业开发能力的开发人员,而您现在就不需要去做相应的开发工作,而只需要指挥我们来完成具体的开发任务,并且可以高效快速的完成客户的需求。
?
面向过程和面向对象都是解决问题的思维方式:
面向过程我们需要参与其中,在整个过程中我们是这个事件的具体的参与者。
面向对象我们不需要参与其中的每个步骤,而只需要我们去找具备对应功能的对象,然后指挥他们做事情即可。
面向对象更加符合现在人们的思维习惯。
?
如果在实际需求中,没有可以完成具体功能的对象时,这时自己先造一个对象, 然后再按照面向对象的方式来使用这个对象。
?
接下来学习的主要思想:
我们如何使用Java程序描述一个对象,然后创建这个对象,再使用这个对象,以及对象和对象之间的关系。
?
一般的做法:遇到需求之后,我们首先分析需求中的名词,基本上需求中的名词就是一个一个的对象(名词提炼法)。
当把名词提炼出来之后,开始分析当前这个对象中具体有哪些行为和功能,或者具备哪些基本的数据。
?
名词:大象、冰箱。
?
描述各个名词(对象)的细节:
大象
{
}
?
冰箱
{
打开()
{
}
?
存储( 大象 )
{
?
}
关闭()
{
}
}
?
在分析完具体的对象之后,我们需要创建出真实的这些对象。
?
有大象这个具体真实的事物:
大象 dx = new 大象(); // 创建出了一个大象这个事物
有冰箱这个事物
冰箱 bx = new 冰箱(); // 有了冰箱这个事物
?
bx.打开(); //打开了冰箱的门
bx.存储( dx ); //把大象装到冰箱中
bx.关闭();//关闭冰箱的门
?
在分析需求的时候,一定要分析清楚当前某个功能或者行为具体应该属于哪个对象上。
分析以下都有哪些对象,并说明功能属于哪个对象。
?
?
人:
门: 开属于门自身的功能。
?
火车司机刹车:
?
?
火车:刹车是火车的功能。
司机:
?
一般当我们分析出具体的对象时候,需求中的动作,一般都属于某个对象的功能。
?
要把生活中存在的具体的个体,以及某个事物最终用Java程序来体现:
生活中的一类事物,可以对应Java中的某个class程序,而把这个class程序称为一个类。因此上述分析的所有的对象,我们都可以使用Java中的类来封装和描述。
?
当我们需要把生活中的事物使用Java中的类进行封装和描述的时候:
首先需要先分析当前生活中的事物具有哪些基本的特点(基本的属性,具备的功能/行为/动作(用java中的函数表示))。然后通过分析在和Java中的类建立对应的关系。最后才能使用Java中的类描述。
?
?
人的案例:
我们应该从具体的某个人,或者从某几个人中开始分析当前人这一类事物具备的共性特点。
?
人具备基本的数据:身高、体重、年龄、姓名、性别.......
人具备的基本功能:吃饭、睡觉、学习。
?
人
{
身高
体重
年龄
性别
姓名
?
吃饭(){}
睡觉(){}
学习(){}
}
?
分析完某一类事物具备的共性特征之后,就要开始考虑这类事物的那些基本的数据应该使用Java中的什么描述?而事物的基本功能应该使用Java中的什么描述?
?
事物的基本数据,一般在生活中就是一个数据,这个数据可以使用学习过的一个变量来表示。
事物的行为/功能/动作,可以使用Java中的函数来描述。
?
用Java中的类 描述 当前分析的这个事物:事物的名称,就是Java中的类名
?
class Person
{
double height; //身高
double weight; //体重
int age; //年龄
char sex; //性别
String name; // 姓名
?
//描述人这类事物的共性行为
//前面的函数修饰符不用写
void eat()//吃饭
{
}
?
void sleep()//睡觉
{
}
?
void study()//学习
{
}
}
?
当描述完一个事物之后,要在Java程序中使用这个事物,首先需要使用new 关键字创建出这个事物在Java中的对象,然后通过这个对象就可以调用其中的所有特征。
?
Person p = new Person(); //创建出了一个人 对象
p.age = 23;
p.name = "班导";
p.sex = ‘女‘;
?
p.eat();
p.sleep();
p.study();
?
注意:如果在当前这个class类仅仅只是为了描述一个事物,不需要独立运行
????所以可以不用写main函数,如果一个类需要独立运行,那么必须得写main函数
?
需求:用java代码描述人的一些属性和具有的行为(功能)
?
/*
????当前这个class类仅仅只是为了描述一个事物,不需要独立运行
????所以可以不用写main函数
*/
class Person
{
????/*
????????定义变量描述人的基本特性
????*/
????double height;//身高
????double weight;//体重
????int age;//年龄
????char sex;//性别
????String name;//姓名
????//定义功能描述人类的行为
????void sleep()//睡觉
????{
????????System.out.println("sleep");
????????
????}
????void eat()//吃饭
????{
????????System.out.println("eat");
????}
????void study()//学习
????{
????????System.out.println("study");
????}
}
/*
????书写一个测试类
????在该类中需要使用上面类中的属性和方法
?
*/
class PersonTest
{
????/*
????????需要独立运行,所以需要主方法
????*/
????public static void main(String[] args)
????{
????????//创建类Person的对象
????????Person person=new Person();
????????//给类中的属性赋值
????????person.age=18;//person.age表示使用person对象调用Person类中的age属性
????????person.name="班导";//person.name表示使用person对象调用Person类中的name属性
????????person.sex=‘女‘;//person.sex表示使用person对象调用Person类中的sex属性
????????/*
????????????使用person对象调用Person类中的方法
????????*/
????????person.sleep();
????}
}
车的基本数据(属性):
颜色
品牌(车名)
车牌号码
?
车的基本行为(功能):
跑(运行)
?
分析和步骤:
定义一个车类class,名字为Car。因为在类Car中不需要独立运行,只是描述车的属性,所以不用定义main函数。
定义完类Car,需要定义一个测试类CarTest来测试车的属性和和功能。
?
?
class Car
{
????//车的基本属性
????String color;
????String name;
????String number;
?
????//车的行为
????void run()
????{
System.out.println("车的颜色:"+ color +",车的品牌:" + name);
????}
}
class CarTest
{
????public static void main(String[] args)
????{
????????//创建车的对象
????????Car c = new Car();
????????//给车的属性赋值
????????c.color = "yellow";
????????c.name = "BMW";
????????c.number= "沪A88888";
????????c.run();
????}
}
?
?
?
?
?
以上的代码在内存中执行的图解如下图所示:
?
?
?
说明:当上述代码写完之后,就会在dos窗口中输入javac .java源文件,生成class类文件,如果想看到运行效果,那么我们就会在dos窗口中继续输入命令 java class类文件,目的是通过java.exe命令来启动jvm虚拟机来运行class文件,而在启动完虚拟机的时候,jvm虚拟机就会在内存中开辟5个内存空间栈内存,堆内存,方法区,本地方法区和寄存器。
由于在dos窗口中输入 java CarTest,所以jvm会去硬盘上加载CarTest.class文件,将CarTest.class类文件加载到内存中的方法区中。Jvm就开始在CarTest.class文件中找main方法运行。
执行到new Car();的时候,jvm首先会在当前java环境中找,如果没有找到,那么jvm就会去当前的硬盘中找Car.class类文件,如果再找不到就会报错。如果找到,就会将类文件加载到方法区中。
在java中如果是new关键字开辟的内存都是在堆内存中开辟,而在Car的类中定义的变量也会在堆内存中开辟变量空间,在堆内存中开辟的空间都有默认初始化值,这里的三个变量都是引用类型,所以初始化值是null.
?
在程序中使用一个类来描述生活中的某一类事物,而事物的基本属性我们使用了变量描述。这些变量的书写位置和类中的函数属于并列关系。这时这些变量称为类中的成员变量。而类中负责描述行为(功能)的函数称为类中的成员函数(成员方法)。
在类中定义成员变量,和第二天学习的定义变量没有任何区别。只是把变量写在类的成员位置上而已。
类中的成员函数(成员方法),它和我们学习的函数定义完全一致。
?
在使用Java中的new 关键字创建当前这个类的对象时, 这个类中的所有成员变量,会随着对象在堆中的出现而存在。所有成员变量随着的对象在堆中出现之后,都会有默认的初始化值。
?
?
?
?
?
需求:在以上程序中添加如下代码的结果是什么?
?
?
?
?
注意:只要在程序中使用new关键字创建对象,那么在堆中都会有一个新的对象产生。
?
?
说明:因为重新创建了一个新的车的对象,这时在堆中又会有一个新的空间。
由于创建的新的车对象没有进行手动的赋值,这时这个对象中的所有成员变量的值都是默认的值。
?
?
?
出现以上的情况的内存图解说明:
?
?
需求:下面的代码在堆内存中是否有垃圾?
?
class Car
{
????//车的基本属性
????String color;//车的颜色
????String name;//车的品牌
????String number;//车牌号码
????/*
????????车的基本行为
????*/
????void run()
????{
????????System.out.println("车的颜色:"+color+",车的品牌:"+name);
????}
}
//在这个类中使用Car类中的属性和方法
class CarTest
{
????public static void main(String[] args)
????{
????????//创建车的对象
????????Car car=new Car();
????????Car car2=car;
????????//给车的属性赋值
????????car.color="yellow";
????????car.name="BMW";
????????car.number="沪A88888";
????????//调用车的行为(方法)
????????car.run();
????????car=null;
????}
}
?
没有。内存图解如下图所示:(注意和上个图的区别)
?
?
?
要研究类和对象的关系:
为什么要写一个类:Java是通过类这个形式描述生活中的某一类事物。因此我们就必须通过类展示生活中的所有事物。
?
?
总结:
类和对象的关系:
类:
类是用来描述生活中的某一类事物。描述的是一类事物所具有的共性内容。
类只是java语言用来描述事物的一种方式。我们可以把类当做生活中某一类事物的共性的总结和描述。
?
对象:
而对象是基于这个类在Java中创建出来的真实个体(实例)(在堆内存中存在)。
而把Java中的对象可以理解成生活中的具体一个实物。
?
举例:车整体是一个大类,而你自己所拥有的一辆车就是一个对象。
?
先要使用类来描述事物,才可以使用类创建对象
?
?
接下来我们主要学习的任务:
1) 研究如何去描述一个类,以及这个类中能够书写什么内容。
2) 研究基于这个类怎么去创建出Java中的对象,以及创建对象的过程中JVM具体做了什么事情。
3) 研究类和类之间的关系。
?
?
?
?
?
?
?
?
?
?
?
?
前言作业:
提示:建议先练习重点知识点的代码
?
?
?
?
?
?
标签:
原文地址:http://www.cnblogs.com/beyondcj/p/5860857.html