一、面向对象
1、什么是对象
万事万物皆对象,对象是具体的;
认识一个对象往往从两个方面进行:一是对象具有什么状态,二是对象具有什么行为。对象的状态即对象本身的固有属性,对象的行为即对象具有的功能。
2、什么是类
类是具有相同的状态和行为的一组对象的集合。
3、如何理解面向对象
毫不夸张夸张的说,面向对象是程序开发人员认识、理解世界的世界观、方法论;
面向对象的基本哲学是,世界是由各种各样具有自己的内部状态(属性)和运动规律(行为)的对象所组成的;不同对象之间的相互作用和通讯构成了完整的现实世界;
从方法论的角度认为,在描述世界的过程中,使用的模型或系统的结构应该直接与现实世界的结构相对应,应该围绕现实世界中的对象来构造模型或系统,通过对象的相互作用来反映世界的运行过程。这样建立起来的系统才是符合现实世界的本来面目的。
面向对象的思想已经涉及到软件开发的各个方面,如:面向对象分析(OOA: Object Oriented Analysis),面向对象设计(OOD: Object Oriented Desigen)以及面向对象编程(OOP:Object Oriented Programming)。
4、面向对象程序设计
面向对象程序设计(OOP: Object Oriented Programming):是一种基于面向对象思维的计算机软件设计方法,是目前最主流的软件开发方法。
面向对象程序设计是指:在设计一个软件系统时,尽可能运用人类的自然思维方式,将问题域中的事物抽象的表示为系统中的对象,作为系统的基本构成单位,使系统直接的映射问题域,保持问题域中事物及相互关系的本来面貌。
二、Java中的类和对象
Java是一种纯面向对象语言,每个程序至少包含一个类,所有数据(属性)和操作(行为)都封装到类中。
1、声明类
Java中使用class
来声明类,具体语法格式如下:
class 类名{
// 成员变量声明部分,即属性;
// 成员方法生命部分,即行为;
}
说明:
-
类声明在Java源文件中(扩展名为.java的文本文件),一个源文件中只能声明一个公开的类(用public关键词修饰的类),源文件名必须与该类名相同。同时,一个源文件中也可以声明多个非公开类。
-
类的声明包括类首和类主体两部分:类首确定类名,其中
class
是声明类的关键字,类名需符合标识符的命名规范,并约定所有单词首字母大写,一般为一个名词或名词性短语;类主体声明类有哪些属性及声明类有哪些行为,属性
用成员变量来体现;行为
用成员方法来体现。 -
声明成员变量的语法就是申明变量的语法,只不过成员变量声明在类主体内,不在方法中。方法中申明的变量称之为局部变量。
-
声明成员方法时,成员方法名需符合标识符的命名规范,并约定首字母小写,其余单词首字母大写,一般为一个动词或动宾短语。
-
声明类,也就是创建了一种新的引用数据类型。
-
仔细观察下面的示例
public class Student {
// 声明成员变量
String name; // 姓名
int age; // 年龄
String studentNo; // 学号
// 声明成员方法
/**
* 自我介绍的方法
*/
void introduce(){
System.out.printf("大家好,我是 %s ,我今年 %d 岁了,我的学号是:%s;", name, age, studentNo);
}
}
2、创建对象
被声明过的类可以用来创建对象,所谓的创建对象
就是声明变量并初始化的过程;
- 观察一个实例:
public class Test {
public static void main(String[] args) {
// 声明一个Student类型的对象
Student stu1;
// 初始化
stu1 = new Student();
// 或者两者写在一起
Student stu2 = new Student();
}
}
- 说明:
- 使用
new
运算符创建对象,实质就是为对象在内存中分配内存空间; new Student()
会创建一个Student
类的对象,这个过程也叫做实例化一个Student
类的对象;- 一个类可以实例化多个对象,不同对象在内存中是独立存在的。
- 使用
3、使用对象
对象被创建后,这个对象就具有了所属类的属性和方法,对象可以使用 .
运算符来访问属性(调用成员变量)或执行行为(调用成员方法)。
- 观察一个示例:
public class Test02 {
public static void main(String[] args) {
Student stu1 = new Student();
// 向对象的属性赋值
stu1.name = "林冲";
stu1.age = 21;
stu1.studentNo = "14728369";
// 调用对象的方法
stu1.introduce();
}
}
4、对象的内存分配
上面代码在运行时,内存中是如何变化的呢,请看下图:
说明:
- 执行代码
Student stu
时,在main方法对应栈帧的局部变量表中,为Student类型的变量stu分配一块内存。 - 执行
stu = new Student()
时,首先,new操作符会让JVM在堆内存中分配一块内存空间(最主要的就是为属性分配内存空间),用来存储一个Student类型的对象,之后,赋值操作会将堆内存中已经分配好的内存空间的首地址存储到变量stu在局部变量表里对应的位置。 - 堆内存中为刚才创建的
Student
对象的name属性
,age属性
,studentNo属性
赋值,即向这些变量对应的内存中存入值,基本数据类型存具体数据,引用类型存内存地址编号。
注意
- 实例化一个Student对象时,该对象的属性是具有初始值(默认值)的,
byte、short、int、long
类型的属性的初始值是0
,float、double
类型的属性的初始值是0.0
,boolean
类型的属性的初始值是false
,char
类型的属性的初始值是'\u0000'
,引用类型的属性的初始值是null
。 - 观察下面的示例:
public class Test03 {
public static void main(String[] args) {
Student student = new Student();
student.introduce();
}
}
-
结果显示为:
大家好,我是null, 我今年0岁了,我的学号是:null;
5、空指针null
- 观察下面的示例:
public class Test04 {
public static void main(String[] args) {
Student student = new Student();
student = null;
student.introduce();
}
-
运行结果为:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.husung.test01.Student.introduce()" because "student" is null at com.husung.test01.Test04.main(Test04.java:7)
造成这个异常的原因就在于student = null;
,将变量赋值为null;
应用类型的变量应该存储一个内存地址编号,而null
值则表明没有引用任何内存地址编号,是一个空引用。当变量的值是null时 ,访问属性或调用方法,将会抛出NullPointerException
。
三、包
在复杂的文件系统中,文件分门类别存储在不同文件夹中,便于组织管理及查找,同时也避免了文件重名问题。在程序设计过程中,一个系统工程需要编写几百个甚至上千个文件,可能有很多开发人员共同协作完成,也存在组织管理类文件和避免类文件同名等问题。Java中使用包来解决,Java的类文件存储在不同的包中。
1、将类组织在包中
在每一个类文件最前面,使用关键字package
说明该类文件的类组织在那个包中。
- 观察下面的一个示例:
package com.husung.test01;
public class Student {
String name;
int age;
String studentNo;
void introduce() {
System.out.printf("大家好,我是%s, 我今年%d岁了,我的学号是:%s", name, age
, studentNo);
}
}
说明:
- 使用了
package
语句说明了类Student
在包com.husung.test01
中,项目中应该有对应的包路径结构,同时,包名会在磁盘上生成对应的文件目录。如下:
- 一个类文件中只能有一条
package
语句,且位于类文件最上面(忽略注释)。 - 同一个包中类名不可以相同,不同包中类名可以相同。
- 类所属的包名.类名称之为类的完全限定名,如例子中Student类的完全限定名为
com.husung.test01.Student
。 - 通常,每个公司开发的软件系统中,开头的包名都是该公司的域名倒置。
2、常见的Java系统包
JDK中已经为开发者提供了许多声明好的类,称为类库,位于JDK安装目录下的\lib
目录中,开发者可以直接使用。同时,JDK中将这些类按相关的功能都组织在一个个不同的包中,这些包常被称作系统包,常见的系统包有:
系统包 | 说明 |
---|---|
java.lang | Java语言的核心类,如String 、 Math 、 System 等 |
java.util | 大量的工具类,如Scanner 、Random |
java.net | Java网络相关的工具类 |
java.io | Java输入/输出操作的相关类 |
java.text | 一些Java格式化的相关类 |
java.sql | Java对数据库操作的相关类 |
java.awt 和 java.swing | Java下图形界面程序开发的相关类 |
3、导入其他包中的相关类
程序开发过程中,经常需要在一个类中使用另外一个包中的类,此时就需要导入其他包中的类。通常有两种方法,一是使用import语句,另一种是使用类的完全限定名。
3.1、使用import语句
package com.husung.test02;
import com.husung.test01.Student;
public class Test05 {
public static void main(String[] args) {
Student student = new Student();
}
}
说明:
import
语句在package
语句下,类声明上方,一个类文件中可以包含任意数量的import
语句。一个类文件中导入某个类后,该类文件中的声明的所有类中均可以使用被导入的类。- 可以使用
*
来导入某个包中的多个类,比如将java.util包下的所有类都导入进来,可以使用import java.util.*;
。 - 同包中的类在使用时无需显式导入;
java.lang
包中的类在使用时无需显式导入。
3.2、使用类的完全限定名
- 观察下面的示例:
package com.husung.test02;
public class Test06 {
public static void main(String[] args) {
com.husung.test01.Student student = new com.husung.test01.Student();
}
}