1、理解面向过程和面向对象的概念以及区别;
2、掌握如何在需求中提取对象,会使用Java代码描述提取的对象;
3、了解对象在内存中的存在状态
4、理解类和对象的区别
5、掌握局部变量和成员变量的概念和使用
6、理解匿名对象的概念、使用局限和应用;
7、掌握引用传递和值传递
1.面向对象的引入
需求:计算一个班级的总分;
问题升级:
多次出现相同的功能:
为了解决这个问题,可以使用函数:
结论:使用函数,可以提高代码的复用性;需求再次升级:
直接复制粘贴代码。造成的结果是:程序复用性差,维护困难;
思考:原来在一个函数中出现重复的代码,解决的办法是,将重复的代码抽取出来,放到一个函数中,通过调用函数实现功能;
现在又出现重复的函数,能否将它抽取出来,放到一个地方,要使用的时候在调用呢?函数:定义在类中的一段独立的代码;所以要将函数抽取出来,也只能放到一个类中;
要在一个类中使用其他类中定义的函数,需要先创建这个类的对象,然后通过这个类的对象来调用里面的函数;
格式是:
创建一个类的对象:
类名变量名(对象名、引用名)= new类名();
本例:
FunctionTool tool = new FunctionTool();
通过一个对象调用类中的方法:
对象名.方法名(参数);
本例:
tool.getSum(array);
. :表示“的”的意思;
在最后的解决中,我们就使用了面向对象的方法;
总结:可以通过将函数抽取到一个类中,然后创建这个类的对象,通过对象调用函数的方式,提高代码的重用性;
2.面向过程和面向对象
2.1.面向过程
什么是过程:
过程就是做一件事情的先后经过;
生活中的过程:
泡面:1、买面;2、烧开水;3、拆包装,把面放到开水中,加入调料,盖上;4、吃面;
程序的过程:
java中的过程,程序执行的先后经过,先执行哪行,后执行哪行;
什么是面向过程:
就是一种解决问题的思想;
使用这种思想解决问题,我们关心的是事情中有哪几步组成,然后一步步实现;
使用面向过程写程序,我们首先要分析需求由那些功能组成,然后写函数实现各个功能,最后根据需求依次调用各个函数;
在这个过程中,开发者需要参与到实现的每一步中,就是劳动者;
前面几天都是按照面向过程的思想写程序;
面向过程的好处:在需求简单的时候,程序简单明了,结构清晰;
弊端:在需求复杂的时候,就会非常麻烦,开发和维护都很困难;
2.2.面向对象
什么是对象:
指的是生活中实际存在的事物;
生活中的对象:
冰箱;被子;钱;电脑;手机;椅子;桌子;地板;电灯;空气;雾霾;地球;太阳;……
Java程序中的对象:
java中的对象,就是通过new关键字在内存中开辟的空间;
什么是面向对象:
也是一种解决问题的思想;
使用这种思想解决问题,我们关心的是事情中有那些参与者;
使用这种思想写程序,首先分析需求有那些功能,然后找有没有已经实现好功能的类,
如果有,就直接拿来,创建它的对象,通过对象调用功能;
如果没有,就需要自己写一个类,然后在类中书写实现功能的函数【面向过程】,然后创建这个类的对象,通过对象调用功能;
在这种过程中,开发者,更多的是在调用其他已经写好的类,是功能的调用和指挥者;
适合开发复杂的功能;
在面向过程中,程序的基本单位是函数;面向对象,程序的基本组成就是类;
2.3.面向过程和面向对象举例
吃饺子;
面向过程:
1、包饺子:先剁馅;和面;包饺子;
2、煮饺子:烧开水;下饺子;
3、吃饺子
4、收拾
面向对象:
1、找一个饺子馆(实现了提供饺子的对象):告诉老板吃的口味、数量(相当于给功能传参)
2、等着做好端上来:相当于调用函数返回结果;
3、吃饺子
4、给钱
2.4.面向过程和面向对象的区别
1、关注点不同:
i.面向过程:关心的是事件中的每一步功能怎么做;
ii.面向对象:关心的是事件中的每一步功能有没有什么对象已经实现好了,然后直接拿来使用;
2、效率不同:
i.面向过程:因为自己要参与每一步的实现,所以效率比较慢;
ii.面向对象:因为大多数都是调用别人已经实现好的功能,所以效率比较高;
3、开发质量:
i.面向过程:因为是自己一步步实现的,大多数情况会有地方会出问题;
ii.面向对象:因为大多数都是调用别人写好的功能,而这些功能一般都经过大量的验证,质量有保证;
4、使用范围不同:
i.面向过程:适合解决需求简单的问题;
ii.面向对象:更适合解决复杂的需求;
联系:在面向对象中,有没有过程?肯定有;面向对象,是基于面向过程的;
3.对象在需求中的使用和练习
面向对象写程序,第一步,也是最重要的一步,就是在需求中找出对象;
简称:找对象;
3.1.需求一:模拟猫抓老鼠;
场景:
1、猫看见老鼠;
2、猫追老鼠;
3、猫抓老鼠;
名词提炼法:在需求描述文字中,找到名词;
名词:猫老鼠
对象:猫老鼠;
伪代码描述对象:
伪代码,就是不是真实的代码,是一些可以看懂的符号;
猫{
看(老鼠){}
追(老鼠){}
抓(老鼠){}
}
老鼠{
}
场景模拟:
猫汤姆= new猫();
老鼠杰瑞= new老鼠();
汤姆.看(杰瑞);
汤姆.追(杰瑞);
汤姆.抓(杰瑞);
练习一:人吃饺子;
1、找对象:
i.名词:人饺子
对象:人饺子
2、伪代码描述
人{
吃(饺子){}
}
饺子{}
3、场景模拟:
人张三= new人();
饺子三全水饺= new饺子();
张三.吃(三全水饺);
3.2.需求二:人开手机;
1、找对象:
人手机
2、伪代码描述:该谁的功能,就要放在谁里面
人{
开(手机){
手机.开机();
}
}
手机{
开机(){}
}
3、场景模拟
人老王= new人();
手机诺基亚= new手机();
老王.开(诺基亚);
练习二:人关灯;
1、找对象:人灯
2、伪代码描述对象
人{
关(灯){
灯.关灯();
}
}
灯{
关灯(){}
}
3、场景模拟:
人小明= new人();
灯阿拉丁神灯= new灯();
小明.关(阿拉丁神灯);
4.对象在代码中的体现
//需求:写程序模拟红色的车在行驶;
/*
找对象:车
伪代码描述:
车{
颜色;
行驶(){}
}
场景模拟:
车法拉利= new车();
法拉利.颜色=红色;
法拉利.行驶();
*/
//java的代码,都写在类里面
class Car//建立一个类,描述车这个事物
{
//属性,因为值是可以改变的,所以应该使用变量表示
//因为事物的属性,属于事物本身,不属于某个具体功能,
//所以表示属性的变量应该直接定义在类中
//一个变量,如果直接定义在类中,就是成员变量
//事物的属性要使用成员变量描述
String color;
//功能,用函数表示
//表示车的行驶功能
void run(){
}
}
//定义一个类,用于测试
class Test
{
public static voidmain(String[] args)
{
//创建一辆车的对象
Car car = newCar();
car.color ="红";
car.run();
}
}
5.对象的内存图解
6.类和对象的区别
java中,先有类,然后对象是根据类创建出来的;
7.局部变量和成员变量
7.1.概念
成员变量:如果一个变量直接定义在类中,就是成员变量;
局部变量:如果一个变量定义在局部范围(函数),就是局部变量
7.2.同名的局部变量和成员变量的使用
问题:下列程序执行的结果是什么?出现这种结果的原因是什么?
class Demo
{
//定义一个成员变量,变量名为a,同时给它赋值为10
int a = 10;
//定义一个函数,名字叫func;
void func(){
int a = 100;
//在函数中需要使用变量,会首先在函数里面找有没有定义这个变量;如果有,就直接使用;如果没有,再到调用它的对象中找。
}
}
class Test
{
public static voidmain(String[] args)
{
Demo d = new Demo();
d.func();
}
}
7.3.区别
1、从定义的位置上:
a)局部变量:定义在局部范围(函数中)
b)成员变量:直接定义在类中(类的成员位置)
2、从内存上看:
a)局部变量:保存在栈内存中
b)成员变量:保存在堆内存中
3、从生命周期(指的是从分配空间到回收空间)上看:
a)局部变量:定义它的函数进栈执行到这一行,给它开辟空间;函数出栈,空间被回收
b)成员变量:创建对象的时候开辟空间;对象成为垃圾空间被回收的时候,成员变量的空间被回收;
4、从使用范围上:
a)局部变量:只能在定义它的函数中使用;
b)成员变量:在定义它的类中都可以使用
5、从初始值上看:
a)局部变量:没有默认值,使用前必须先初始化;
b)成员变量:有默认值,使用前可以不必先赋值,也可以先赋值
8.匿名对象
8.1.什么是匿名对象
什么是对象名:
匿名:没有名字;
匿名对象:就是没有名字的对象;
8.2.匿名对象的局限
问题:下列程序执行的结果是什么?出现这种结果的原因是什么?
class Demo
{
int a;
void func(){
}
}
class Test
{
public static voidmain(String[] args)
{
new Demo().a = 10;
new Demo().func();
}
}
结论:匿名对象,只能在创建的时候被使用一次;一旦创建匿名对象的这行代码结束运行,匿名对象就会称为垃圾空间被回收;
8.3.匿名对象的应用
像这种情况,对象只需要使用一次的时候,为了避免产生空间浪费,可以使用匿名对象传参:
9.引用传递和按值传递
问题:下列程序执行的结果是什么?出现这种结果的原因是什么?
class Demo
{
int a ;
}
class Test
{
public static voidupdate(Demo d){
d.a += 10;
}
public static void update(inta){
a += 10;
}
public static voidmain(String[] args)
{
Demo d = new Demo();
d.a = 10;
update(d);
int a = 10;
update(a);
}
}
按值传递:
给变量赋值时,如果变量的数据类型属于8种基本数据类型,这时传递的是实际的常量值;这种数据传递的方式叫做按值传递。
使用这种方式传递数据,修改一个变量的值,对其他变量没有影响;
引用传递:
给变量赋值时,如果变量的数据类型不属于8种基本数据类型(也就是引用),这时传递的是堆内存中的地址;这种数据传递方式叫引用传递(按址传递)。
使用这种方式传递数据,通过一个变量修改数据,对其他拥有这个引用的变量,都有影响;