Java面向对象编程之类和对象

Java编程语言是一种面向对象的编程语言,其特性在于高度的抽象性。那么,什么是面向对象呢?面向对象和面向过程有什么区别呢?万物可归类,什么是类呢?万物皆对象,类和对象之间的联系是什么?Java程序的运行需要jvm(Java虚拟机)的支持,那么,面向对象编程在计算机中怎么进行内存分析;任何类都有自己的构造方法,构造方法和常见的方法体是一样的吗?

(一)面向对象和面向过程
面向对象和面向过程同为对软件分析设计开发的一种思想,指导人们用不同的思想设计开发软件。
1. 举个栗子: 设计五子棋来理解面向过程与面向对象。 面向过程的设计思路就是首先分析问题的步骤:1、开始游戏,2、黑子先走,3、绘制画面,4、判断输赢,5、轮到白子,6、绘制画面,7、判断输赢,8、返回步骤2,9、输出最后结果。把上面每个步骤用不同的方法来实现。
面向对象的设计思路是抽象组成问题的类,整个五子棋可以分为1、黑白双方,这两方的行为是一模一样的,2、棋盘系统,负责绘制画面,3、规则系统,负责判定诸如犯规、输赢等。第一类对象(玩家对象)负责接受用户输入,并告知第二类对象(棋盘对象)棋子布局的变化,棋盘对象接收到了棋子的变化就要负责在屏幕上面显示出这种变化,同时利用第三类对象(规则系统)来对棋局进行判定。
2. 面向过程(OO):面向过程程序是由不同的函数组成,最小的程序单元是函数,每个函数负责完成某一个功能,用于接受输入数据,函数对输入数据进行处理,然后输出结果数据,整个软件系统由许多函数组成,其中作为程序入口的函数称之为主函数,主函数依次调用其他函数,普通函数之间可以相互调用,从而实现整个系统功能。当你拿到一个问题时,你分析这个问题 是第一步先做什么,第二步再做什么,分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现。其特点在于适合简单任务,无需协作。指导思想是:具体问题具体分析

                                       面向过程的程序=算法+数据结构

3. 面向对象(OOP):是以功能来划分问题,而不是步骤,以一种组件化的形式进行代码设计,对于某一类问题的解决,一种以对象为基础,以事件或消息来驱动对象执行处理的程序设计技术。它具有抽象性、封装性、继承性及多态性 。面向对象处理问题:将面对的问题抽象处理,以对象为中心封装成不同的类,然后实例化不同的具体对象,利用具体的对象来描述在整个问题的解决中所起到的作用。指导思想是:透过现象看本质。

                                                     对象=算法+数据结构
                                               面向对象的程序=N个对象+控制信息

4. 二者联系

              1>都是解决问题的一种思维方式 
              2>简单问题可以使用面向过程的编程思想
              3>复杂问题在宏观层面上使用面向对象编程,在微观层面上使用面向过程编程。

5. 实例蛋炒饭和盖浇饭
用面向过程的方法写出来的程序是一份蛋炒饭,而用面向对象写出来的程序是一份盖浇饭。
蛋炒饭制作把米饭和鸡蛋混在一起炒匀。盖浇饭呢,则是把米饭和盖菜分别做好,你如果要一份红烧肉盖饭呢,就给你浇一份红烧肉;如果要一份青椒土豆盖浇饭,就给浇一份青椒土豆丝。

蛋炒饭的好处就是入味均匀,吃起来香。如果恰巧你不爱吃鸡蛋,只爱吃青菜的话,那只能全部倒掉,重新做一份青菜炒饭了。盖浇饭就没这么多麻烦,你只需要把上面的盖菜拨掉,更换一份盖菜就可以了。盖浇饭的缺点是入味不均,可能没有蛋炒饭那么香。 那么从饭馆角度来讲的话,做盖浇饭显然比蛋炒饭更有优势,他可以组合出来任意多的组合,而且不会浪费。

盖浇饭的好处就是”菜”“饭”分离,从而提高了制作盖浇饭的灵活性。饭不满意就换饭,菜不满意换菜。用软件工程的专业术语就是”可维护性“比较好,”饭” 和”菜”的耦合度比较低。蛋炒饭将”蛋”“饭”搅和在一起,想换”蛋”“饭”中任何一种都很困难,耦合度很高,以至于”可维护性”比较差。软件工程追求的目标之一就是可维护性,可维护性主要表现在3个方面:可理解性、可测试性和可修改性。面向对象的好处之一就是显著的改善了软件系统的可维护性。

(二)类和对象
<1>类的定义
对所具有相同特征实体的抽象。
在面向对象的程序设计语言中,类 是抽象的概念集合,表示的是一个共性的产物,类之中定义的是属性和行为(方法) 。
类就是具备某些共同特征的实体的集合,它是一种抽象的数据类型,
比如说动物就是一类事物,作为动物是一个类的定义,即为class。其属性就是动物所具有的特性,比如说大小,形状,等,行为即是指动物所具有的行为方式,行走,吃饭,睡觉等。

//定义类的格式
public class 类名{
        定义属性: 类的特性,事物的基本特征,可以通过变量来定义属性,比如人的姓名
             private String    name    =  “张飞”;
           修饰符 数据类型 变量名 = 值;
定义方法: 类具有的行为   用来定义该事物的具体功能的。
    修饰符 返回值类型 方法名(参数列表){
                          
            }
      }

定义一个人的类:

class Person {     // 类名称首字母大写
    String name ;   //属性
    int age ;
    public void tell() {        // 没有static,方法、
             System.out.println("姓名:" + name + ",年龄:" + age) ;
     }
}

<2>对象的定义
对象就是一个真实世界中的实体,对象与实体是一一对应关系的,意思就是现实世界的每一个实体都是一个对象,所以对象是一个具体的概念,(类的具体化和实例化)
动物类为例,具体的某个动物,比如说猫,猫作为一个具体的对象,不仅具有动物类的所有属性和行为,同时可以具有自己的特点。
在这里插入图片描述

属性用来描述具体某个对象的特征。比如小志身高180M,体重70KG,这里身高、体重都是属性。
面向对象的思想就是把一切都看成对象,而对象一般都由属性+方法组成!

属性属于对象静态的一面,用来形容对象的一些特性,方法属于对象动态的一面,咱们举一个例子,小明会跑,会说话,跑、说话这些行为就是对象的方法!所以为动态的一面, 我们把属性和方法称为这个对象的成员!

<3>类和对象的比较
类和对象的区别
  1,类是一个抽象的概念,它不存在于现实中的时间/空间里,类只是为所有的对象定义了抽象的属性与行为,类是对于一系列对象的抽象。就好像“Person(人)”这个类,它虽然可以包含很多个体,但它本身不存在于现实世界上。
  2,对象是类的一个具体。它是一个实实在在存在的东西。
  3,类是一个静态的概念,类本身不携带任何数据。当没有为类创建任何对象时,类本身不存在于内存空间中。
  4,对象是一个动态的概念。每一个对象都存在着有别于其它对象的属于自己的独特的属性和行为。对象的属性可以随着它自己的行为而发生改变。  
类:具有同种属性的对象称为类,是个抽象的概念。比如“人”就是一类,期中有一些人名,比如小明、小红、小玲等等这些都是对象,类就相当于一个模具,他定义了它所包含的全体对象的公共特征和功能,对象就是类的一个实例化,小明就是人的一个实例化!我们在做程序的时候,经常要将一个变量实例化,就是这个原理!我们一般在做程序的时候一般都不用类名的,比如我们在叫小明的时候,不会喊“人,你干嘛呢!”而是说的是“小明,你在干嘛呢!”

(三)面向对象内存分析
Java虚拟机的内存:栈stack,堆heap,方法区method area

  • 栈中保存的是Java八种基本数据类型的变量(short, int, long, byte, double, float, char, boolean),引用数据类型的局部变量,对象的引用变量(相当于对象实例或者数组的名字)
    1>描述的是方法执行的内存模型,每个方法调用都会创建一个栈帧(存储局部变量,操作数方法入口等)
    2>jvm为每个线程创建一个栈(存储模型类似于子弹夹),用于存放该线程执行方法的信息(如实参)
    3>栈属于线程私有,不能实现线程的共享
    4>栈的存储模型:先进后出,后进先出,(类似于子弹夹)
    5>栈由系统自动分配,一个连续的内存空间。、
  • 堆的特点用来存放动态产生的数据,比如new出来的对象
    1>堆用来存储创建好的对象和数据
    2>jvm只有一个堆,且被所有线程共享
    3>堆是一个不连续的存储空间。
  • 方法区的特点
    1>jvm只有一个方法区,被所有线程共享
    2>方法去也是堆,常用来存储常量相关的信息。
    3>用来存放程序中不变或者唯一的内容。

在这里插入图片描述

举例说明:

//车类
class Car{		//事物的公共属性使用成员变量描述。
	String	name; //名字的属性
 	String	color; //颜色属性
 	int wheel;	//轮子数
 		//事物的公共行为使用函数描述。
	public void run(){
		System.out.println(name+"飞快的跑起来啦...");
	}
} 
class Demo1{
	public static void main(String[] args){	
		Car c1 = new Car(); 
		c1.name = "宝马";
		Car c2 = new Car();
		c2.name = "大众";
		c1 = c2; 
		System.out.println("名字:"+ c1.name);
	}
}

运行结果:名字:大众
内存分析:
在这里插入图片描述

jvm以main函数作为程序入口:
1.先声明了c1变量 分配在栈内存
2.new Car 在堆内存创建了一个车对象 看看Car有那些成员属性,然后再给对象分配初始值,为name=null,color=null,wheel=0 (成员一旦创建,对象的成员变量也会马上分配默认的初始值) 然后把地址0x97赋给了c1 c1就指向了车的这个对象。
3. c1.name就是c1拿着地址找到车的对象 然后把name改成" 宝马 "
4.再声明了c2变量 分配在栈内存
5.再new 一个 Car 在堆内存再创建了一个车对象 看看Car有那些成员属性,然后再给对象分配初始值,为name=null,color=null,wheel=0 (成员一旦创建,对象的成员变量也会马上分配默认的初始值) 然后把地址0x67赋给了c2 c2就指向了车的这个对象。
6. c2.name就是c2拿着地址找到车的对象 然后把name改成“ 大众 ”
7. 把c2的持有地址赋给了c1 c1的地址原来是0x97 改为 0x67
8 c1拿着改后的地址去找地址为0x67的对象 输出为0x67地址的对象中的属性name.
所以结果为;大众

java1内存分析:
Java内存分配全面浅析
java运行的详细内存分析,精确到每一步!!!!
Java 内存分配全面浅析 ]

(四)构造方法

  用于对象的初始化

(1)通常用new关键字调用
(2)构造器有返回值,但不能定义返回值类型,且不能再构造器中使用returen返回一个值
(3)若没有定义构造器,系统会自定义一个
(4)构造器必须和·类名一致
普通方法有返回类型,方法名小写,不能和类名相同,如:void XX(){}  普通方法:代表对象可以干什么
Java中类的构造方法

总结: 面向对象和面向过程是两种不同的编程思想,面向对象利用事物的共性抽象成类,然后实例化以形成对象,从A到B,怎么走,先抽象一个A类,抽象一个B类,然后抽象一个路径类,设计每一个类的具体方法,实例化三个类即可。也就是透过现象看本质,面向过程的编程思想对待不同的问题有不同的解决方式,从A到B,怎么走,第一步是什么,第二步是什么,等等,具体问题具体分析。类是一个高度抽象的思维,也即一类有共性的实物的抽象,对象是类的实例化,即类的具体某一个实际形象,任何问题都可以抽象成几个类的集合, 通过设计类自己在整个问题中的方法,然后实例化类,通过类之间的关系来解决问题。jvm虚拟机用来运行Java程序,对于程序进行内存分析时,通过mian函数作为程序的入口,在栈中分配内存,在堆中分配初始化成员属性,存储创建好的对象和数据。构造方法和普通方法一样,用来表示对象可以做什么,只不过,过早方法必须和类名相似,用于对象的初始化。

猜你喜欢

转载自blog.csdn.net/weixin_41792162/article/details/83684316