第四章 面向对象(基础)
主要内容
- 面向过程和面向对象
- 类和对象
- 面向对象编程
- 创建对象的内存分析
- 成员变量和局部变量的区别
- 构造方法及其重载
- 构造方法和成员方法的区别
- this关键字
- static关键字
- 代码块(局部代码块、构造代码块和静态代码块)
- package包
学习目标
知识点 | 掌握程度 |
---|---|
面向过程和面向对象 | 理解 |
类和对象 | 理解 |
面向对象编程 | 掌握 |
创建对象的内存分析 | 掌握 |
成员变量和局部变量的区别 | 理解 |
构造方法及其重载 | 掌握 |
构造方法和成员方法的区别 | 理解 |
this 关键字 | 掌握 |
static 关键字 | 掌握 |
代码块(局部代码块、构造代码块和静态代码块) | 掌握 |
package 包 | 掌握 |
1. 面向对象概念
面向过程(Procedure Oriented)和面向对象(Object Oriented)是两种不同的软件分析、设计和开发思想。它们引导开发者以不同方式思考和解决问题。历史上,面向过程思想先出现,但随着软件规模扩大和问题复杂性提高,面向过程的局限性逐渐显现,面向对象思想应运而生并成为当今主流方法。
C语言是典型的面向过程语言,而Java则是典型的面向对象语言。
1.1 面向过程
面向过程是通过分析解决问题所需的步骤,然后用函数逐步实现这些步骤,使用时依次调用这些函数来完成任务。
优点:
- 性能较高,因为不需要类的实例化,减少了资源消耗
- 适合对性能要求极高的场景,如单片机、嵌入式开发、Linux/Unix系统等
缺点:
- 代码可维护性较差
- 复用性不强
- 扩展性有限
1.2 面向对象
面向对象思维方式更符合人类自然思考习惯,能将复杂问题简单化。它将问题分解为各个对象,建立对象的目的不是为了完成某个步骤,而是描述事物在整个问题解决过程中的行为。宏观上使用面向对象把握全局,微观处理上仍然是面向过程。
面向过程更像是"执行者"(自己做事情),而面向对象更像是"指挥者"(指挥对象做事情)。
优点:
- 易于维护:代码组织更清晰
- 易于复用:通过继承和组合可以重用已有代码
- 易于扩展:可以通过多态等特性灵活扩展功能
- 低耦合:封装、继承、多态等特性使系统更灵活,更易维护
缺点: - 性能相对面向过程略低,因为类的实例化和方法调用有额外开销
1.3 面向对象举例
1.3.1 如何开汽车
面向过程分析 | 面向对象分析 |
---|---|
第一步:踩离合 | 驾驶员 (对象) |
第二步:挂挡 | 汽车(对象) |
第三步:踩油门,松离合 | 驾驶员开汽车(对象交互) |
第四步:车走了 | car.start() (方法调用) |
在面向过程中,我们关注的是"如何开车"的每个步骤;而在面向对象中,我们关注的是"谁来开车"和"开什么车",然后通过对象之间的交互完成任务。
1.3.2 如何修建房子
面向过程分析 | 面向对象分析 |
---|---|
第一步:设计房子(修建几层楼,几间卧室等) | 设计师(对象,负责房屋设计) |
第二步:购买材料(建筑材料、装修材料等) | 采购员(对象,负责材料购买) |
第三步:修建毛坯房(夯实地基,修建房屋等) | 建筑工人(对象,负责房屋建设) |
第四步:房屋装修(卫生间先防水后贴地板等) | 装修工人(对象,负责房屋装修) |
第五步:入住 | 入住(对象,执行入住行为) |
2. 类和对象
Java是一种面向对象的程序设计语言(Object Oriented Programming:OOP),类和对象是其核心概念。理解它们之间的区别和联系对于掌握面向对象编程至关重要。
2.1 对象(object)
从哲学角度讲,万物皆对象。从编程角度看,对象是现实世界中具体事物在程序中的表示。
对象具有两个基本特征:
- 状态(属性):对象的特征,描述对象的数据
- 行为 (方法):对象能够执行的操作
例如:
- 一部手机是一个对象,它有品牌、型号、颜色等属性,有打电话、发短信、拍照等行为
- 一只猫是一个对象,它有品种、年龄、颜色等属性,有吃饭、睡觉、捉老鼠等行为
- 一个学生是一个对象,他有姓名、学号、年龄等属性,有学习、考试、运动等行为
2.2 类(class)
类是对象的抽象,是对一类具有相同特征的对象的描述。类定义了这类对象共有的属性和行为,是创建对象的模板或蓝图。
类的组成部分:
- 属性 (成员变量):描述类的特征
- 方法 (成员方法):描述类的行为
- 构造方法 :用于创建对象并初始化属性
例如:
- 手机类(Phone)定义了所有手机共有的属性(品牌、型号、颜色)和行为(打电话、发短信、拍照)
- 猫类(Cat)定义了所有猫共有的属性(品种、年龄、颜色)和行为(吃饭、睡觉、捉老鼠)
- 学生类(Student)定义了所有学生共有的属性(姓名、学号、年龄)和行为(学习、考试、运动)
2.3 类与对象的关系
类与对象的关系可以从以下几个方面理解:
-
抽象与具体的关系:
- 类是抽象的概念,不占用实际内存空间(方法区除外)
- 对象是具体的实例,占用实际内存空间
-
模板与实例的关系:
- 类是创建对象的模板或蓝图
- 对象是根据类的定义创建的实例
-
一对多的关系:
- 一个类可以创建多个对象
- 多个对象都是同一个类的实例
-
时间顺序关系:
- 先有类,后有对象
- 必须先定义类,才能创建对象
3. 面向对象编程
3.1 类的定义
在Java中,类是对象的模板或蓝图,定义了对象的属性和行为。类就像一张设计图纸,而对象则是根据这张图纸创建的实体。一个空类虽然可以定义,但没有任何实际意义。要使类有意义,我们需要为其添加具体的组成部分。
类的主要组成部分:
- 属性(field) :定义格式:
[修饰符] 属性类型 属性名 = [默认值];
- 方法(method) :定义格式:
[修饰符] 返回值类型 方法名(形参列表) { 方法体 }
在类中定义的属性也称为 成员变量 ,类中定义的方法称为 成员方法 。
【示例】创建一个学生类,并添加类的成员变量和成员方法
public class Student {// 属性,此处也称为成员变量String name; // 姓名int age; // 年龄String major; // 专业// 方法,此处也称为成员方法void eat(String food) {System.out.println(name + "正在吃" + food);}void study() {System.out.println(name + "," + age + "岁,专业是" + major + ",正在学习Java");}void introduce() {System.out.println("大家好,我是" + name + ",今年" + age + "岁,就读于" + major + "专业");}
}
注意 :成员变量定义在类中,整个类中的成员方法都可以访问。
3.2 创建对象
在Java中,对象也叫做object
或 instance
(实例),所以也称为实例对象。要创建对象,必须先有一个类,然后通过 new 关键字
来创建对象。
语法格式 : 类名称 对象名称 = new 类名称();
【示例】通过Student类(模板),创建两个学生对象(具体实例)
// 测试类
public class ObjectTest {public static void main(String[] args) {// 实例化小明学生对象Student stu1 = new Student();// 成员变量赋值stu1.name = "小明"; // 设置名字stu1.age = 18; // 设置年龄stu1.major = "计算机科学"; // 设置专业System.out.println("姓名:" + stu1.name + ",年龄:" + stu1.age + ",专业:" + stu1.major);// 调用成员方法stu1.eat("小龙虾"); // 调用吃饭方法stu1.study(); // 调用学习方法stu1.introduce(); // 调用自我介绍方法System.out.println("------------------------");// 实例化小花学生对象Student stu2 = new Student();// 操作成员变量stu2.name = "小花"; // 设置名字stu2.age = 17; // 设置年龄stu2.major = "数据科学"; // 设置专业System.out.println("姓名:" + stu2.name + ",年龄:" + stu2.age + ",专业:" + stu2.major);// 调用成员方法stu2.eat("冰淇淋"); // 调用吃饭方法stu2.study(); // 调用学习方法stu2.introduce(); // 调用自我介绍方法}
}
注意事项:
- 成员变量隶属于对象,只能通过对象来调用,我们可以通过
对象.成员变量
来操作成员变量。 - 成员方法隶属于对象,只能通过对象来调用,我们可以通过
对象.成员方法(实参列表)
来调用成员方法。
3.3 成员变量默认值
我们可以在类中对成员变量显式初始化,也可以在创建对象成功后,通过 对象.成员变量
来设置成员变量值。如果以上两种操作都不做,Java虚拟机会使用默认值对其初始化。
数据类型 | 默认值 |
---|---|
整型 | 0 |
浮点型 | 0.0 |
字符型 | '\u0000' |
布尔值 | false |
引用类型 | null |
3.4 对象内存分析
Java程序运行时的内存分配主要包括:
- 栈 :用于存放局部变量,其特点是:先进后出,自下而上存储,方法执行完毕,自动释放空间。
- 堆 :用于存放new出来的对象,需要垃圾回收器来回收。
当我们创建对象时,对象本身存储在堆内存中,而对象的引用变量存储在栈内存中。引用变量中存储的是对象在堆内存中的地址,通过这个地址可以找到并操作对象。
【随堂练习】
- 使用计算器(Calculator)完成加法和减法运算,并能显示出该计算器的品牌和尺寸。
- 计算器成员变量:品牌(brand)、尺寸(size)
- 计算器成员方法:加法运算(add)、减法运算(sub)和显示计算机信息(show)
public class Calculator {// 成员变量String brand; // 品牌double size; // 尺寸(英寸)// 加法方法public int add(int a, int b) {System.out.println("正在使用" + brand + "计算器进行加法运算");return a + b;}// 减法方法public int sub(int a, int b) {System.out.println("正在使用" + brand + "计算器进行减法运算");return a - b;}// 显示计算器信息public void show() {System.out.println("这是一台" + brand + "品牌的计算器,尺寸为" + size + "英寸");}
}
// 测试类
public class CalculatorTest {public static void main(String[] args) {// 创建计算器对象Calculator calc = new Calculator();// 设置成员变量calc.brand = "卡西欧";calc.size = 4.5;// 调用成员方法calc.show();// 进行计算int sum = calc.add(25, 17);System.out.println("加法结果:" + sum);int diff = calc.sub(100, 45);System.out.println("减法结果:" + diff);}
}
3.5 成员变量和局部变量区别
局部变量是定义在方法或代码块中的变量,成员变量是定义在类中与类的方法处于同一层次的变量。
成员变量和局部变量的区别:
区别点 | 成员变量 | 局部变量 |
---|---|---|
定义位置 | 定义在类中,整个类中的成员方法都可以访问 | 定义在方法或代码块中,只在所属的区域有效 |
内存位置 | 存在于堆内存的对象中 | 存在于栈内存的方法中 |
生命周期 | 随对象创建而存在,随对象消失而消失 | 随所属区域执行而存在,随所属区域消失而释放 |
初始化 | 有默认初始值 | 无默认初始值,必须先赋值后使用 |
可用修饰符 | 可被public 、protected 、private 、static 、final 修饰 | 只能被final 修饰 |
在使用变量时需要遵循的原则为: 就近原则 。首先在局部范围找,有就使用;接着在成员位置找。
public class VariableDemo {// 成员变量int num = 10;String name = "全局变量";public void method() {// 局部变量int num = 20;System.out.println("局部变量num:" + num); // 输出20,就近原则System.out.println("成员变量num:" + this.num); // 输出10,使用this关键字访问成员变量System.out.println("成员变量name:" + name); // 输出"全局变量",没有同名局部变量,直接访问成员变量}public void anotherMethod() {// 局部变量int age = 30;// 下面的代码会编译错误,因为局部变量必须初始化后才能使用// int score;// System.out.println(score);// 正确的做法int score = 0; // 初始化后使用System.out.println(score);// 访问成员变量System.out.println("成员变量num:" + num); // 输出10}
}
3.6 匿名对象
通过使用new关键字来创建对象,这种对象分为两种:匿名对象与非匿名对象。
- 非匿名对象 :
Student stu = new Student();
- 有名字的对象,可以重复使用 - 匿名对象 :
new Student();
- 没有名字的对象,只能使用一次
使用场合 :
- 当对象方法仅进行一次调用时,可以简化为匿名对象
- 匿名对象可以作为实际参数进行传递
【示例】匿名对象的使用
public class AnonymousObjectDemo {public static void main(String[] args