首页 > 编程语言 >Java基础-面向过程和面向对象

Java基础-面向过程和面向对象

时间:2024-02-27 17:34:45浏览次数:34  
标签:Java 变量 构造方法 对象 成员 面向对象 面向 静态 方法

面向过程和面向对象都是对软件分析、设计和开发地一种思想,它指导着人们以不同的方式去分析、设计和开发软件。这两种思想是相辅相成的。

面向过程:

使用面向过程思想思考问题时,我们首先思考“怎么按步骤实现?”并将步骤对应成方法,一步一步,最终完成。这个思想适合简单任务,不需要过多协作的情况下。比如:如何开车?

面向对象:

使用面向对象思想思考问题时,我们首先思考的是“有什么?”并将一件物体拆分成无数个物体,一步一步进行设计,最终完成,这样适合较复杂的任务,比如:如何造车?

面向对象和面向过程的总结:

  1. 都是解决问题的思维方式,都是代码组织的方式。
  2. 解决简单问题可以使用面向过程。
  3. 解决复杂问题:宏观上使用面向对象把握,微观处理上仍然是面向过程。

2. 对象的进化史(数据管理和企业管理的共通之处)

  • 数据无管理时代
  • 数组管理和企业部门制
  • 对象和企业项目制

3. 对象和类的概念

类可以看作是一个模板,或者图纸,系统根据类的定义来造出对象。

class

对象:我们叫做Object,instance(实例)。以后我们说某个类的对象,某个类的实例,是一个意思。

1. 类的定义:

Java中类的定义分为两个部分:类的声明和类的主体。

1. 类的声明:

格式如下:

[<修饰符>] class <类名> [extends <父类>][implements <接口名>]
  1. 类定义修饰符。类定义修饰符为类声明的可选部分,定义类的性质(如abstract、final)和访问权限(public、默认)。
  2. extends。extends为类声明中的可选部分,用于说明类的父类。一般形式为extends<父类>。Java语言中,如果在类声明中无extends,则该类的父类均隐含为java.lang.Object。不同于c++,Java不支持多重继承,因此,extends之后最多只可跟一个类。
  3. implements。implements为类声明的可选部分,用于说明该类实现的接口。java允许一个类实现多个接口,接口之间使用“,”隔开。

2. 类主体:

类主体包括类的成员变量(field)的说明和成员方法(method)的定义与实现。

1. 成员变量

成员变量定义的一般格式:

[变量修饰符] <变量类型> <变量名>
1. 变量修饰符包括权限修饰符和静态修饰符等:
  1. 权限修饰符分为四种:
    • public:允许被任何程序包中的类访问;
    • protected:允许被类自身、子类及其相同包的类访问;
    • 默认/default:允许类自身及其同一个包内的类所访问;
    • private:只允许类自身进行访问;
  2. 静态修饰符:
    • static:修饰类变量:如果一个数据需要被所有对象共享使用的时候,那么即可使用static修饰该成员变量。

    • 访问方式:

      1. 可以使用对象进行访问。 格式:对象.静态属性名
      2. 可以使用类名进行访问。 格式:类名.静态属性名
    1. 静态的成员变量可以使用类名或者是对象进行访问。
    2. 非静态的成员变量只能使用对象进行访问,不能使用类名直接访问。
    3. 千万不要为了方便而是用static修饰一个成员变量,只有这个成员变量的数据是需要被共享的时候才使用static修饰。

推荐使用类名进行访问。

  1. final

被final修饰的成员变量不可变。

2. 变量类型:

可以是Java语言中任意的基本数据类型或引用数据类型(如类,数组等)。

3. 变量名:
  1. 类中成员变量名必须唯一。
  2. 但允许成员变量的名字与类中的成员方法同名。
  3. 不同类中也允许出现同名的变量名。
2. 成员方法:
            成员方法定义的一般形式如下:
                与普通方法一样。
1. 方法修饰符:

主要有public、private、protected、final、static、abstract和synchronized。

  1. 访问权限修饰符:同成员变量的权限修饰符。
  2. final:修饰最终方法,被final修饰的成员方法不允许被子类重载。
  3. static:
    • 用于修饰类方法(或静态方法),与类变量类似,类方法不需要通过创建对象来使用,可以直接通过类来访问,类方法也不允许被重载。
    1. 非静态的方法只能使用对象调用,不能使用类名调用
    2. 静态方法可以直接访问静态的成员,但是不能直接访问非静态的成员
      • 因静态方法可以使用类名调用,而这个时候对象可能还没有存在在内存中,这时候非静态的数据也就不存在在内存中。
    3. 非静态方法可以直接访问静态以及非静态的成员
      • 因非静态方法必须要由对象调用,如果对象存在了,静态数据以及非静态数据早就存在内存中了。
    4. 静态函数不能出现this以及super关键字
      • 因静态方法可以使用类名直接调用,而这个时候可能还没有对象存在,this又要代表当前对象。
  4. abstract:用于修饰抽象方法,该方法只有方法声明,没有方法体。
  5. synchronized:修饰符用于线程同步。
2. 方法返回值类型:

成员方法的返回值的类型可以是Java语言的任何数据类型,包括自定义类。

如果一个成员方法不需要返回值,则其返回值的类型为void。

如果有返回值,那么return语句要带参数,并且return语句中返回的数据类型必须与方法说明中的方法返回值的类型一致。

3. 方法名:

方法名是Java语言的合法标识符,方法命名建议符合Java编程规范:首字母小写,并符合驼峰命名规则。

4. 参数列表:

成员的方法列表有逗号分隔的类型即参数名组成,是可选项。参数的类型可以是Java语言的任何数据类型。

5. 方法体:

方法体用{}括起来,是方法定义的主要部分,包含了实现方法功能的代码。

在方法体中可以定义局部变量,他的作用域仅在方法体内。

3. 构造方法(constructor):
  1. 构造方法也属于方法,但是是一种非常特殊的方法。
  2. 构造方法用于生成该类的一个对象实例,并对对象实例中的成员变量初始化。
  3. 当用new关键字创建一个类的新对象时,构造方法立即执行。
  4. 构造方法的名字必须与类名相同,语法如下:
public 类名([参数列表]){
	[语句序列];
}
  1. 注意:

    1. 构造方法没有返回值类型,甚至没有void。其修饰符只能是public、private、protected中的任一个。

      • 虽然不能定义返回值类型,但是本质上构造方法是有返回值的。因为返回值类型一定是本类,所以不可以自行定义返回值类型。不能在构造方法中使用return返回某个值。
    2. 构造方法不能从父类中继承。

    3. 系统默认提供无参构造方法,该方法根据成员变量的类型进行初始化,数值类型的成员变量被初始化为0,boolean类型的成员变量被初始化为false,引用类型的成员变量被初始化为null。

    4. 构造方法可以重载,一个类可以有任意多个构造方法。若重载了构造方法,系统将不再提供无参构造方法。

    5. 构造方法不能直接通过方法名调用,必须通过new运算符调用。

      • 但是创建对象不仅仅可以用new,还可以利用反射机制等等进行创建。
    6. 在构造方法中可以调用当前类和其父类的另一个构造方法,但必须是方法体的第一条语句。使用当前类的构造方法用this来引用,使用其父类的构造方法用super来引用。

4. UML图

用来表示一个类的结构:包括属性和方法.

2. 面向对象的内存分析:

Java虚拟机的内存可以分为3个区域:栈stack、堆heap、方法区method area(本质上是在堆中,但是由于比较特殊,所以单列出来).

1. 栈stack:

栈的特点如下:

  1. 栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)
  2. JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)
  3. 栈数与线程私有,不能实现线程之间的共享。
  4. 栈的存储特性是“先进后出,后进先出”。
  5. 栈是由系统自动分配,速度快。栈是一个连续的内存空间。

2. 堆heap:

堆的特点如下:

  1. 堆用于存储创建好的对象和数组(数组本质上也是一个对象)。
  2. JVM只有一个堆,被所有线程共享。
  3. 堆是一个不连续的内存空间,分配灵活但是速度慢。

3. 方法区method area(又叫静态区):

方法区的特点如下:

  1. JVM只有一个方法区,被所有线程共享。
  2. 方法区实际也是堆,知识用于存储类、常量相关的信息。
  3. 用来存放程序中永远是不变或唯一的内容。(类信息【Class对象】、静态变量、字符串常量等)。

4. 当一个程序启动之后会发生什么?

  1. 使用java.exe来运行这个程序时,JVM启动,会创建堆、栈和方法区。
  2. 首先要将整个类的相关信息全部加载到方法区中。比如:代码、静态变量、静态方法、字符串常量等等...
    • 代码中所有带引号的都是字符串常量,都将在类加载的时候存入方法区内。
  3. 程序开始调用main方法,则在栈中创建一个main方法的栈帧。
`Student st = new Student();`

方法中若创建一个对象,首先要调用构造方法,栈中创建一个构造方法的栈帧。堆中出现被创建好的对象及其地址。利用赋值符号将st = 该对象的地址。

属性赋值就是利用对象的地址在堆中找到该对象,将其对象的属性进行赋值。(字符串赋值是要在方法区中找到字符串常量的地址,将其赋值)。

当一个方法调用完成之后栈帧就会删除。

4. 垃圾回收机制:

1. 垃圾回收机制

Java引用了垃圾回收机制,令c++程序员最头疼的内存管理问题迎刃而解。Java程序员可以将更多的精力放到业务逻辑上而不是内存管理工作上,大大的提高了开发效率。

1. 内存管理:

java的内存管理很大程度上指的就是对象的管理,其中包括对象空间的分配和释放。

对象空间的分配:使用new关键字创建对象即可。

对象空间的释放:将对象赋值null即可。垃圾回收期将负责回收所有“不可达”对象的内存空间。

2. 垃圾回收过程:

任何一种垃圾回收算法一般要做2件基本事情

  1. 发现无用的对象。
  2. 回收无用对象占用的内存空间。

垃圾回收机制保证可以将“无用的对象”进行回收,无用的对象指的就是没有任何变量引用该对象。Java的垃圾回收器通过相关算法发现无用对象,并进行清除和整理。

3. 垃圾回收相关算法:

引用计数法:

堆中每个对象都有一个引用计数,被引用一次,计数+1,被引用变量值变为null,则计数-1,直到计数为0,则表示变成无用对象,优点是算法简单,缺点是“循环引用的无用对象”无法被识别。

引用可达法:

程序把所有的引用关系看作一张图,从一个节点GC ROOT开始,寻找对象的引用节点,找到这个节点以后,继续寻找这个节点的引用节点,当所有的引用节点寻找完毕之后,剩余的节点则被认为是没有被引用的节点,即无用的节点。

2. 通用的分代垃圾回收机制:

分代垃圾回收机制是基于一个事实:不同的对象的生命周期是不一样的。因此,不同生命周期的对象可以采取不同的回收算法,以便提高回收效率,我们将对象分为3种状态:年轻态、年老态和持久态。JVM将堆内存划分为Eden、Survivor和Tenured/old空间。

垃圾回收过程:

  1. 新创建的对象,绝大多数都会存储在Eden区中
  2. 当Eden满了(达到一定比例)不能创建新的对象,则触发Minor GC,清理无用对象,将有用的对象全部复制到Survivor1或者Survivor2中,如放到了Survivor1中,同时清空Eden区。
  3. 当Eden区再次满了,会将Survivor1中有用的对象放到Survivor2中,同时将Survivor1中的对象清空,然后将Eden区中的有用对象复制到Survivor1中。
  4. 默认当一个对象在Survivor1和Survivor2中重复15次也没有被清理的对象,会被复制到Old/Tenured区中。
  5. 当Old区满了之后,则会触发一个一次完整地垃圾回收(Full GC)。

【注】:Full GC:用于清理年轻代、年老代区域。成本比较高,对系统性能产生影响。所以平时我们的JVM调优,就是有很大一部分是对于Full GC的调节。

5. 对象创建的过程和this、static关键字:

类是对象模板,只有实例化之后才可以使用。

1. 对象的创建:

1. 对象声明:

对象声明的一般格式:
类名 对象名;

声明了对象名之后,该对象还没有引用任何实体,只是一个空对象(null)。

2. 对象创建:

new运算符用于创建一个类的实例并返回对象的引用。一般格式如下:
对象名 = new 类名([参数列表]);

  1. 对象的声明并不为对象分配内存空间。用new运算符为对象分配内存空间,实例化一个对象,并根据所调用的构造方法进行成员变量初始化。
  2. 如果使用的是默认构造方法,则初始化规则如下:
    • 对于整型成员变量,默认初值为0;
    • 对于浮点型成员变量,默认初值为0.0;
    • 对于boolean类型成员变量,默认初值为false;
    • 对于引用型成员变量,默认初值为null;
  3. 一个类可以有多个对象,并分别为每个对象分配空间,一个对象的成员变量的改变不会影响其他对象的成员变量(类变量除外)。

3. 对象使用

可以通过“.”运算符来实现对自己的成员变量和方法的调用。

4. 对象的释放:

通过垃圾回收器GC

【总结】创建一个对象过程分为4步:

  1. 分配对象空间,并将对象成员变量初始化。
  2. 执行属性值的显式初始化。
  3. 执行构造方法。
  4. 返回对象的引用给相关的变量。

2. this的本质:

this的本质就是“创建好的对象的地址”,由于在构造方法调用前,对象已经创建(对象已经分配好了内存,this指针指向的是这块内存)。因此在构造方法中也可以使用this代表“当前对象”。

在实例方法和构造方法中使用this

区分成员变量和局部变量:

成员变量在整个类中有效,局部变量仅在方法内有效。在方法体中的声明变量以及方法的传入参数均称为局部变量,局部变量只在方法体内有效。

如果实例方法中或类方法中的局部变量名字与成员变量名字相同,这个成员变量在这个方法内暂时失效。如果确实想引用成员变量,则可以使用this关键字。

返回实例对象本身的引用

this还可以作为类成员方法的return语句的参数,用来返回对象本身的引用。

使用this调用类的其他构造方法:

在类的构造方法中,可以使用this()来调用该类的其他构造函数,具体调用那个构造函数是根据this的参数类型来确定的。this调用其他构造方法一定要在方法体中的第一行。

this不能用于static方法中

this指的是当前对象,但是static方法是类方法,可以在对象创建之前调用此方法,则this不可以存在static方法中。

3. static关键字:

在类中,用static声明的成员变量为静态成员变量,也称为类变量。类变量的生命周期和类相同,在整个应用程序执行期间有效。static修饰的成员变量和方法,从属于类。普通变量和方法从属于对象的。

静态方法中不可以使用非静态方法和非静态变量。

静态初始化块:

  1. 构造方法用于对象的初始化。静态初始化块用于类的初始化操作。在静态初始化块中不能直接访问非static成员。
  2. 静态初始化块在类加载的时候就已经执行了,所以说没有创建对象,也会执行静态初始化块内的内容。

【注意事项】:
1.上溯到Object类,先执行Object的静态初始化块,再向下执行子类的静态初始化块,直到我们的类的静态初始化块为止。
2.构造方法执行顺序和上面顺序一样。

6. 参数传值机制:

Java中方法中所有参数都是“值传递”,也就是“传递的是值的副本”。也就是说,我们得到的是“原参数的复印件,而不是原件”。因此复印件改变不会影响原件。

基本数据类型参数的传值:

传递的是值的副本,副本改变不会影响原件。

引用类型参数的传值:

传递的是值的副本,但是引用类型指的是“对象的地址”。因此,副本和原参数都指向了同一个“地址”,改变“副本指向地址对象的值,也就意味着原参数指向对象的值也发生了改变”。

7. 包机制和命名空间:

包机制是java中管理类的重要手段。开发中,我们会遇到大量同名的类,通过包我们很容易对解决类重名的问题,也可以实现对类的有效管理。包对于类,相当于文件夹对于文件的作用。

1. 命名空间

Java注重解决名字空间的冲突问题,没有全局方法、全局变量。

所有的变量和方法都是在类中定义,且是类的重要组成部分,每个类又是包的一部分,因此每个java变量或方法都可以用全限定的名字定义,即使用包名、类名、域名三部分(之间用“.”分隔)的形式访问类成员。

2. 包的定义和引入:

1. 包的定义:

一般可以使用package知名源文件中的类数与那个具体的包。定义包语句的格式如下:

package pkg1[.pkg2[.pkg3...]];
  1. 包的名字有层次关系,各层之间以点分隔。包层次与java开发系统的文件系统结构相同,也就是说包名和他们的结构应该同目录(文件夹)相对应。
  2. 需要注意的是,如需要定义包,程序首行必须是package语句,他的前面只能由注释或者空行。另外,一个文件只能有一个package语句。
  3. 包的命名规范:域名倒着写:com.jd(京东)、com.alibaba(阿里巴巴)
  4. com.gsl和com.gsl.car,这两个包没有包含关系,时两个完全独立的包。只是逻辑上看起来后者是前者的一部分。

2. 包的引入:

当使用其他的包内的类时,需要在package语句之后使用import语句。import语句的格式如下:

import pkg1[.pkg2[.pkg3...]];
  1. import语句用于将其他包的类引入当前名字空间中,而当前包总是处于当前名字空间中,程序中无需引用同一个包或该包的任何元素。
  2. java.lang包被默认导入,即可以直接使用。除此之外,JDK主要还有java.io、java.util、java.awt、java.swing、java.awt.image、java.applet、java.net、java.sql、sun.tools.debug等包。

3. 静态导入(import static):

静态导入的作用是导入指定类的静态属性,这样我们可以直接使用静态属性。

标签:Java,变量,构造方法,对象,成员,面向对象,面向,静态,方法
From: https://www.cnblogs.com/guosiliang/p/18037357

相关文章

  • Java基础-常用类
    一、字符串相关的类1.String的特性String类:代表字符串。Java程序中的所有字符串字面值(如"abc")都作为此类的实例实现。String是一个final类,代表不可变的字符序列。字符串是常量,用双引号引起来表示。他们的值在创建之后不能更改。String对象的字符内容是存储在一个字符数......
  • java 实现根据word模板生成word文件 word转pdf
    最近做项目要求生成word文件及PDF文件,生成word文件时其中内容要根据不同公司提供的内容动态替换里面的值。参考了很多之后选择用word模板生成word文件。其中主要参考:https://www.cnblogs.com/suzan/p/10577738.html 简单的word模板:https://files.cnblogs.com/files/blogs/8095......
  • Java中使用Graphics2D实现图片添加文字/图片水印
    场景java实现给图片添加水印实现步骤:获取原图片对象信息(本地图片或网络图片)添加水印(设置水印颜色、字体、坐标等)处理输出目标图片。注:博客:https://blog.csdn.net/badao_liumang_qizhi实现1、新建工具类 importorg.apache.commons.lang3.StringUtils;importjavax.im......
  • Java 中 MessageFormat.format 用法
    转载自:https://blog.csdn.net/xiaokui_wingfly/article/details/46124057 查看原文:http://www.ibloger.net/article/139.htmlMessageFormat本身与语言环境无关,而与用户提供给MessageFormat的模式和用于已插入参数的子格式模式有关,以生成适用于不同语言环境的消息。Mes......
  • 平面向量|思维导图
    前言使用方法:如果想得到更好的显示效果,可以点击全屏按钮,已经实现电脑端、手机端的适配,效果很好;电视端没有实现适配,Ipad端的适配没有测试;思维导图全屏......
  • java 通过 microsoft graph 调用outlook
    废话不多说一官方文档先看一下官方文档,https://learn.microsoft.com/zh-cn/graph/tutorials/java?context=outlook%2Fcontext&tabs=aad&tutorial-step=1其中的代码,可以通过地址下载:https://developer.microsoft.com/en-us/graph/quick-start 二授权方式microsoft登录授权......
  • Java面向对象之接口和抽象类的区别一目了然
    介绍相信对于Java面向对象部分,很多人很长一段时间对于接口和抽象类的区别,使用场景都不是很熟悉,同是作为抽象层重要的对象,工作中到底什么情况下使用抽象类,不是很清楚。本文就一次性把这些概念一次性说清楚,不用再烦恼了,哈哈!核心概念接口与抽象类最明显的区别可能就是使用上的......
  • java读取resource下的文件 下载
    点击查看代码publicvoiddownloadKsxxYzyTemplate(HttpServletRequestrequest,HttpServletResponseresponse){try{//FileDownloadUtils.downloadFileFromResource(response,YZYMB_NAME,YZYMB_URL);FileDownloadUtils.downloadFileFro......
  • iOS 面向对象与类
    至于未来会怎样,要走下去才知道反正路还很长,天总会亮。1.面向对象1.1什么是面向对象(OOP)面向对象ObjectOrientedProgramming。在软件开发中,我们虽然用的是面向对象的语言,但我相信绝大多数入门或者工作经验不长的同学敲出来的代码依然是大段的面向过程的思想,我们只是把面向......
  • C#与Java的继承与实现上的差异
    虽然C#和Java都支持继承和接口实现这两种面向对象编程的基本概念,但它们在一些细节上有一些差异。继承(Inheritance)单继承vs多继承:C#支持单继承,一个类只能直接继承自一个父类。Java也支持单继承,一个类只能直接继承自一个父类。基类构造函数的调用:在C#中,如果......