1 认识面向对象
1.1 初始面向对象和面向过程(了解)
面向过程的开发方式主要的特点:
注重步骤,注重的是实现这个功能的步骤。另外面向过程也注重实现功能的因果关系。
面向过程有什么缺点?
面向过程最主要是每一步与每一步的因果关系,其中A步骤因果关系到B步骤,A和B联合形成一个子模块,子模块和子模块之间又因为因果关系结合在一起,假设其中任何一个因果关系出现问题,此时整个系统的运转都会出现问题。(代码和代码之间的耦合度太高,扩展力太差)
面向过程有什么优点?
对于小型项目,采用面向过程的方式进行开发,效率较高。不需要前期进行对象的提取,模型的建立,可以直接开始写代码,编写因果关系,从而实现功能。
什么是面向对象的开发方式?
采用面向对象的方式进行开发,更符合人类的思维方式。
面向对象就是将现实世界分割成不同的单元,然后每一个单元都是先成对象,然后给一个环境驱动一下,让各个对象之间写作起来形成一个系统。
采用面向对象方式进行开发:耦合度底,扩展力强。
使用面向对象编程思想开发系统,在现代开发中会将面向对象贯穿整个过程,一般包括:OOA/OOD/OOP:
● OOA:面向对象分析(Object-Oriented Analysis)
● OOD:面向对象设计(Object-Oriented Design)
● OOP:面向对象编程(Object-Oriented Programming)
1.2 面向对象三大特征(了解)
封装、继承、多态。(后面详解)
1.3 类和对象的概念(理解)
什么是类?
类实际是在现实世界当中不存在的,是一个抽象的概念。
是一个模板。是我们人类大脑进行思考、总结、抽象的一个结果。
类本质上是现实世界当中某些事物具有共同特征,将这些共同特征提取出来形成的概念就是一个“类”,“类”就是一个模板。
什么是对象?
对象是实际存在的个体。
张三、李四都是对象,都属于人这一类。
类 = 属性 + 方法
属性来源于:状态
方法来源于:动作
1.4 类的定义(掌握)
怎么定义一个类,语法格式是什么?
修饰符列表 class 类名{
//类体 = 属性 + 方法
//属性在代码上以”变量“的形式存在
//方法描述动作/行为
}
为什么属性是以”变量“的形式存在的?
因为属性对应的是”数据“,数据在程序中只能放到变量中。
属性其实就是变量。
2 对象的创建和使用方法
2.1 对象的创建和使用(掌握)
先定义一个Student类:
/**
* @author wcs
* @date 2021/8/5 10:12
*/
//定义一个Student类
public class Student {
//属性 (因为是对象的属性,每个对象都是一个实例,所以是实例变量)
//学号
int id;
//姓名
String name;
//年龄
int age;
//性别
boolean sex;
//住址
String address;
}
创建对象:
/**
* @author wcs
* @date 2021/8/5 10:16
*/
//对象的创建和使用
public class StudentTest {
public static void main(String[] args) {
//类型名 变量名 = new 类名();
Student stu1 = new Student();
Student stu2 = new Student();
...
//stu1、stu2也是局部变量
//访问实例变量
System.out.println(stu1.id);//默认值 0
System.out.println(stu1.name);//默认值 null
System.out.println(stu1.sex);//默认值 false
System.out.println(stu2.id);//默认值 0
System.out.println(stu2.name);//默认值 null
System.out.println(stu2.sex);//默认值 false
}
}
2.2 JVM内存管理(理解)

● java虚拟机栈(重点):
概念:描述的是java方法执行的内存模型。(每个方法在执行的时候会创建一个栈帧,用于存储局部变量表,操作数栈,动态链接,方法出口等信息。每个方法从调用直至完成的过程,就对应一个栈帧从入栈到出栈的过程。)
特点:线程私有,生命周期和线程相同。这个区域会出现两种异常:StackOverflowError异常:若线程请求的深度大于虚拟机所允许的深度。OutOfMemoryError异常:若虚拟机可以动态扩展,如果扩展是无法申请到足够的内存。
● 本地方法栈:
概念:它与虚拟机栈所发挥的作用是相似的,区别是java虚拟机栈为执行java方法服务,而本地方法栈是为本地方法服务。
特点:线程私有,也会抛出两类异常:StackOverflowError和OutOfMemoryError。
● Java堆(重点):
概念:是被所有线程共享的一块区域,在虚拟机启动时创建。
特点:线程共享,存放的是对象实例(所有的对象实例和数组),GC管理的主要区域。可以处于物理上不连续的内存空间。
● 方法区(重点):
概念:存储已被虚拟机加载的类信息、常量、静态变量,即时编译器编译后的代码等数据。
特点:线程共享的区域,抛出异常OutOfMemory异常:当方法区无法满足内存分配需求的时候。
2.3 构造方法(掌握)
2.3.1 构造方法有什么用?
构造方法是一个比较特殊的方法,通过构造方法可以完成对象的创建,以及实例变量的初始化。换句话说,构造方法用来创建对象,并且同时给对象的属性赋值。(注意:实例变量没有手动赋值的时候,系统会赋默认值。)
2.3.2 缺省构造器
当一个类没有提供任何构造方法,系统会默认提供一个无参数的构造方法(这个构造方法被称为缺省构造器)
当一个类中手动提供了构造方法,那么系统将不再提供无参数构造方法。
2.3.3 构造方法怎么调用?
使用new运算符来调用构造方法。
new 构造方法名(形式参数列表);
2.3.4 构造方法的语法特点
修饰符 构造方法名 (形式参数列表){
//构造方法体;
//通常在构造方法体中给属性赋值,完成属性初始化。
}
注意:
修饰符列表不能写出public static,目前统一写成:public。
构造方法名和类名必须一致。
构造方法不需要指定返回值类型,也不能写出void。
无参构造方法和有参构造方法都可以调用。
构造方法支持方法重载,并且在一个类当中构造方法可以有多个,并且所有的构造方法名字都是一样的。
示例:
学生类:
/**
* @author wcs
* @date 2021/8/5 16:07
*/
public class Student {
String name;
int age;
//无参构造
public Student() {
System.out.println("我是无参构造方法");
}
//有参构造
public Student(String stuname) {
name = stuname;
}
public Student(String stuname, int stuage) {
name = stuname;
age = stuage;
}
}
测试类:
/**
* @author wcs
* @date 2021/8/5 16:01
*/
public class ConstructorTest01 {
public static void main(String[] args) {
Student stu1 = new Student();
System.out.println(stu1.name);//默认值null
System.out.println(stu1.age);//默认值0
System.out.println("--------------");
Student stu2 = new Student("小明");
System.out.println(stu2.name);//小明
System.out.println(stu2.age);//0
System.out.println("--------------");
Student stu3 = new Student("小红", 18);
System.out.println(stu3.name);//小红
System.out.println(stu3.age);//18
}
}
运行结果:

2.4 空指针异常(理解)
/**
* @author wcs
* @date 2021/8/5 14:50
*/
public class NullPointerTest {
public static void main(String[] args) {
//创建客户对象
Customer c = new Customer();
//访问客户id
System.out.println(c.id);//默认值为0
//赋值后访问
c.id = 9521;
System.out.println(c.id);//9521
//如果客户c为空
c = null;
System.out.println(c.id);//发生空指针异常(NullPointerException)
}
}
class Customer {
//客户id
int id;
}
当变量c为null时,也就是说变量c中存储的地址为空,本来地址是指向堆内存中的c对象,现在没有地址指向了,所以也就无法访问对象中的id。
堆内存中的c对象没有引用指向它,此时就等待垃圾回收机器回收。GC会将这个垃圾对象释放掉。(Java中的垃圾回收器GC主要针对回收的是堆内存当中的垃圾数据)
2.5 参数传递问题(理解)
/**
* @author wcs
* @date 2021/8/5 15:17
*/
public class Test01 {
public static void main(String[] args) {
int i = 10;
add(i);
System.out.println(i);//10
}
public static void add(int i) {
i++;
System.out.println(i);//11
}
}
以上程序执行顺序是:声明变量i并赋值10,将i变量中的数据10复制一份传给add方法,然后执行add方法,i++,接着输出11,此时add方法执行完毕,出栈,接着执行main方法输出i,i还是最先声明的变量i,所以为10。
/**
* @author wcs
* @date 2021/8/5 15:35
*/
public class Test02 {
public static void main(String[] args) {
Person p = new Person();
p.age = 10;
add(p);
System.out.println(p.age);//11
}
public static void add(Person p) {
p.age++;
System.out.println(p.age);//11
}
}
class Person {
int age;
}
以上代码执行过程:
先给p对象的属性age赋值10,然后把p对象的地址传递到add方法中,p对象属性age++,然后输出age为11,回到main方法中,因为地址一直没变所以指向的一直是p对象,所以p对象的age为11。
Java中关于方法调用时参数传递时实际上只有一个规则:
不管你是基本数据类型还是引用数据类型,实际在传递的时候都是将变量中保存的那个”值“复制一份传过去。