面向对象
面向对象的引入
在代码中如果需要遍历多个数组,我们可以将遍历的代码 封装 到方法中,需要遍历时,
就调用相应的方法即可,提高代码的复用性。
在对数组遍历的基础上继续增加需求,比如获取最值(最大最小值)、数值逆序等,同
样需要将这些功能封装到相应的方法中。这样继续封装会发现方法越来越多,于是就想能不
能将这些方法继续进行封装呢?
通过前面的讲解我们知道类是可以存放方法的,所以,我们就考虑使用类来封装这多个
方法,将来在做数组的操作时,不用去找具体的方法,先找到这个 类 ,然后使用这个类中
的方法。
这就是 面向对象思想 的编程方式。
方法封装的代码示例
/**
* 根据当前数据查找其在数组中的索引位置
*/
public static int search(int[] scores, int score) {
// 默认没有在当前数组scores 中查找到 score
int result = -1;
for (int i = 0; i < scores.length; i++) {
if (scores[i] == score) {
result = i;
}
}
return result;
}
/**
* 打印数组
*/
public static void printArray(int[] nums) {
for (int i =0; i<nums.length; i++) {
System.out.print(nums[i] + ", ");
}
System.out.println();
}
面向对象的思想概述
什么是面向对象、面向过程
面向过程与面向对象都是我们编程中,编写程序的一种思维方式。
面向过程的程序设计方式,是遇到一件事时,思考”我该怎么做”,然后一步步实现的
过程。
例如:公司需要组装新电脑,按照面向过程的程序设计方式会思考”我该去哪买电脑?
买什么配置?怎么报销等,然后一件件的完成”,最后把公司需要的电脑组装好了。
面向对象的程序设计方式,是遇到一件事时,思考”我该让谁来做”,然后那个”谁”就
是对象,他要怎么做这件事是他自己的事,反正最后一群对象合力能把事就好就行了。
例如,公司需要组装新电脑,按照面向对象的程序设计方式会思考”我该让谁来做,
如小明配好电脑配置清单、让小王去京东买、最后让小郭去财务处报销等,这里的”小明
小王、小郭”就是对象,他们要买好电脑,怎么买是他们自己的事,反正最后一群对象合力
把公司电脑买到了。
现实生活中存在各种形式不同的事物,这些事物之间存在着各种各样的联系,在 JAVA
中使用对象来映射现实中的事物,使用对象的关系来描述事物之间的联系,这种思想就是
面向对象思想。
面向对象思想举例
面向过程
洗衣服:
盘子打水 – 泡衣服 – 倒洗衣粉 – 搓衣服 – 过水(过水) – 拧干 –晾衣服
做饭:
买菜–洗菜–洗锅 切菜–烧菜–吃–洗碗
面向对象 洗衣服:
洗衣机(对象):
扔进去– 倒洗衣粉 - 按开始键 - 晾衣服 做饭:
叫饿了么–吃
对象—女朋友
面向对象的好处
通过生活中的真实场景使用面向对象分析完之后,我们开始分析面向过程和面向对象的差异
做出总结:
- 面向对象思维方式是一种更符合人们思考习惯的思想
- 面向过程思维方式中更多的体现的是执行者(自己做事情),面向对象中更多的体
现是指挥者(指挥对象做事情)。- 面向对象思维方式将复杂的问题简单化。
类与对象
对象在程序中的使用
举例把大象装进冰箱
面向过程
面向过程关注步骤,为了把大象装进冰箱,需要 3个过程。
1. 把冰箱门打开(得到打开门的冰箱)
2. 把大象装进去(打开门后,得到里面装着大象的冰箱)
3. 把冰箱门关上(打开门、装好大象后,获得关好门的冰箱)
每个过程有一个阶段性的目标,依次完成这些过程,就能把大象装进冰箱。
面向对象
为了把大象装进冰箱,需要做三个动作(或者叫行为)。每个动作有一个执行者,
它就是对象。
1. 冰箱,你给我把门打开
2. 冰箱,你给我把大象装进去(或者说,大象,你给我钻到冰箱里去)
3. 冰箱,你给我把门关上
依次做这些动作,就能把大象装进冰箱。
冰箱.开门()
冰箱.装进(大象)
冰箱.关门()
代码示例
class 大象{
public static void in(){
System.out.printm("把大象放进冰箱里);
}
}
class 冰箱{
public static void open(){
System.out.println("打开冰箱门");
}
public static void close(){
System.out.println("关闭冰箱门");
}
}
class Demo{
调用冰箱类中的打开冰箱门功能
调用大象类中的进冰箱的功能
调用冰箱类中的关闭冰箱门功能
}
面向对象:开发、设计、特征
面向对象开发
就是不断的创建对象,使用对象,指挥对象做事情。
面向对象设计
其实就是在管理和维护对象之间的关系。
面向对象特征
封装(encapsulation)
继承(inheritance)
多态(polymorphism)
对象在代码中的体现
在分析现实生活中的事物时发现,这些事物都有其具体的特点和功能,这些特点和功能就组
成了这个特殊的事物(对象)
类和对象之间有什么关系?
我们学习编程是为了什么?
我们学习编程语言,就是为了模拟现实世界的事物,实现信息化。
比如:去超市买东西的计费系统、银行办业务的系统。
我们如何描述现实世界事物
举例: 描述学生事物
姓名、年龄、性别 – 描述事物的特征(属性、特点)
学习、吃饭、睡觉 – 这个事物能干什么
属性: 就是该事物的描述信息
行为: 就是该事物能够做什么
我们学习编程语言,就是为了模拟现实中的事物,Java 语言最基本单位是 类 ,所以,我
们就应该把事物用一个 类 来体现。
由此我们就得到了现实中的事物和类的对应关系
事物 ———————- 类
属性 ———————- 变量
行为 ———————- 方法
类和对象的概念
类:是一组相关的属性和行为的集合
对象:是该类事物的具体体现
举例:
类 — 学生
对象 — 班长就是一个对象
类的定义概述和学生类的分析
类的定义
现实世界的事物,学生属于人,拥有人的特征(属性)
属性(特征):人的身高,体重 …
行为:人可以吃饭、睡觉、上课(学生的行为)
Java中用类(class)描述事物也是如此
属性 —- 成员变量
行为 —- 成员方法 定义类其实就是定义类的成员
1. 成员变量:和以前定义变量是一样的,只不过位置发生了改变,在类中,方法外
2. 成员方法:和以前定义方法是一样的,只不过把 static 去掉(后面在详细讲解static的作用)
类的定义格式
创建java文件,与类名相同
public class 类名{
数据类型 属性名称 1;
数据类型 属性名称 2;
//和普通方法一样,只是去掉 static
public void 行为名称(){
//行为...
}
}
学生类的定义
- 学生事物
属性: 姓名、年龄、性别 - 行为: 吃饭、睡觉 学生事物与学生类的对应关系
属性 –成员变量 - 行为 –成员方法 案例演示
根据分析,完成学生类代码
代码示例
//定义一个学生类
class Student{
//姓名 字符串 String
//学号 整数 int
//年龄
//属性
String name;//姓名变量
int code;//学号
int age; //年龄
//行为 方法
//吃饭的方法
public void eat(){
System.out.println("黄焖鸡");
}
//睡觉
public void sleep(){
System.out.println("睡觉");
}
}
手机类的定义
完成学生定义:模仿学生类,定义手机类
手机的事物:
属性: 品牌、颜色、价格
行为: 打电话、发短信、玩游戏
class Phone {
String color; // 颜色
String brand; // 品牌
// 打电话
public void call() {
System.out.println("拨打电话");
}
public void sendSms() {
System.out.println("发送短信");
}
}
类的使用
学生类的使用
- 使用步骤
- 在一个java文件中新建一个测试类。
- 如何使用呢?
- 需要拿到对应类的对象才能使用。
- 使用new创建对象 如何创建对象呢?
- 格式:类名 对象名 = new 类名(); 如何使用成员变量呢?
- 格式:对象名.变量名 如何使用成员方法呢?
- 格式:对象名.方法名(…)
成员变量和局部变量的区别
- 在类中的位置不同
- 成员变量:在类中方法外
- 作用范围:整个类
- 局部变量:在方法定义中或者方法声明上。
- 作用范围:当前方法或者代码块,定义在 for 循环中的 i ,i 的变量只在 for 循
- 环语句中可以使用。
- 在内存中的位置不同(如果没有介绍到堆栈,那么不需要讲)
- 成员变量:在堆内存
- 局部变量:在栈内存
- 生命周期不同 作用域不同
- 成员变量:随着对象的创建而存在,随着对象的消失而消失
- 局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
- 初始化值不同
- 成员变量:有默认初始化值
- 局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。
- 注意事项:局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。
示例代码
class Variable {
// 成员变量
int num = 20;
public void show() {
// 局部变量
int num2 = 30;
int num = 40;
System.out.println(num);
System.out.println(num2);
}
}
class VariableDemo {
public static void main(String[] args) {
// 创建对象
Variable v = new Variable();
v.show();
}
}
注:
补充知识点:
Java内存
Java 程序在执行时,需要使用内存来存储执行过程中产生的数据,而且要存储的东西
比较多,数据类型也不一样,如果不对这块内存区域进行划分管理,会显得比较杂乱无章。
所以需要对内存进行划分,方便管理。
Java内存通常被划分为 5个区域:程序计数器(Program Count Register)、本地
方法栈(Native Stack)、方法区(Methon Area)、栈(Stack)、堆(Heap)。各个
内存区所负责的功能不同。栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new
出来的对象)或者常量池中(字符串常量对象存放在常量池中。)堆:存放所有new出来的对象。
基本类型和引用类型作为参数传递
Java中数据类型
基本数据类型:byte、short、int、long、float、double、char、boolean
引用类型:类(class)、接口(interface)、数组(array)Java中参数传递问题
形式参数类型分两种
基本类型:形式参数的改变不影响实际参数
引用类型:形式参数的改变直接影响实际参数方法的参数是类名
如果你看到了一个方法的形式参数是一个类类型(引用类型),这里其实需要的是该类
的对象。在传递过程中,传递的是该类对象的地址值.
注意:在Java里面基本类型和 String是按值传递,因为 String底层是char实现,char
是基本数据类型,其它都是引用传递
- 基本数据类型
基本类型作为参数传递时,其实就是将基本类型变量 a空间中的值复制了一份传递给调
用的方法 changeArgs(),当在 changeArgs()方法中 a 接受到了复制的值,再在
changeArgs()方法中对 a 变量进行操作,这时只会影响到 changeArgs 中的 a。当
changeArgs()方法执行完成,程序又回到 main方法执行,main方法中的a值还是原来的
值。当引用变量作为参数传递时,这时其实是将引用变量空间中的内存地址(引用)复制了
一份传递给了 changeArr()方法的 arr 引用变量。这时会有两个引用同时指向内存中的同
一个对象。当执行changeArr方法中的arr[0] = 30时,会根据arr所持有的引用找到
内存中的对象,并将其 arr[0]的值改为30,由于是两个引用指向同一个对象,不管是哪一
个引用改变了引用的所指向的对象的中的值,其他引用再次使用都是改变后的值。
String 数据类型,在传递改变后,返回的值是不变的,String 是有char组成的,char类型不改变,String类型也不改变
封装
封装概述
封装,是面向对象思想的特征之一。面向对象共有三个特征:封装,继承,多态。
封装表现:
- 方法就是一个最基本封装体。
- 类其实也是一个封装体。
从以上两点得出结论,封装的好处:
1. 提高了代码的复用
2. 隐藏了实现细节,还要对外提供可以访问的方式。便于调用者的使用,这是核心之一也可以理解为就是封装的概念。
3. 提高了安全性。
封装举例
机箱:
一台电脑,它是由 CPU、主板、显卡、内存、硬盘、电源等部件组成,其实我们将这些部件组装在一起就可以使用电脑了,但是发现这些部件都散落在外面,很容造成不安全因素,于是,使用机箱壳子,把这些部件都装在里面,并在机箱壳上留下一些插口等
总结:机箱其实就是隐藏了办卡设备的细节,对外提供了插口以及开关等访问内部细节的方式。
封装原则
将不需要对外提供的内容都隐藏起来
把属性隐藏,提供公共方法对其访问
封装好处
隐藏实现细节,提供公共的访问方式
提高了代码的复用
提高安全性
private关键字的概述和特点
private关键字特点
是一个权限修饰符
可以修饰成员变量和成员方法
被其修饰的成员只能在本类中被访问
案例演示 private关键字特点
class Student {
private String name;
private int age;
private String gender;
public void show() {
System.out.println(name + "的年龄是:" + age + ",性别是:" + gender);
}
}
class StudentDemo {
public static void main(String[] args) {
Student s = new Student();
s.name = "学生一";
s.age = 23;
s.gender = "女";
s.show();
}
}
名字、年龄、性别等信息已被私有,错误的值无法赋值,可是正确的值也赋值不了,这样还是不行,那怎么办呢?按照之前所学习的封装的原理,隐藏后,还需要提供访问方式。只要对外提供可以访问的方法,让其他程序访问这些方法。同时在方法中可以对数据进行验证。 一般对成员属性的访问动作:赋值(设置 set),取值(获取 get),因此对私有的变量访问的方式可以提供对应的setXxx或者 getXxx的方法。
代码:
class Student {
// 把属性隐藏起来
private String name;
private int age;
private String gender;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public void show() {
System.out.println(name + "的年龄是:" + age + ",性别是:" +
gender);
}
}
public class StudentTest {
public static void main(String[] args) {
// 创建对象
Student s = new Student();
// 不能直接访问了
// s.name = "学生一";
// s.age = 23;
// s.gender = "女";
// 通过setxxx 方法设置值
s.setName("学生一");
s.setAge(18);
s.setGender("女");
}
}
匿名对象的概述和应用
匿名对象的概念
匿名对象是指创建对象时,只有创建对象的语句,却没有把对象的地址值赋值给某个变量
说白了就是没有名字的对象
如:已经存在的类:
代码
public class Student {
public void eat() {
System.out.println("吃");
}
}
创建一个普通对象
Student p = new Student();
创建一个匿名对象
new Student();
匿名对象的特点
- 创建匿名对象直接使用,没有变量名。
new Student().eat() //eat方法被一个没有名字的 Student对象调用了。
匿名对象在没有指定其引用变量时,只能使用一次。
new Student().eat(); 创建一个匿名对象,调用eat方法
new Student().eat(); 想再次调用eat方法,重新创建了一个匿名对象匿名对象可以作为方法接收的参数、方法返回值使用
匿名对象应用场景
调用方法,仅仅只调用一次的时候。
注意:调用多次的时候不适合,因为用一次就是创建了一个新的对象
匿名对象可以作为实际参数传递,传递的时候实际是传递的内存中的地址值.
代码演示
class StudentUtils {
public static Student getStudent() {
// 普通方式
// Student s = new Student();
// return s;
// 匿名对象作为方法返回值
return new Student();
}
public static void printStu(Student s) {
System.out.println(s);
}
}
class Test {
public static void main(String[] args) {
// 调用getStudent方法,得到一个Student对象
Student s = StudentUtils.getStudent();
// 调用printStu方法
StudentUtils.printStu(s);
// 匿名对象作为方法接收的参数
StudentUtils.printStu(new Student());
}
}