今日任务:
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.1.需求一:模拟猫抓老鼠;
场景:
1、猫看见老鼠;
2、猫追老鼠;
3、猫抓老鼠;
名词提炼法:在需求描述文字中,找到名词;
名词: 猫 老鼠
对象: 猫 老鼠;
伪代码描述对象:
伪代码,就是不是真实的代码,是一些可以看懂的符号;
猫{
看(老鼠){}
追(老鼠){}
抓(老鼠){}
}
老鼠{
}
场景模拟:
猫 汤姆= new 猫();
老鼠 杰瑞= new 老鼠();
汤姆.看(杰瑞);
汤姆.追(杰瑞);
汤姆.抓(杰瑞);
3.2.需求二:人开手机;
1、找对象:
人 手机
2、伪代码描述:该谁的功能,就要放在谁里面
人{
开(手机){
手机.开机();
}
}
手机{
开机(){}
}
3、场景模拟
人 老王= new 人();
手机 诺基亚 = new 手机();
老王.开(诺基亚 );
练习二:人关灯;
1、找对象:人 灯
2、伪代码描述对象
人{
关(灯){
灯.关灯();
}
}
灯{
关灯(){}
}
3、场景模拟:
人 小明 = new 人();
灯 阿拉丁神灯= new 灯();
小明.关( 阿拉丁神灯);
- 对象在代码中的体现
//需求:写程序模拟红色的车在行驶;
/*
找对象: 车
伪代码描述:
车{
颜色;
行驶(){}
}
场景模拟:
车法拉利 = new 车();
法拉利.颜色 = 红色;
法拉利.行驶();
*/
//java的代码,都写在类里面
class Car//建立一个类,描述车这个事物
{
//属性,因为值是可以改变的,所以应该使用变量表示
//因为事物的属性,属于事物本身,不属于某个具体功能,
//所以表示属性的变量应该直接定义在类中
//一个变量,如果直接定义在类中,就是成员变量
//事物的属性要使用成员变量描述
String color;
//功能,用函数表示
//表示车的行驶功能
void run(){
System.out.println(color+ "颜色的车在行驶");
}
}
//定义一个类,用于测试
class Test{
public static voidmain(String[] args) {
//创建一辆车的对象
Car car = newCar();
car.color ="红";
car.run();
}
}
- 对象的内存图解
- 类和对象的区别
java中,先有类,然后对象是根据类创建出来的;
- 局部变量和成员变量
7.1.概念
成员变量:如果一个变量直接定义在类中,就是成员变量;
局部变量:如果一个变量定义在局部范围(函数),就是局部变量
class Demo{
//成员变量
int a =100;
void show(){
//局部变量
int b =20;
}
}
7.2.同名的局部变量和成员变量的使用
问题:下列程序执行的结果是什么?出现这种结果的原因是什么?
class Demo{
//定义一个成员变量,变量名为a,同时给它赋值为10
int a = 10;
//定义一个函数,名字叫func;
void func(){
int a = 100;
//在函数中需要使用变量,会首先在函数里面找有没有定义这个变量;如果有,就直接使用;如果没有,再到调用它的对象中找。
System.out.println("method:" + a);
}
}
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.1.什么是匿名对象
什么是对象名:
匿名:没有名字;
匿名对象:就是没有名字的对象;
8.2.匿名对象的局限
问题:下列程序执行的结果是什么?出现这种结果的原因是什么?
class Demo{
int a;
void func(){
System.out.println("method:" + a);
}
}
class Test{
public static voidmain(String[] args){
new Demo().a = 10;
System.out.println(new Demo().a);
new Demo().func();
}
}
结论:匿名对象,只能在创建的时候被使用一次;一旦创建匿名对象的这行代码结束运行,匿名对象就会称为垃圾空间被回收;
8.3.匿名对象的应用
像这种情况,对象只需要使用一次的时候,为了避免产生空间浪费,可以使用匿名对象传参:
- 引用传递和按值传递
问题:下列程序执行的结果是什么?出现这种结果的原因是什么?
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);
System.out.println(d.a);
int a = 10;
update(a);
System.out.println(a);
}
}
按值传递:
给变量赋值时,如果变量的数据类型属于8种基本数据类型,这时传递的是实际的常量值;这种数据传递的方式叫做按值传递。
使用这种方式传递数据,修改一个变量的值,对其他变量没有影响;
引用传递:
给变量赋值时,如果变量的数据类型不属于8种基本数据类型(也就是引用),这时传递的是堆内存中的地址;这种数据传递方式叫引用传递(按址传递)。
使用这种方式传递数据,通过一个变量修改数据,对其他拥有这个引用的变量,都有影响;