目录
(四)面向对象:
1、面向对象的理解:
(1)编程思想:
OOP(Object Oriented Programming)面向对象编程。
以对象为核心进行编程,将世界上所有的事物都抽象成对象,通过调用对象来实现具体的功能;遇到大问题,可以将大问题拆成小问题,借助不同的对象来解决小问题。
(2)与面向过程的区别:
编程思想上:
POP(procedure oriented Programming),面向过程编程是一种以过程为中心的编程思想,靠自己一步一步去实现功能,需要对每个步骤精确控制,强调按步骤实现功能,先分析解决问题所需步骤,再自定义方法实现每个步骤功能,然后依次调用方法,最终实现功能
OOP见上面的介绍。
在数据与代码组织上:
面向过程的数据和方法是分离的,函数独立存在,如果想要操作数据,需要将数据传到方法的参数中。
面向对象的数据与方法都被封装在对象中,如果想要操作数据,可以通过调用对象的方法来进行。
在代码的复用性上:
面向过程的代码复用性较低,有时候即使是相似的功能,但在不同的环境下,代码也需要进行或多或少的修改,不方便进行重复使用。
面向对象的代码复用性高,它具有继承与多态的特征。
在代码的可维护性上:
面向过程的代码维护性较差,当要完成大型项目时,太多的函数会使函数间的关系变得很复杂,牵一发而动全身,很难维护。
面向对象的代码维护性好,对于对象的封装性,使程序之间相对独立,便于维护。
下面是一个经典的生活案例,帮助理解:
情景:小明早上起床,想要吃鸡蛋饼。分别用两种不同思想去解决该问题,具体如下:
面向过程:小明先准备面、鸡蛋等原材料,再和面,然后开火烙饼,最后成功吃到鸡蛋饼
面向对象:小明到街上找到摊煎饼的大娘,让大娘做个鸡蛋饼,最后吃到了鸡蛋饼
(3)面向对象的优缺点(与面向过程相比):
面向对象的优点:①封装性提高了代码的安全性和可维护性,降低了代码的耦合度,修改对象的内部逻辑,只用保证接口不变,就不会产生影响。
②继承实现了代码的复用与拓展,子类可以继承父类的代码和方法,并在此基础上新增或者重写。
③多态增强了代码的灵活性,不同对象对于同一个消息(调用同一个方法),可以做出不同的反应。
④以对象为核心,贴近现实,降低了模块化程度的复杂度。
⑤便于团队协作与大型项目管理
---------------------------------------------------------------
缺点:①过度封装会导致性能损耗,需要加载很多个类
②编码者学习成本较高
③对于简单问题可能杀鸡用牛刀
④内存占用较多
-------------------------------------------------------------------------------------------------------------------------
面向过程的优点:①代码简洁,开发效率高
②执行效率高,资源消耗率多
③逻辑清晰,易于调试
④容易上手
⑤适合模块化程度低的单一任务
------------------------------------------
缺点:①代码的复用性差,冗余度高
②拓展性弱,难以应对需求变化
③不适合复杂项目和团队协作
④维护的难度随规模的增加而急速上升
(4)面向对象的特点:
更符合人类思想习惯的思想
利用对象去实现功能
将复杂事情简单化,针对要解决问题的用户而言,可以把大问题拆解成小问题,分别指挥不同的 对象去解决小问题
程序员的角色由执行者变成了指挥者
(5)面向对象开发的思路:
就是不断创建对象,使用对象,指挥对象做事情实现功能
(6)面向对象的三大特征:封装、继承、多态
2、对象:
(1)概念:
对客观事物的抽象,任何一个事物都可以抽象成对象
每个对象由属性(静态的信息描述)和行为(动态的功能描述)组成
具有相似属性和行为的对象可以归为一类(类的定义)
类是对象的抽象,对象是类的实例
举例:我们身边的能看到的东西,都是对象,例如桌子、话筒、笔记本电脑、电脑键盘、你、你的鞋子、眼睛等等。
3、类:
(1)定义:
具有相似属性和行为的一组对象可以抽象为一类,是引用数据类型
(2)组成:
成员变量(属性):指事物的特征,如:手机的品牌,型号,价格等
成员方法(行为):指示物所具有的功能,如:手机可以发短信,打电话等
(3)理解:
类作为对象的数据类型,对象是类的实例,类是对象的抽象
(4)类定义的格式:
[public] class 类名 {
//属性,可以包含多个
[权限修饰符] 数据类型 成员变量名;
//行为,可以包含多个
[权限修饰符] 返回值类型 成员方法名(形参列表) {
具体功能实现
}
//构造器,可有可无,暂时不用写, 构造器的相关内容,我们放在下一篇封装里面讲
[权限修饰符] 类名(形参列表) {
初始化语句
}
}
注意:public修饰的类,类名要与文件名保持一致
案例:
基础类代码展示:
public class Student {
// 属性: 姓名, 年龄
// 成员变量: 跟之前定义变量的格式一样, 只不过位置发生了改变, 放到了类中的方法之外
String name;
int age;
// 行为 : 打招呼
// 成员方法: 跟之前定义方法的格式一样, 只不过去掉了static关键字
public void sayHello() {
System.out.println("hello");
}
}
(5)创建类的对象:
格式:
类名 对象名 = new 类名();
调用对象的成员的方法:
//成员变量公有时,可以直接通过对象调用来访问
对象名.成员变量;
//成员变量私有时,需要借助get/set方法获取变量的值/给变量赋值
对象名.set(值)/get();
//调用公有的成员方法
对象名.成员方法();
注意:对象的创建我们一般写在测试类当中,放在main方法里,测试类和基础类要放在一个文件夹下。
接上面的Student基础类,下面我们以这个为例,展示一下测试类的例子:
public static void main(String[] args) {
// 实例化对象
// 固定格式:类名 对象名 = new 类名();
Student stu = new Student();
// 输出对象属性的默认值
// 对象属性访问格式:对象名.变量名
System.out.println(stu.name); // null
System.out.println(stu.age); // 0
// 给对象属性赋值
stu.name = "张三";
stu.age = 23;
// 再次输出对象属性值
System.out.println(stu.name); // 张三
System.out.println(stu.age); // 23
// 对象成员方法调用
// 固定格式:对象名.方法名(实际参数列表);
stu.sayHello();
// 输出结果:全类名@对象内存地址
// 全类名:包名.类名
System.out.println(stu);
}
(6)对象的内存结构:
程序运行过程:1. 加载 Student 类:把 Student.class 文件内容加载到方法区中2. 加载main 方法并运行:整个 main 方法的代码都被加载到栈区中3. 创建引用类型变量:在栈空间中开辟一块内存空间,用 stu 标识4. 在堆中开辟内存创建对象,并给属性赋上默认初始值5. 将堆空间对象内存地址值放入 stu 标识的内存区域中6. 对象属性赋值:将 "tom" 和 20 放入堆空间对象内存区域内7. 对象方法调用:找到方法区 sayHello 方法对应的代码,执行8. main方法继续执行,遇到 } ,程序执行结束注意:整个过程中基础类只加载一次,只要是他的对象都可以用

(7)成员变量与局部变量的区别:
定义位置不同:
成员变量:在类中,但在方法外
局部变量:在方法中
内存中位置不同:
成员变量:在堆内存中
局部变量:在栈内存中
生命周期不同:
成员变量:随着对象的创建而出现,对象的消失而消失
局部变量:随着方法的调用而出现,程序的结束而消失
初始化值不同:
成员变量:有默认初始化值
局部变量:没有默认值,先定义后初始化,才能使用,不赋值不能用