Java - 面向对象从基础到高级之基础
面向对象基础
一、面向对象思想
1.概述:
面向对象是相对于面向过程来讲的,指的是把相关的数据和方法组织为一个整体来看待,从更高的层次来进行系统建模,更贴近事务的自然运行模式。
面向对象到面向过程,是程序员思想上从执行者到指挥者的转变。
2.举个例子:
当我们独自生活时,我们经常纠结一日三餐怎么吃。
面向过程:每天自己完成买菜 - 做饭 - 吃饭 - 洗碗的过程。
面向对象:招聘一个保姆,每天等吃即可。
假设你是一个富豪,拥有一座占地3000亩地的庄园,不再是只关注吃饭问题,还有花草树木修剪,泳池维护清洗,卫生打扫,洗衣做饭等。
面向过程:全都自己完成。
面向对象:招聘一个管家,然后让管家招聘园丁、泳池维护工、保姆等。
结论:面向过程需要关注很繁琐的过程,而面向对象不用关注具体的细节,更关注的是统筹架构的问题。
3.三大思想:
面向对象思想从概念上讲分为以下三种:OOA、OOD、OOP
OOA:面向对象分析(Object Oriented Analysis)
OOD:面向对象设计(Object Oriented Design)
OOP:面向对象程序(Object Oriented Programming
4.三大特征:
封装性:所有的内容对外部不可见
继承性:将其他的功能继承下来继续发展
多态性:方法的重载本身就是一个多态性的体现
二、类与对象
1.两者的关系:
类表示一个共性的产物,是一个综合的特征,而对象,是一个个性的产物,是一个个体的特征,类似生活中的图纸与实物的概念。
类必须通过对象才可以使用,对象的所有操作都在类中定义,类由属性和方法组成。
类必须编写在.java文件中,一个.java文件中可以存在N个类,但是只能存在一个public修饰的类,.java文件的文件名称必须与public修饰的类名完全一致,同一个包中不能存在相同名称的类。
2.类的定义格式:
class 类名 {
成员属性;
成员方法;
}
3.属性与方法:
属性定义格式:数据类型 属性名;
属性定义并赋值的格式:数据类型 属性名 = 初始化值;
方法定义格式:
权限修饰符 返回值类型 方法名(形式参数列表) {
//方法体
return 返回值;
}
4.创建对象及使用:
类名 对象名 = new 类名();
访问类中的属性:对象.属性;
访问类中的方法:对象.方法(实际参数列表);
Person p = new Person();
//给对象属性赋值:
//格式:对象名.属性名 = 值;
p.name = "张三";
p.age = 18;
p.sex = '男';
p.say();
int s = p.sum(100,200);
System.out.println(s);
5.定义一个类:
class Person {
//属性 - 特征
String name;
int age;
char sex;
//方法 - 行为
/**
定义格式:
返回值类型 方法的名称 (形式参数列表) {
方法体
return 返回值;
}
调用格式:
对象名.方法名称 (实际参数列表) ;
*/
void say() {
system.out.println("自我介绍:我是"+name+",我的年龄:"+age+",我的性别:"+sex);
}
int sum(int x,int y) {
int z = x+y;
return z;
}
/*
void xxx() {
if(true) {
return;//表示结束方法
}
System.out.println("哈哈");
}
*/
}
三、创建对象内存分析
1.栈内存:
先进后出,可以理解为一个杯子,往杯子里放糖,最先放进去的糖堆在了最底下,当取出来时,最先放进去的最后被取出来。
Java栈的区域很小,大概2m左右,特点是存取的速度特别快。
存储速度快的原因是栈内存通过栈指针来创建空间与释放空间,当指针向下移动时会创建新的内存,当指针向上移动时会释放这些内存。这种方式速度特别快,仅次于PC寄存器,但是这种移动的方式,必须要明确移动的大小与范围。明确大小与范围是为了方便指针的移动,这是一个对于数据存储的限制,存储的数据大小是固定的,影响了程序的灵活性,所以更大部分的数据一般存储在堆内存中。
2.堆内存:
堆存放的是类的对象,堆内存中内存的释放是由GC(垃圾回收器)完成的,垃圾回收器回收堆内存的规则:当栈内存中不存在此对象的引用时,则视其为垃圾,等待垃圾回收器回收。
堆内存与栈内存不同,优点在于我们创建对象时,不必关注堆内存中需要开辟多少存储空间,也不需要关注内存占用时长。
3.关于栈和堆:
可以认为栈里面存放是对象的名称和基本数据类型的值,栈内存中存储的是地址,指向堆内存。
例如:
Book b1 = new Book();
相当于在栈内存中存储了一个b1,b1会存储在栈的底部,其默认值为null,而等号右边通过new Book()创建对象在堆内存中开辟了空间,创建了一块内存,这个内存的类型叫做Book,而内存都是有地址的,假设这段内存地址是0x1234,这段内存地址最终赋值给了b1(栈内存中),也就是说栈内存中存放了地址,而这个地址指向了堆内存,通过这种方式操作对象里存储的数据(地址)。
再例如:
Book b2 = b1;
(接上例)相当于在栈内存中又储存了一个b2,b2会储存在b1的上方,其默认值为null,而等号右边相当于把b1的内容赋值给了b2,也就是说把b1的地址0x1234赋值给了b2,使得b2的地址也为0x1234,这样一来当我们改变b2的属性时,栈内存中b2的地址指向了堆内存,从而改变了堆内存中该地址储存的数据,最终的效果就是b1的属性也同样会发生改变,因为b1和b2是同一个地址。所以,要注意,此操作并不是赋值,通过此操作后b2和b1成为了同一个对象,他们的地址相同,改变任意一个对象的属性另外一个对象的属性也会跟着变化。
4.方法区:
存放的是:类信息、静态的变量、常量、成员方法。
方法区中包含了一个特殊的区域(常量池)(存储的是使用static修饰的成员)
四、构造方法
1.作用:
用于对象初始化。
2.执行时机:
在创建对象时,自动调用。
3.特点:
所有的Java类中都会至少存在一个构造方法,如果一个类中没有明确的编写构造方法,则编译器会自动生成一个无参的构造方法,构造方法中没有任何的代码。
如果自行编写了任意一个构造器,则编译器不会再自动生成无参的构造方法。
4.定义的格式:
与普通方法基本相同,区别在于:构造方法名称必须与类名相同,没有返回值类型的声明。
Person2() {//无参的构造方法
System.out.println("构造方法执行了");
}
Person2(String n) {//有参的构造方法
}
5.构造方法设计:
建议自定义无参构造方法,不要对编译器形成依赖,避免错误发生。
当类中有非常量成员变量时,建议提供两个版本的构造方法,一个是无参构造方法,一个是全属性做参数的构造方法。
当类中所有成员变量都是常量或者没有成员变量时,建议不提供任何版本的构造。
6.进阶补充:
在一个构造方法中,调用另一个构造方法时,调用的代码必须编写在构造方法的第一行。
eclipse中使用Shift + Alt + s快捷创建构造方法、set、get。
五、方法的重载
一个类中定义的方法和构造方法,是允许重载的:
1.方法的重载要求方法的名称相同(构造方法原本就是相同的)
2.参数列表长度 或 参数列表的类型 或 参数类型顺序不同
注意:与返回值类型无关!
方法的重载,可以让我们在不同的需求下,通过传递不同的参数调用方法来完成具体的功能。
构造方法的重载,可以让我们在不同的创建对象的需求下,调用不同的方法来完成对象的初始化。
六、匿名对象
没有对象名称的对象就是匿名对象。
匿名对象只能使用一次,因为没有任何的对象引用,所以将称为垃圾,等待被GC回收。
只使用一次的对象可以通过匿名对象的方式完成,这一点在以后的开发中将经常使用到。
上一篇: ps制作超炫的明火爆炸特效