面向对象与内存分析
1 面向对象与内存分析
1.1 面向对象三个阶段
1.1.1 面向对象分析(OOA,Object Oriented Analysis)
从个性中发现并抽取共性,包括:用于描述静态特点的名词、用于描述动态特点的动词。
1.1.2 面向对象设计(OOD,Object Oriented Design)
设计类应当具备的静态特性和动态特性,即:
①用于描述静态特点的名词,将其作为“类的属性(properties)”;
②用于描述动态特点的动词,将其作为“类的方法(methods)”。
1.1.3 面向对象编程(OOP,Object Oriented Programming)
将其用Java编程语言描述,进行编码实现。
编码-是信息从一种形式或格式转换为另一种形式的过程,也称为计算机编程语言的代码简称编码。
1.2 类-【基本模板,具备通用属性和功能的模板】
class className{
//property defining
[修饰符] 属性类型 属性名 = [默认值] ;
//method defining
[修饰符] 方法返回值类型 方法名(形参列表) {
// n条语句
}
}
1.3 创建对象-【具备特定属性值和特定功能的单个个体】
className objectName=new className([params...]);
“new”关键字会自动调用类的构造器,并返回对新创建对象的引用(地址)
构造器【构造器的对应的方法名必须和类名称相同】
相当于按照类模板,为已经生产好的单个“对象”——“进行属性赋值”的工具;
- 调用构造器的作用并非是创建类的实例,因为在进入到构造器方法体之前,this(即类的实例)已经存在;
- 调用构造器的作用:仅是为已经预先创建好的类的对象,进行属性赋值操作.
//constructor template
[修饰符] className(params){
super();
//toDo
}
1.4 创建对象的过程
1.4.1 Part-1:Java程序的执行过程
包括:编译——>解释执行两个过程,其中:
①编译:是指将.java的源代码经“[javac.exe-编译器]”编译为.class字节码文件;
②解释:是指由JVM加载.class字节码文件,并将其交由“[java.exe-解释器]”解释执行的过程。
PS:在具体执行时,是从主类的main方法开始逐行执行-main方法体中的代码语句。
1.4.2 Part-2:JVM、Javac.exe、Java.exe作用及其关系简述
1.4.2.1 JVM(Java Virtual Machine)
Java虚拟机,是运行在操作系统之上的一个应用程序,是Java平台无关特性的实现基础,具有完备的架构,包括:处理器、堆栈(Stack)、寄存器等,还具有相应的指令系统(字节码就是一种指令格式)。
In a word,JVM is an application which can read and execute byte-codes.
Technically, JVM has its own memory model(内存模型) separates from OS.
1.4.2.2 javac.exe(java编译器)
Java编译器,可以将Java源文件(.java文件)转换为Java字节码文件(.class文件,一种可供JVM读取和运行的二进制字节码文件).
1.4.2.3 java.exe(java解释器)
Java解释器,是JVM的一部分,可理解为:Java解释器用来解释Java编译器编译后的字节码文件.
*1.4.2.4 三者间的关系
javac.exe将存储在操作系统内存中的*.java源代码文件编译JVM能理解的*.class二进制字节码文件;然后由JVM将其装载到JVM内存(堆、栈、方法区、常量池等)中,供java.exe逐行解释为对应的机器码并逐行执行。
1.4.3 Part-3:对象创建的过程简述
首先明确一点,【创建类A的对象的前提,A的父类已经被实例化(类A中可以通过super()语句调起父类的构造器)】
[1]由Java编译器[javac.exe]将Java源代码文件编译为字节码文件;
[2]由JVM通过类加载器[ClassLoader]将字节码文件转载进JVM内存中;
[3]由Java解释器逐行解释字节码文件并执行。
上述过程大致解释了一个对象的创建过程,即:
Java程序在执行过程中遇到new关键字,首先会去检查new关键字之后[首次被使用]的className指向的类A是否具有父类,
- 若有,会先由JVM将A的父类通过类加载器将父类装载到JVM内存中,并通过"super();"优先创建A的父类的实例,将其存储到JVM内存堆区;
- 若无,会直接去创建java.lang.Object根父类的实例。
- 然后才会去装载类A对应的字节码文件,创建子类的实例[实例创建之后,已经完成了成员属性的默认初始化操作],并将其存储到JVM内存堆区,通过类A的构造器为子类实例进行属性赋值操作;
- 最后将A类对象的JVM堆区的内存地址返回给栈中的引用变量进行保存;
- 程序员即可通过这个栈中的引用对象来调用A类对象的成员方法、间接访问A类对象的特有属性等操作。
1.4.4 Part-4:对象内存分析
图示如下,
2 类与对象举例
2.1 Person类定义
package com.msb.oop;
import java.io.Serializable;
/**
* @Auther: xiwd
* @Date: 2021/12/11 - 12 - 11 - 15:57
* @Description: com.msb.oop
* @version: 1.0
*/
public class Person implements Serializable {
private static final long serialVersionUID = 2642102877515064840L;
//properties-[static features-名词]
String name;
int age;
//methods-[dynamic features-动词]
//setter
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
if (age<0)
return;
this.age = age;
}
//getter
public String getName() {
return name;
}
public int getAge() {
return age;
}
/**
* constructor without params-[无参构造器]
*/
public Person(){
this(null,0);
}
/**
* constructors with params-[有参构造器]
* @param name the object's name
* @param age the object's age
*/
public Person(String name,int age){
this.name=name;
this.age=age;
}
/**
* get the specific object's information
* @return String type-the content of information
*/
public String introduce(){
return "[name:"+this.name+",age:"+this.age+"]";
}
/**
* eat food with a specific name
* @param food food's name
*/
public void eat(Food food){
System.out.println(this.name+" eat "+food.getName());
}
}
2.2 Food类定义
package com.msb.oop;
/**
* @Auther: xiwd
* @Date: 2021/12/11 - 12 - 11 - 16:12
* @Description: com.msb.oop
* @version: 1.0
*/
public class Food {
//properties
private String name;
public byte aByte;
public int anInt;
public short aShort;
public long aLong;
public float aFloat;
public double aDouble;
public char aChar;
public boolean aBoolean;
public String string;
//setter
public void setName(String name) {
this.name = name;
}
//getter
public String getName() {
return name;
}
//methods
public Food(){
this(null);
}
public Food(String name){
super();
this.name=name;
}
}
2.3 main方法测试
package com.msb.oop.test;
import com.msb.oop.Food;
import com.msb.oop.Person;
/**
* @Auther: xiwd
* @Date: 2021/12/11 - 12 - 11 - 16:16
* @Description: com.msb.oop
* @version: 1.0
*/
public class Main_OOP {
public static void main(String[] args) {
Person person=new Person("ZhangSan",12);
Food food=new Food("Apple");
System.out.println(person.introduce());
person.setAge(0);
System.out.println(person.introduce());
person.eat(food);
System.out.println(food.aByte);//0
System.out.println(food.anInt);//0
System.out.println(food.aShort);//0
System.out.println(food.aLong);//0
System.out.println(food.aFloat);//0.0
System.out.println(food.aDouble);//0.0
System.out.println(food.aChar=='\u0000');//true
System.out.println(food.aBoolean);//false
System.out.println(food.string);//null
}
}