面向对象编程
一、Java面向对象学习的三条主线
Java类及类的成员
:属性、方法、构造器;代码块、内部类面向对象的三大特征
:封装性、继承性、多态性、(抽象性)- 其他关键字:this、super、static、final、abstract、interference、package、import
“大处着眼,小处着手”
1.1、面向过程与面向对象
面向过程
(POP,Procedure Oriented Programming):强调的是功能行为,以函数为最小单位,考虑怎么做。
面向对象
(OOP,Object Oriented Progamming):将功能封装进对象,强调了具备功能的对象,以类/对象为最小单位,考虑谁来做。
举例:
问题描述:“人把大象装进冰箱”
1.面向过程:强调的是功能行为,以函数为最小单位,考虑怎么做。
① 把冰箱门打开
② 抬起大象,塞进冰箱
③ 把冰箱门关闭
2.面向对象:强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。
人{
打开(冰箱){
冰箱.开开();
}
抬起(大象){
大象.进入(冰箱);
}
关闭(冰箱){
冰箱.闭合();
}
}
冰箱{
开开(){}
闭合(){}
}
大象{
进入(冰箱){}
}
1.2、面向对象的两个要素
类
:对一类事物的描述,是抽象的、概念上的定义
对象
:是实际存在的该类事物的每个个体,因而也称为实例(instance)
- 面向对象程序设计的重点是类的设计
- 设计类,就是设计类的成员,常见的类的成员有:
属性
:field(可翻译为 ”域“ 或 ”字段“ ),对应类中的成员变量
行为
:method,对应类中的成员方法
类创建好后如何使用?----类的实例化,即创建类的对象
1.3、类和对象的使用
(面向对象思想落地的实现):
步骤:
1.创建类,设计类的成员
2.创建类的对象
3.通过 ”对象.属性“ 或 "对象.方法” 调用对象的结构
public class PersonTest {
public static void main(String[] args) {
//创建Person类的对象
Person p1 = new Person();
// Scanner scanner = new Scanner(System.in);
//调用对象的结构:属性、方法
//调用属性:对象.属性
p1.age = 1;
p1.isMale = true;
p1.name = "Cute";
System.out.println(p1.age);
//调用方法:对象.方法
p1.eat();
p1.sleep();
p1.talk(Chinese);
}
public class Person{
//属性
String name;
int age;
boolean isMale;
//方法
public void eat(){
System.out.println("人可以吃饭");
}
public void sleep(){
System.out.println("人可以睡觉");
}
public void talk(String language){
System.out.println("人可以说话,使用的是:" + language);
}
}
}
如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的属性(非static的)
1.4、对象的内存解析
- 内存结构:栈(局部变量)、堆(new出来的结构:对象(非static成员变量)、数组)
- 变量:成员变量 vs 局部变量(方法内、方法形参、构造器内、构造器形参、代码块内)
- 方法中的变量都是局部变量
- 引用类型的变量,只可能存储两类值:null 或 地址值(含变量的类型)
重要!!!
虚拟机栈
:即为平时提到的栈结构。我们将局部变量存储在栈结构中
堆
:我们将new出来的结构(比如:数组、对象)加载到堆空间中。 补充:对象的属性(非static的)加载到堆空间中
方法区
:类的加载信息、常量池、静态域本地方法栈:一般存储C、C++的东西
1.5、对象数组的内存解析
引用类型的变量,只可能存储两类值:null 或 地址值(含变量的类型)
1.5、类中属性的使用
类中属性的使用
属性(成员变量) vs 局部变量
1.相同点:
1.1 定义变量的格式:数据类型 变量名 = 变量值
1.2 先声明、后使用
1.3 变量都有其对应的作用域
2.不同点
2.1 在类中声明的位置不同
属性
:直接定义在类的一对{}内
局部变量
:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量 2.2 关于权限修饰符的不同
属性:可以在声明属性时,指明其权限,使用权限修饰符
常用的权限修饰符:private 、public、缺省、protected---->封装性
局部变量:不可以使用权限修饰符
2.3 默认初始化值的情况
属性:类的属性,根据其类型。都有默认初始化值
整型(byte、short、int、long):0
浮点型(float、double): 0.0
字符型(char): 0(或’\u0000‘)
布尔型(boolean): false
引用数据类型(类、数组、接口):null
局部变量:没有默认初始化值
意味着,我们在调用局部变量之前,一定要显式赋值
特别地,形参在调用时,我们赋值即可。
2.4 在内存中加载的位置
属性:加载到堆空间中(非static)
局部变量:加载到栈空间
具体可见下表:
不同点 | 属性(成员变量) | 局部变量 | |
---|---|---|---|
相同点 | 1.1 定义变量的格式:数据类型 变量名 = 变量值 | 1.2 先声明、后使用 | |
1.3 变量都有其对应的作用域 | |||
2.1 在类中声明的位置不同 | 直接定义在类的一对{}内 | 声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量 | |
2.2关于权限修饰符的不同 | 可以在声明属性时,指明其权限,使用权限修饰符 | 不可以使用权限修饰符 | |
2.3 默认初始化值的情况 | 类的属性,根据其类型。都有默认初始化值 | 没有默认初始化值。意味着,我们在调用局部变量之前,一定要显式赋值。特别地,形参在调用时,我们赋值即可。 | |
2.4 在内存中加载的位置 | 加载到堆空间中(非static) | 加载到栈空间 |
1.6、类中方法的声明和使用
方法:描述类应该具有的功能
比如:
- Math类:sqrt()\random()…
- Scanner类:nextXxx()…
- Arrays类:sort()\binarySearch()…
1.6.1、举例
public void eat()//无返回值,无形参
public void sleep(int hour)//无返回值,有形参
public String getName()//有返回值,无形参
public String getNation(String getNation//有返回值,有形参
1.6.2、方法的声明
权限修饰符 返回值类型 方法名(形参列表){
方法体
}
static final abstract 也可以修饰方法
1.6.2.1、成员变量和局部变量
- 在方法体外,类体内声明的变量称为成员变量;
- 在方法体内部声明的变量成为局部变量。
1.6.3、具体说明
1.6.3.1、权限修饰符
默认权限的修饰符都是public
Java规定的4种修饰符:private、public、protected、缺省
1.6.3.2、返回值类型
可分为 有返回值 vs 无返回值
-
如果有返回值,则必须在方法声明时,指定返回值的类型。同时,方法中需要使用return关键字来返回指定类型的变量或常量。格式:
return 数据;
-
如果方法没有返回值,则方法声明时,使用void来表示。没有返回值的方法中,就不使用return,但是,如果使用的话,只能"
return;
"表示结束此方法的意思。 -
定义方法该不该有返回值?
① 题目要求
② 凭经验:具体问题具体分析
1.6.3.3、方法名
方法名属于标识符
,应该符合标识符的规则和规范, ”见名知意“
1.6.3.4、形参列表
方法可以声明0个,1个,或多个形参、
格式:数据类型1 形参1 ,数据类型2 形参2,…
1.6.3.5、方法体
方法功能的体现
1.6.3.6、return关键字
-
使用范围:使用在方法体中
-
作用:
① 结束方法
② 针对于有返回值类型的方法,使用”return 数据“方式返回所要的数据。
③ 注意:return 关键字后面不可以声明执行语句
1.6.3.7、如何调用
方法的使用中,方法可以调用当前类的属性或方法
特殊的:方法A中又掉用了方法A:递归方法
方法中,不可以定义方法。