想要学习Java的封装、继承和多态,前提我们要了解Java的程序设计思想—面向对象。
面向对象
面向对象的概述
面向对象和面向过程都是一种编程思想。生活中的事物都可以说成一个对象。比如猫是一个对象,狗也是一个对象,房子可以说成是一个对象,衣服也可以说成是一个对象。而面向过程重点表示了去做的过程。
面向对象与面向过程的区别:
-
面向过程的程序设计思想(Process-Oriented Programming),简称POP
-
关注的焦点是过程:像程序中的方法。
-
以过程,步骤为主,考虑怎么做,程序员是具体执行者
-
制约了软件的可维护性和可扩展性
-
-
面向对象的程序设计思想( Object Oriented Programming),简称OOP
- 关注的焦点是类:像程序中的类
- 以对象(谁)为主,考虑谁来做,谁能做,程序员是指挥者
- 面向对象仍然包含面向过程,只不过关注点变了,关注谁来做
- 软件可重用性、可维护性和可扩展性强
面向对象思想是一种更符合我们思考习惯的思想,它可以将复杂的事情简单化,并将我们从执行者变成了指挥者
说一个例子:(洗衣服)
面向过程:我们要①接水->②放衣服->③放洗衣液->④手搓->⑤拧干->⑥晾衣服
面向对象:我们只需要①放衣服到洗衣机->②打开洗衣机->③晾衣服就行了
类和对象
万物都可以说是对象。一个对象要具有一定的特征和属性。
对象:是一个具有特定属性和行为特征的事物。
类:类是对象更抽象一点的描述,也可以说类就是对象的模板。
类是对一类事物的描述,是比较抽象的。
对象是对一类事物的实例,是具体一点的。
》-------------------------------------------------------
就比如类可以说成是宠物,而实例可以说成是狗
类的定义
类通常是使用关键字class进行定义,在类中包含了类的成员:成员属性和成员方法等。
类的定义格式:
public class 类名 {
//成员变量,描述这类事物的属性
//成员方法,描述这类事物的行为
}
- 成员变量:和局部变量类似。但位置发生了改变。在类中,方法外,用于描述对象的属性特征。
- 成员方法:和以前写的main方法格式类似。只不过功能和形式更丰富了。在类中,方法外,用于描述对象的行为特征。
定义类的代码举例:
//定义顾客类
public class Customer {
//成员变量,描述属性特征
String name;//姓名
int age;//年龄
int weight;//体重
//成员方法,描述行为特征
public void shopping(){
System.out.println("购物...");
}
}
对象的创建
对象是在类的基础上进行详细的描述。是对类的实例化。比如说:类中定义了长、宽的属性,那么创建一个对象就可以给这两个赋不一样的值,可以是一个长方形也可以是一个正方形。
-
创建对象语法格式:
类名 对象名= new 类名 ();
Customer c=new Customer();
-
使用对象的成员,使用“. ”操作:
使用成员变量:对象名.属性
使用成员方法:对象名.方法名()c.name="张三"; //访问对象的属性,赋值 c.age=18; System.out.println(c.name+"--"+c.age); //访问对象的属性,获取值 c.shopping(); //访问对象的方法
对象的内存分析
我们平时新建的局部变量和方法,都是在栈中放着的。而当我们创建对象的时候,对象的引用也是放到栈里面的,而new出来的对象放到了堆里面。栈中对象的引用存的是对象在堆中的实际地址。
JVM的内存图
JVM内存结构图的各区域作用:
区域名称 | 作用 |
---|---|
栈 | 虚拟机栈,用于存储正在执行的每个Java方法的局部变量表等。局部变量表存放了编译期可知长度的各种基本数据类型、对象引用,方法执行完,自动释放。 |
堆 | 存储对象(包括数组对象),new来创建的,都存储在堆内存。 |
方法区 | 存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 |
程序计数器 | 程序计数器是CPU中的寄存器,它包含每一个线程下一条要执行的指令的地址 |
本地方法栈 | 当程序中调用了native的本地方法时,本地方法执行期间的内存区域 |
包(package)
包的作用
Java中创建的类多了,自然而然或许在我们不知道的情况下就会创建了几个有相同名字的类,那这个时候我们在想使用类,使用的是哪一个类呢?这个时候在改名字太过麻烦了。那我们就可以通过包名也可以说使用不同路径下的类。
使用包的好处:
- 可以避免重名,有了包后,类的全名就变成了包名.类名。
- 可以分不同的模块管理不同的类
- 控制某些类的可见范围
声明包的语法格式
package 包名;
注意:
- 包的声明必须在文件首行
- 一个源文件只能有一个声明包的语句
包的命名规范
- 所有的单词都小写,分级之间使用 . 分割
跨包使用类
前提:类的权限修饰符 :public、protected
- 包名.类名
-
- java.util.Scanner input = new java.util.Scanner(System.in);
- 也可以在package的下面使用import导入包路径。
-
- import的语法格式:
-
- import 包.类名;
import 包.*;
import static 包.类名.静态成员;
- import 包.类名;
注意:
- 使用java.lang包下的类,不需要使用import语句。
- import必须写在package下面和class上面
- 如果类中所需要两个同名不同包的类,另一个写类全名
成员变量
- 局部变量:定义在方法体或者代码块等局部区域的变量。
- 定义在类内,与方法平行的变量。
其中成员变量又分为 类变量(静态变量,使用static修饰的变量)和实例变量(没有static修饰的变量)
成员变量有默认初始值
数据类型 | 默认值 |
---|---|
byte,short,int,long | 0 |
float,double | 0.0 |
char | 0或’\u0000’表现为空 |
boolean | false |
数组,类,接口等引用类型 | null |
语法格式:
class 类名{
【修饰符】 数据类型 变量名;
}
注意:
- 可以使用四种权限修饰符
- 可以是基本数据类型,也可以是引用数据类型。
类变量
特点:
- 使用static修饰的变量
- 属于类的变量,推荐使用
类名.变量名进行访问
- 随着类的加载而加载
- 所有的对象共用一个类变量
格式:
class 类名{
【修饰符】static 数据类型 变量名;
}
实例变量
特点:
- 没有static修饰的变量
- 属于对象的变量,使用
对象名.变量名进行访问
- 每个对象有一个实例变量
- 在本类中可以通过this使用。
格式:
class 类名{
【修饰符】数据类型 变量名;
}
实例变量与局部变量的区别
实例变量 | 局部变量 | |
---|---|---|
声明的位置 | 直接声明在类的成员位置 | 声明在方法体中或其他局部区域内(方法声明上,构造方法,代码块等) |
修饰符 | public、private、final等 | 不能使用访问权限修饰符,可以使用final |
内存加载位置 | 堆 | 栈 |
初始化值 | 有默认初始化值 | 无默认初始化值 |
生命周期 | 同对象的生命周期 | 随着方法的调用而存在,方法调用完毕即消失 |
静态方法
使用static修饰的方法,也叫作类方法,工具类中使用的比较多,可以直接使用类名.方法名
进行调用。特点同类变量类似。
声明格式:
public class 类名{
【修饰符】 static 返回值类型 方法名(【参数列表】){
【方法体】
【return】
}
}
实例方法
实例变量是没有static修饰的变量,而实例方法也是没有static修饰的方法。先声明后使用,不调用不执行,调用一次执行一次。在本类中可以通过this使用。
声明格式:
public class 类名{
【修饰符】 返回值类型 方法名(【参数列表】){
【方法体】
【return】
}
}