java入门 -- 类与对象及内存解析

1 如何理解面向对象

1. 面向过程(POP)与面向对象(OOP)

▪ 面向过程(Procedure Oriented)和面向对象(Object Oriented,OO)都是对软件分析、设计和开发的一种思想,它指导着人们以不同的方式去分析、设计和开发软件。早期先有面向过程思想,随着软件规模的扩大,问题复杂性的提高,面向过程的弊端越来越明显的显示出来,出现了面向对象思想并成为目前主流的方式。两者都贯穿于软件分析、设计和开发各个阶段,对应面向对象就分别称为面向对象分析(OOA)、面向对象设计(OOD)和面向对象编程(OOP)。C语言是一种典型的面向过程语言,Java是一种典型的面向对象语言。

2. 如何去理解面向对象

▪ 面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

例子:是如何将大象装进冰箱

面向过程:
▪ 总共分三个过程,第一个过程:冰箱门打开(关着门的冰箱) 返回值是打开门的冰箱
▪ 第二个过程:大象装进去(打开门的冰箱) 返回值是打开着门,装着大象的冰箱
▪ 第三个过程:冰箱门关上(打开着门,装着大象的冰箱) 返回值关着门的装着大象的冰箱

在这里插入图片描述

▪ 面向对象:
总共分三个动作,(每个动作都有一个对象去执行)
第一个动作:冰箱.开门()
第二个动作:冰箱.装进(大象)
第三个动作:冰箱.关门()
或者是链式调用冰箱.开门().装进(大象).关门()

在这里插入图片描述

思路:

▪ 根据问题需要,选择问题所针对的现实世界中的实体。
▪ 从实体中寻找解决问题相关的属性和功能,这些属性和功能就形成了概念世界中的类。
▪ 把抽象的实体用计算机语言进行描述,形成计算机世界中类的定义。即借助某种程度上的语言,把类构造成计算机能够识别和处理的数据结构。
▪ 将类实例化成计算机世界中的对象。对象是计算机世界中解决问题的最终工具。

2 类与对象

▪ 类是对一类事物的描述,用于描述现实事物的,它将现实事物进行抽象化,模板化描述。
▪ 对象是对象是实际存在的该类事物的每个个体。

2.1 类的成员构成

▪ 在java中可以简单理解为,class 修饰类,就是说class后面跟一个类名 ,类里面有他的属性和方法。
▪ 注意一个class 里面的属性和方法必须在一对{ } 中 ,一个方法的所有内容也都要在一对{ } 中。

成员变量(属性)和局部变量的区别?在这里插入图片描述
成员变量(属性)和局部变量的区别?

项目成员变量局部变量
声明的位置直接声明在类中方法形参或内部、代码块内、构造器内等
修饰符private、public、static、final等不能用权限修饰符修饰,可以用final修饰
初始化值有默认初始化值没有默认初始化值,必须显式赋值,方可使用
内存加载位置堆空间 或 静态域内栈空间

2.2 对象的产生

▪ 简单理解就是每new一个就产生了一个相应的对象。

Person p1 = new Person();

2.3 匿名对象

▪ 匿名就是没有名字的对象,在创建对象时,只通过new的动作在堆内存开辟空间,却没有把堆内存空间的地址值赋值给栈内存的某个变量用以存储。
▪ 如果对一个对象只需要进行一次方法调用,那么就可以使用匿名对象。
▪ 我们经常将匿名对象作为实参传递给一个方法调用。
▪ 由于我们没有记录堆内存对象的地址值,所以只能用一次,再次使用就找不到了。

new Person().shout();

2.3 对象的使用

Person p1 = new Person();
Person p2 =new Person();
p1.age = 35;  //访问p1的属性
p1.shout();//访问p1的方法
p2.shout();//访问p2的方法

举例说明:

public class Home33 {

 public static void main(String[] args) {
 	// TODO Auto-generated method stub
Scanner sc =new Scanner(System.in);
System.out.println("输入字符串");
  String s=sc.nextLine();
  int upperLetterCount=0;;
 for(int strIndex = 0;strIndex < s.length();strIndex++)
 		if(s.charAt(strIndex) >= 65 && s.charAt(strIndex) <= 90)
 			upperLetterCount++;
 	System.out.printf("The number of uppercase letters is %d", upperLetterCount);
 	
 	sc.close();

 }

}

▪ 其中Scanner sc =new Scanner(System.in);和String s=sc.nextLine();都可以认为是创建了一个对象。
▪ 通过对象可以去调用相应类里面的属性和方法,不用再去利用类名去调用。

3 类的属性与方法

3.1 属性

▪ 语法格式:
修饰符 数据类型 属性名 = 初始化值 ;
▪ 说明1: 修饰符
▪ 常用的权限修饰符有:private、缺省、protected、public
▪ 其他修饰符:static、final (暂不考虑)
▪ 说明2:数据类型
▪ 任何基本数据类型(如int、Boolean) 或 任何引用数据类型。
▪ 说明3:属性名
▪ 属于标识符,符合命名规则和规范即可。

举例:

public class Person{
private int age; //声明private变量 age
public String name = “Lila”; //声明public变量 name
}

3.2 方法

方法也就是函数之前有提到过

▪ 方法通过方法名被调用,且只有被调用才会执行。
▪ 方法被调用一次,就会执行一次。
▪ 没有具体返回值的情况,返回值类型用关键字void表示,那么方法体中可以不必使用return语句。如果使用,仅用来结束方法。
▪ 定义方法时,方法的结果应该返回给调用者,交由调用者处理。
▪ 方法中只能调用方法或属性,不可以在方法内部定义方法。

举例:

public class Stack {

 // 栈中的所有数据
 	public int[] data = new int[10];
 	public int top = 0;
 	public int capacity = 10;
 	
 	public Stack() {
 	}

 	public Stack(int capacity) {
 		this.capacity = capacity;
 	}
 	
 	public void push(int e) {
 		if (capacity == top) {
 			// 扩容
 			data =Arrays.copyOf(data,3);
 			System.out.println("扩容");
 		} else {
 			data[top++] = e;
 		}
 	}
 	
 	

 	public int pop() {
 		if (!isEmpty()) {
 			return data[--top];
 		}
 		return -1;
 	}
 	
 	public int peek() {
 		if (!isEmpty()) {
 			return data[top - 1];
 		}
 		return -1;
 	}

 	public boolean isEmpty() {
 		if (top == 0) {
 			return true;
 		}
 		return false;
 	}
 	
 	public void clear() {
 		top = 0;
 	}
 	
 	public int size() {
 		return top;
 	}
 	
 	public String toString() {
 		String str = "";
 		for (int i : data) {
 			str += i + ", ";
 		}
 		return "["+ str +"]";
 	}
}
Stack stack = new Stack();
		
		stack.push(123);
		stack.push(456);
		stack.push(789);
		stack.push(100);
		System.out.println(stack);

在这里插入图片描述
具体的面向对象问题会在面向对象三大特征中提到。

4. 内存解析以及参数传递

java的具体内存解析会在jvm中着重介绍,这里只为简单理解。
在这里插入图片描述
首先了解几个概念

▪ 堆(Heap),此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在Java虚拟机规范中的描述是:所有的实例以及数组都要在堆上分配。
▪ 栈(Stack),是指虚拟机栈。虚拟机栈用于存储局部变量等。局部变量表存放了编译期可知长度的各种基本数据类型(boolean、byte、char 、 short 、 int 、 float 、 long 、
double)、对象引用(reference类型,它不等同于对象本身,是对象在堆内存的首地址)。 方法执行完,自动释放。
▪ 方法区(Method Area),用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

对象的产生:

public static void main(String[] args) {
Person p1 = new Person();
Person p2 =new Person();
p1.age = 35;  //访问p1的属性
p1.shout();//访问p1的方法
p2.shout();//访问p2的方法
}
public class Person{
private int age; //声明private变量 age
public String name = “Lila”; //声明public变量 name
void shout(){
System.out.println(“oh,my god! I am ” + age);
}
}

在栈中声名一个地址然后指向对空间进行对象的产生。
在这里插入图片描述
new一个对象就会在栈空间中产生一个相应的地址,开辟一个堆空间,然后指向对应的对象。
在这里插入图片描述
对象的生命周期
在这里插入图片描述
对象的内存解析

Person p1 = new Person();
p1.name = "Tom";
p1.isMale = true;
Person p2 = new Person();
sysout(p2.name);//null
Person p3 = p1;
p3.age = 10;

在这里插入图片描述
成员变量vs局部变量的内存位置

class Person{//人类
//1.属性
String name;//姓名
int age = 1;//年龄
boolean isMale;//是否是男性
public void show(String nation){
//nation:局部变量
String color;//color:局部变量
color = "yellow";
} }
//测试类
class PersonTest{
public static void main(String[] args){
Person p = new Person();
p.show(“USA”);
} }

在这里插入图片描述
对象数组的内存解析

Student[] stus = new Student[5];
stus[0] = new Student();
sysout(stus[0].state);//1
sysout(stus[1]);//null
sysout(stus[1].number);//异常
stus[1] = new Student();
sysout(stus[1].number);//0

在这里插入图片描述
方法的参数传递

▪ 形参:方法声明时的参数
▪ 实参:方法调用时实际传给形参的参数值

Java的实参值如何传入方法呢?
Java里方法的参数传递方式只有一种:值传递。 即将实际参数值的副本(复制品)传入方法内,而参数本身不受影响。

▪ 形参是基本数据类型:将实参基本数据类型变量的“数据值”传递给形参
▪ 形参是引用数据类型:将实参引用数据类型变量的“地址值”传递给形参

基本数据类型传递
基本数据类型不会影响到其他方法中的参数

public static void main(String[] args) {
int x = 5;
System.out.println("修改之前x = " + x);// 5
// x是实参
change(x);
System.out.println("修改之后x = " + x);// 5
}
public static void change(int x) {
System.out.println("change:修改之前x = " + x);
x = 3;
System.out.println("change:修改之后x = " + x);
}

在这里插入图片描述
在这里插入图片描述
引用数据类型的参数传递

public class asdf {
  public static void main(String[] args) {
  	Person obj = new Person();
  	obj.age = 5;
  	System.out.println("修改之前age = " + obj.age);// 5
  	// x是实参
  	change(obj);
  	System.out.println("修改之后age = " + obj.age);// 3
  	}
  	public static void change(Person obj) {
  	System.out.println("change:修改之前age = " + obj.age);
  	obj.age = 3;
  	System.out.println("change:修改之后age = " + obj.age);
  	}

}
class Person{
  int age; 
  }

结果
在这里插入图片描述
在这里插入图片描述

public static void main(String[] args) {
   	Person obj = new Person();
   	obj.age = 5;
   	System.out.println("修改之前age = " + obj.age);// 5
   	// x是实参
   	change(obj);
   	System.out.println("修改之后age = " + obj.age);// 5
   	}
   	public static void change(Person obj) {
   	obj = new Person();
   	System.out.println("change:修改之前age = " + obj.age);
   	obj.age = 3;
   	System.out.println("change:修改之后age = " + obj.age);
   	}

}
class Person{
   int age; 
   }

结果:
在这里插入图片描述

在这里插入图片描述

注:以上部分图片来自尚硅谷

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值