目录
1、对象和类
2、类之间的关系
3、引用
4、对象的创建和使用
5、构造函数/构造方法
6、内存解析
在这篇文章中,我们将学习面向对象的思想,并学习如何使用面向对象思想编程。在学习面向对象编程之前,我们先了解一下编程语言的发展:机器语言,汇编语言,高级语言,面向对象的语言。
机器语言:直接由计算机指令组成,指令,数据,地址,都用0或1的符号串组成,可以由计算机直接执行;
汇编语言:用容易理解和记忆的符号表示指令,数据,寄存器,抽象层次低,程序员不易理解。
高级语言:屏蔽了机器细节,提高了语言的抽象层次,更接近于人类语言。60年代出现的结构化编程语言,提出了结构化数据和语句,数据和过程抽象等概念。
面向对象语言:与以往的语言的不同点是,它的出发点是能更加客观的描述问题域中客观存在的事物。
编程语言朝着人类更能理解的方向发展。
提到面向对象,大家都会想到面向过程开发,那么这两者的区别是什么呢?主要区别在于:
面向过程关注怎么做,做多少事。
面向对象关注谁去做,多少人去做。
面向对象编程,以下概念必须要掌握:
1)对象用于计算机语言中对问题域中事物的描述。对象通过“属性”和“方法”来分别对应事务的静态和动态属性。
2)类是对同一类型事物的抽象,类中定义了这类对象具备的动态和静态属性。
3)类可以看做是一类对象的模板,对象是一个类具体的实现,Instance。
关系 | |
关联 | 最弱的关系,所有的关系都是关联关系 |
聚合 | 整体到部分。又分为聚集,组合。 聚集:雁群和大雁的关系;组合:身体和头的关系 |
继承 | 从一般到特殊。XX is a XX |
多态 | |
实现 |
了解完上述内容后,用面向对象的思想如何分析问题呢?
Java语言中,除基本类型之外的类型都称之为引用类型。Java中的对象通过引用对其操作。
String s; // 1.声明String类型变量s
s = new String("hello world!"); // 2.给s赋值"hello world!"
如以上代码:
执行第1句时,声明String类型的引用变量s;
执行第2句时,通过new语句创建一个String类型的对象,用s指向它,以后通过s完成对这个对象的操作。
从内存的角度看这两步:
执行第1句时,在栈中分配一块空间,保存对象的地址,此时存的地址是null。
执行第2句时,在堆中分配一块空间,保存对象,此时s存的地址是堆内存的地址。
那如何在内存中区分类和对象呢?
类是静态的的概念,每个类只有一份,保存在代码区;
对象是运行过程中new出来的,保存在堆中,类中的成员变量在不同对象中有不同的值(除静态变量),对象在没有引用时会被回收掉。
1)必须使用new创建对象;
2)执行对象.成员变量来引用成员变量;
3)执行对象.方法(实参列表)来引用方法;
4)同一个类的每个对象的成员变量有不同的存储空间;
5)同一个类的每个对象共享该类的方法。
非静态的方法,是针对每个对象调用。
说到对象的创建,必须要说一下对象的构造函数。
1)使用new() + 构造函数的方法创建一个对象;
2)构造函数是定义在Java类的,一个用来初始化对象的成员变量函数;
3)构造函数名和类名相同,没有返回值;
4)没有指定构造函数时,编译器为每个类自动添加一个无参构造函数,如:
类名(){};
Java在函数调用中传递参数时,遵循值传递的原则:基本类型传递数据值本身。引用类型,传递对象的引用,而不是对象本身。
public class MemoryAnalysis {
public static void main(String[] args) {
Point p1 = new Point(1, 1, 1); // 1
Point p2 = new Point(2, 2, 2); // 2
double distance = p2.getDistance(p1); // 3
System.out.println(distance); // 4
p1.setX(5); // 5
System.out.println(p1.getDistance(new Point(3, 3, 3))); // 6
}
}
class Point {
double x, y, z;
Point(double _x, double _y, double _z) {
x = _x;
y = _y;
z = _z;
}
public void setX(double x) {
this.x = x;
}
double getDistance(Point p) {
return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y) + (z - p.z) * (z - p.z);
}
}
Point p1 = new Point(1, 1, 1); // 1
Point p2 = new Point(2, 2, 2); // 2
double distance = p2.getDistance(p1); // 3
第4步执行结束后,栈中变量的空间被释放
System.out.println(distance); // 4
p1.setX(5); // 5
System.out.println(p1.getDistance(new Point(3, 3, 3))); // 6
从图中我们可以看出,在方法传参,参数是引用类型时,在栈中创建一个变量指向参数的引用地址,而不是生成一个新的对象。
方法执行结束后,栈空间的变量全部被释放,堆空间的对象等垃圾回收时被释放
我们在分析的时候,可能会遇到复杂表达式,这时候有个原则:从里到外分析;
形参,实参在栈中都会占用一块空间,方法的返回值也会存在一块临时区域(栈)中,方法执行结束后,临时区域(栈)的空间自动释放;
是指一个类中可以定义方法名相同,参数列表不同的多个方法。在实际使用时根据不同的参数列表选择方法。
普通方式的重载已经老生常谈了,这里我们重点看下构造函数的重载
class Point {
private double x;
private double y;
Point() {}
Point(int x1, int y1) {
this.x = x1;
this.y = y1;
}
public double getX() {return x;}
public double getY() {return y;}
public void setX(double x) {this.x = x;}
public void setY(double y) {this.y = y;}
}
接下来我们举个例子,从内存的角度解析程序执行过程
因为内存解析篇幅较长,我们单独拿出来讲解。请亲爱的读者朋友移步:
[Java基础]面向对象-内存解析_小王师傅66的博客-CSDN博客
所以上面就是面向对象中,关于对象和类,类之间的关系,引用,对象的创建和使用,构造函数,内存解析的全部内容。