2022-07-18 第五小组 顾祥全 学习笔记 day11-JavaSE-面向对象

本文深入探讨了不同编程语言的编程思想差异,对比了面向过程与面向对象的开发特点,并通过蛋炒饭和盖饭案例理解两者。讲解了面向对象的四大特征,包括封装、继承、多态和抽象,以及Java中类、对象和它们的关系。涉及对象创建、属性访问、静态与实例的区别,以及编译过程和JVM内存分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

面向对象

1. 不同编程语言在编程思想上又什么区别?

  • C语言采用面向过程

  • C++一半采用面向对象一半采用面向过程(半面向对象)

  • Java采用面向对象(完全面向对象)

2. 面向过程和面向对象的区别

面向过程

面向过程开发特点

 面向过程注重实现功能的步骤,以及步骤之间的因果关系(高耦合,低内聚)

实现一个功能需要分为四个步骤:A步骤、B步骤、C步骤,对于步骤之间的因果关系可以这样来看:
因为A步骤----->所以B步骤,因为B步骤----->所以C步骤。
对于一个项目要求实现两个功能:A功能,B功能,A功能需要2个步骤(A1步骤---->A2步骤),B功能也需要2个步骤(B1步骤--->B2步骤) ,
在面向过程开发会这样做:将A功能的步骤划分称一个模块A,将B功能中的步骤划分一个模块B,因为模块A(A1步骤---->A2步骤)----> 所以模块B(B1步骤--->B2步骤)

从上面的步骤来看,面向过程开发中,代码之间的关联程度很高,如果有一个步骤出错,会导致所有的功能都出现问题(牵一发而动全身)。

面向过程开发的优缺点
  • 优点:在面向过程开发中,对于小型项目的开发,效率较高,前期不需要进行对象的提取、模型的建立,可以直接上手写代码,编写因果关系。(快速开发)
  • 缺点:在面向过程开发中,没有对象的概念,代码直接按的黏连程度很高,扩展力很差。不适合用于大型项目开发。

面向对象

面向对象开发特点

  面向对象编程思想,是以对象为主,更符合人类的思维方式。面向对象在开发中,把程序分为不同的单元,每个单元都实现成对象(这些对象都是独立的,彼此之间的关联程度很低),在给这些对象一个环境驱动一下,让他们彼此协作起来形成一个系统(使用面向对象开发程序:耦合度低,扩展里强)

面向对象开发的优缺点

用案例去理解面向过程与面向对象

蛋炒饭与盖饭:
蛋炒饭:
对于蛋炒饭来说,米饭和蛋混合在了一起,没有独立对象的概念。
假设客户提出需求,只要米饭不要鸡蛋怎么办?
对于客户提出的需求,软件开发者必须实现,于是开始扩展程序,这对于软件开发者来说是一场噩梦。
盖饭:对于盖饭来说,盖饭可以是由不同的菜(鱼香肉丝、香辣肉丝…) + 米饭组成,是有独立对象的概念,
鱼香肉丝可以看成一个独立对象,米饭也可以看成一个独立对象。
假设对象提出需求,我想吃鱼香肉丝盖饭。
软件开发者只需要将鱼香肉丝和米饭准备好,并且给他们一个“盖”的动作,这两个对象便组合在了一起。
假设用户不想吃鱼香肉丝盖饭了,想吃香辣肉丝盖饭
这时只需要将"鱼香肉丝"对象换成"香辣肉丝"对象即可。

面向过程主要关注的是:实现功能的步骤以及整个过程
面向过程主要关注的是:对象A、对象B、对象C,这些对象可以任意组合(ABC、BCA、CAB等…)

3. 面向对象的特征

4. 面向对象开发软件生命周期

  • OOA -----> 面向对象分析(Object-Oriented Analysis)
  • OOD -----> 面向对象设计(Object-Oriented Design)
  • OOP -----> 面向对象编程(Object-Oriented Programing)

5. Java面向对象

什么是类?

  1. 概念:类是能描述对象的共同特征。是一个模板,是不存在的
  2. 内容:
    在这里插入图片描述

什么是对象?

  1. 概念:对象是一个真实存在、具体的事物
  2. 内容
  3. 在这里插入图片描述

类与对象的关系

实例化
instance
抽象
abstract
对象
  • 类:是抽象、概念性的,是在现实世界中不存在的,是由人类观察一类对象并对其进行共性抽取(抽象) 而形成的一个模板(这个“模板”可以用于描述一类对象的共同特征)
  • 对象:对象是在现实世界中一个具体存在的个体,世界上的任何物体都可以看作为一个对象,在程序开发中,对象是由类实例化(创建) 出来的。
  • 实例:对象又被称作为实例
  • 实例化:在程序开发中,创建对象便是类的实例化
  • 抽象:此处的抽象是指,对一类对象进行共性提取,从而形成类
抽象
抽象
抽象
抽象
抽象
抽象
抽象
抽象
手机
电脑
通讯设备
IOS
Android
Windows
Mac
HUAWEI mate30实体机
小米 K30 Pro实体机

由上图可见,HUAWEI实体机和小米实体机都是一个对象,他们都是于安卓手机,将这两个对象的共同特征提取(抽象)出来,便是一个Android类,对于Android手机和Ios手机,将他们的共同特征继续提取(抽象)便成了一个手机类…

如何创建一个对象

  1. 首先需要有一个类,用于实例化对象
		class User{
	//属性(描述对象的状态信息)
	int no;				//用户编号
	String username;	//用户名
	String password;	//密码

	//行为(描述对象的动作/行为)
	sayHello();

	public static void sayHello(){
		System.out.println("你好,我是" + username + "很高兴认识你");
	}
}
  1. 创建(实例化)对象:User u1 = new User();
    在这里插入图片描述

      new User(); ----> 此处会调用User类的无参构造方法

    构造方法用于创建对象并给对象属性初始化。
    在这里插入图片描述

访问对象的属性(实例变量)和方法

  • 访问对象的属性——格式:引用(对象名).属性名
  • 访问对象的方法——格式:引用(对象名).方法名()

注意:引用不能为空,引用为空时访问实例相关的数据会报空指针异常(NullPointException)。

静态方法/静态变量 和 实例方法/实例变量 的区别

静态方法和静态变量都被static关键字修饰;实例方法和实例变量都没有被static关键字修饰。

 对于被static修饰的变量/方法被称作为静态变量/方法(也叫做类变量/方法),静态变量/方法不属于对象而是属于类的,静态变量存储在方法区内存中的静态区中。静态变量/方法可以通过"类名.变量名","类名.方法名()“的方式去访问;同时也可以通过"对象.变量名”,"对象.方法名()“的方式去访问(不建议使用)。
 对于未被static修饰的变量/方法被称作为实例变量/方法,实例变量/实例方法不属于类而是属于对象,实例变量被存储在堆内存中。实例变量/方法可以通过"引用.变量名”,"引用.方法名()"的方式区访问。

编译过程(多个源程序)

共有三个java源程序,如果想要运行TestUser类中的main方法,那么该如何去编译?
第一个程序

public class TestUser {
	public static void main(String[] args){
		User user = new User();
	}
}

第二个程序

public class User{
	int no;				//用户编号
	String username;	//用户名
	String password;	//密码
}

第三个程序

public class Student {
	int student_id;		//学号
	String name;		//姓名
}

这是源文件所在目录(用于查看编译结果的)
在这里插入图片描述
由于main方法中涉及到的源程序只有TestUser.java和User.java所以并不需要对Student.java进行编译。对于这些程序的编译可以有多种方式

  1. 使用javac TestUser.java;javac User.java
    在这里插入图片描述
    编译结果如图所示
    在这里插入图片描述

可以看出,使用这种方式需要对源文件一个一个的进行编译,太麻烦了,那么有没有更好的方式,可以继续看第二步

  1. 使用javac *.java
    在这里插入图片描述
    编译结果结果如图所示
    在这里插入图片描述

可以看出,使用这种方式会将与程序运行无关的源程序进行编译,那么又没有更好的方式呢

  1. 使用javac Test.java
    在这里插入图片描述
    编译结果如图所示
    在这里插入图片描述
    可以看出直接对带有main方法的源程序进行编译,可以顺带对main方法中所有需要用到的类进行编译,并没有对其他源程序进行编译。

所以在对源文件进行编译时,只需要对编写main方法的源程序进行编译,编译器会自动对其中涉及到的所有源程序进行编译。

创建对象时JVM内存分析

以下面的程序为例

class User{
	int no;				//用户编号
	String username;	//用户名
	String password;	//密码
	Address addr;		//地址
	//打招呼介绍自己
	public void sayHello() {
		System.out.println("我叫做:"+ username +",我的家庭地址是:" + addr.toString());
	}
}
class Address {
	String province;	//省
	String city;		//市
	String area;		//区
	//打印地址
	public String toString() {
		return "省:"+ province +",市:"+ city +",区:" + area;
	}
}

public class Test {
	public static void main(String[] args){
		//创建一个Address对象
		Address addr = new Address();
		//创建一个User对象
		User user = new User();
		//初始化addr对象中的信息
		addr.province = "吉林省";
		addr.city = "长春市";
		addr.area = "高薪区";
		//初始化user对象中的信息
		user.no = 1;
		user.username = "张三";
		user.password = "123456";
		user.addr = addr;
		//user对象打招呼介绍自己
		user.sayHello();
		
	}
}

运行结果如下
在这里插入图片描述
内存分析
在这里插入图片描述
对于main方法中的程序

  1. Address addr = new Address(); ----> 在堆内存中创建一个Address对象,并把这个对象的内存地址赋值给addr引用。
  2. User user = new User(); ----> 在堆内存中创建一个User对象,并把这个独享的内存地址赋值给user引用。
  3. addr.city = “长春市” ----> 通过addr这个引用找到这个Address对象,并修改这个对象的city属性(从null(default) —> “长春市”)。
  4. addr.area = “高薪市” ----> 通过addr这个引用找到这个Address对象,并修改这个对象的area属性(从null(default) —> “高薪区”)。
  5. user.no = 1 ----> 通过user这个引用找到这个User对象,并修改这个对象的no属性(从0(default) —> 1)。
  6. user.username = “张三” ----> 通过user这个引用找到这个User对象,并修改这个对象的username属性(从null(default) —> “张三”)。
  7. user.password = “123456” ----> 通过user这个引用找到这个User对象,并修改这个对象的password属性(从null(default) —> “123456”)。
  8. user.addr = addr ----> 通过user这个引用找到这个User对象,并修改这个对象的password属性(此处addr存放的是Address对象的内存地址,将这个内存地址赋值给user对象的addr属性)。
  9. user.sayHello(); ----> user对象调用sayHello(),在sayHello()中调用user.addr.toString()

6.Java方法

方法基础内容

在这里插入图片描述
对方法结构中的修饰符列表可以看下图

在这里插入图片描述

方法重载

在这里插入图片描述

方法的递归调用

在这里插入图片描述

方法内存分析

在这里插入图片描述

思维导图

在这里插入图片描述

Xmind文件/OneDriver共享

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值