1. 面向对象的概念
1.1 理解面向对象
l 面向对象是相对面向过程而言
l 面向对象和面向过程都是一种思想
l 面向过程
强调的是功能行为
l 面向对象
将功能封装进对象,强调具备了功能的对象。
l 面向对象是基于面向过程的。
1.2 面向对象的特点
l 是一种符合人们思考习惯的思想
l 可以将复杂的事情简单化
l 将程序员从执行者转换成了指挥者
l 完成需求时:
先要去找具有所需的功能的对象来用。
如果该对象不存在,那么创建一个具有所需功能的对象。
这样简化开发并提高复用。
1.3 面向对象的开发、设计、特征
l 开发的过程:其实就是不断的创建对象,使用对象,指挥对象做事情。开发的时候,找对象,没有对象,就创建一个对象。
l 设计的过程:其实就是在管理和维护对象之间的关系。
l 面向对象的特征:
封装(encapsulation)
继承(inheritance)
多态(polymorphism)
2. 类与对象的关系
类:对现实生活中事物的描述,抽取对象中的共性内容,是对具体的抽象。
对象:就是这类事物实实在在的存在个体。对象有三个主要特性:对象的行为,对象的状态,对象的标识。
2.1 类与对象
类(class)是构造对象的模板或蓝图。由类构造对象的过程称为创建类的实例。具体对象就是对应Java在堆内存中建立的实体。
2.2 类的定义
其实定义类就是在描述事物,就是在定义属性和行为,属性和行为共同为类中成员(成员变量和方法)。
2.3 成员变量与局部变量
成员变量:
成员变量定义在类中,在整个类中都可以被访问。
成员变量随着对象的建立而建立,存在于对象所在的堆内存中。
成员变量有默认初始化值。
局部变量:
局部变量只定义在局部范围内,如:函数内,语句内等。
局部变量存在于栈内存中。
作用的范围结束,变量空间会自动释放。
局部变量没有默认初始化值。我们要对其进行初始化才可以参与运算。
2.4 匿名对象
匿名对象是对象的简化形式。
匿名对象两种使用情况
当对对象方法仅进行一次调用的时,
匿名对象可以作为实际参数进行传递
3. 封装
封装(encapsulation)有时候也称为数据隐藏。是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
好处:
Ø 将变化隔离。
Ø 便于使用。
Ø 提高重用性。
Ø 提高安全性。
封装原则:
将不需要对外提供的内容都隐藏起来。
把属性都隐藏,提供公共方法对其访问。
实现封装的关键在于绝对不能让类中的方法直接地访问其他类的成员变量。程序仅通过对象的方法与对象数据进行交互。封装给对象赋予了“黑盒”特征。这是提高代码复用性和安全性的关键。
private关键字
Ø 是一个权限修饰符。
Ø 用于修饰成员(成员变量和成员函数)
Ø 被私有化的成员只在本类中有效。
常用方法之一:
将成员变量私有化,对外提供对应的set,get方法对其进行访问。提高对数据访问的安全性。使赋值过程变得可控。set称为更改器方法,get称为访问器方法。
注意:私有仅仅是封装的一种表现形式。之所以对外提供访问方式就因为可以在访问方式中加入逻辑判断等语句。对访问的数据进行操作,提高代码的健壮性。
4. 构造函数
特点:
Ø 函数名与类名相同
Ø 不用定义返回值类型
Ø 没有具体的返回值。
作用:
给对象进行初始化。
注意:
默认构造函数的特点。
多个构造函数是以重载的形式存在的。
*构造函数小细节:当一个类中没有定义构造函数时,那么系统会默认给该类加入一个空参数的构造函数。
Q:什么时候定义构造函数呢?
A:分析事物时,该事物存在具备一些特性或行为,那么将这些内容定义在构造函数中。
Q:构造函数和一般原函数有什么不同?
A:写法上不同。运行上也有所不同。构造函数是一建立就运行,给对象初始化。而一般方法是对象调用才执行,给是对象添加对象具备的功能。
一个对象建立构造函数只能运行一次。而一般方法可以被对象调用多次。
构造代码块
作用:给对象进行初始化,对象一建立就运行,而且,优先于构造函数执行。
给所有的对象统一初始化(共性内容),构造函数时给对应对象初始化。
5. this关键字
特点:this代表其所在函数所属对象的引用。
换言之:this代本类对象的引用。
简单地说,就是哪个对象在调用this所在的函数,this就代表哪个对象
Q:什么时候使用this关键字呢?
A:
当在函数内需要用到调用该函数的对象时,就用this。
在构造函数间调用,只能用this语句,传相应的参数,this只能在构造函数的第一个语句,因为初始化要先执行。
Q:this能够解决什么问题?
A:this代表对象(本类对象)
6. static关键字
静态:这是一个修饰符,只用于修饰成员(成员变量和成员函数)。当成员被static修饰后就多了一种调用方式,可以同时用对象调用,用类名调用。
class CodePiece {
public static void main(String[] args) {
Info info = new Info();
String c = info.country;//对象调用
String cc = Info.country; //类名调用
System.out.println(c + "::" +cc);//China::China
}
}
class Info{
static String country ="China";
Info(){}
}
Q:实例变量与类变量的区别?
1. 存放位置
类变量随着类的加载存在于方法区中,实例变量随着对象的建立存在于堆内存中。
2. 生命周期
类变量的生命周期随着类的消失而消失。
实例变量随着对象的消失而消失。
Q:static的特点?
1. 随着类的加载而加载
2. 优先于对象存在(对象还没有创建的时候他就已经存在了)
3. 被所有对象共享
4. 可以被类名调用
Q:static的使用有什么注意事项?
1. static方法只能访问static成员。
非static方法既可以访问static成员也可以访问非static成员。
2. 静态方法中不可以定义super,this关键字,因为static优先于对象存在。
Q:静态的利弊分析
好处:
1. 对对象的共享数据进行单独的空间存储,节省空间
2. 可以直接被类名调用
弊端:
1. 生命周期过长
2. 访问出现局限性,只能访问static成员
Q:关于main函数的一些问题
main函数是一个特殊的函数,作为程序的入口,可以被虚拟机识别调用。
public:代表该函数访问权限是最大的。
static:代表主函数随着类的加载就已经存在了。
void:代表主函数没有具体返回值。
main:要注意,main不是关键字,是一个特殊单词,可以被虚拟机识别。
String[] args:函数参数,一个字符串类型的数组
在一个类中,可以写多个参数列表不同的main参数进行重载,编译不会出问题,但是,JVM只认识这个固定格式的那个main函数。
Q:什么时候用静态?
要从两方面下手:成员变量和成员函数
成员变量 | 成员函数 |
当对象中出现共享数据时,该数据被静态所修饰,对象中的特有数据要定义成非静态存在于堆内存中 | 当功能内部没有访问到非静态数据时 |
Q:静态代码块的使用
static {
//执行语句
}
特点:随着类的加载而执行(用到类中的内容才加载类进内存,如果只是建立一个引用则不加载,例如Person p = null),只执行一次,优先于主函数执行,优先于构造代码块,用于给类进行初始化。
静态代码块 static{} | 给类初始化 | 不能有this,因为优先于对象存在 |
构造代码块 {} | 给类对象初始化 | 能有this |
构造器 类名(){} | 给特定的类对象初始化 | 能有this |
Q:对象的初始化过程(重要)
1. 类加载进内存
2. 静态代码块执行
3. 堆中开辟空间,分配地址
4. 对象具备属性,进行默认初始化
5. 显式初始化
6. 构造代码块初始化
7. 对对象进行与之对应的构造函数初始化
8. 将内存地址赋给在栈中的变量。
7. 类的设计技巧
(1)一定要保证数据私有。这是最重要的;绝对不要破坏封装性。
(2)一定要对数据初始化。Java不对局部变量进行初始化,但是会对成员变量默认初始化。最好不要依赖于系统的默认值,而是应该显式地初始化所有的数据,可以提供默认值,也可以在所有构造器中设置默认值。
(3)不要在类中使用过多的基本类型。用其他的类代替多个相关的基本类型的使用。这样可以增加阅读性和代码复用性。
(4)不是所有的成员变量都需要独立的访问器和更改器。
(5)将职责过多的类进行分解。
(6)类名和方法名要能够体现他们的职责。