面向对象内容的三条主线:
- Java类及类的成员:(重点)属性、方法、构造器;(熟悉)代码块、内部类
- 面向对象的特征:封装、继承、多态、(抽象)
- 其他关键字的使用:this、super、package、import、static、final、interface、abstract等
1.面向对象VS面向过程
面向过程思想 线性思维
步骤清晰简单,第一步做什么,第二步做什么…
面对过程适合处理一些较为简单的问题
面向对象思想
物以类聚,分类的思维模式,思考问题首先 解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。面向对象适合处理复杂的问题,适合处理需要多人协作的问题
对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理
可以理解为面向对象是一个框架 面向过程是具体的流程
关系:不要把面向过程和面向对象对立起来。他们是相辅相成的。面向对象离不开面向过程!
本质:
以类的方式组织代码,以对象的形式组织(封装)数据
类是对象的抽象 把相像的部分抽取出来 模板
三大特性:
封装 继承 多态 【一个类 不同对象 执行同一个方法得到的结果不同】
从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象
从代码运行角度考虑是先有类后有对象。类是对象的模板
2.类、对象
类与对象的关系
类是一种抽象的数据类型,它是对某一类事物的整体描述/定义,但是并不能代表某一个具体的事物
eg:
Person类、Pet类、Car类等,这些类都是用来描述/定义某一类具体的事物应该具备的特点(属性)和行为(方法)
对象是抽象概念的具体实例
创建与初始化对象
使用
new
关键字创建对象的时候,除了分配内存空间之外,还会给 创建好的对象 进行默认的初始化(赋默认值) 空间&值以及对类中构造器(方法)的调用
类中的构造器也称为构造方法,是在创建对象时必须要调用的。构造器有以下两个特点:
1.必须和类的名字相同
2.必须没有返回类型,也不能写void
public class Person {
//构造方法
public Person() {
}
}
作用:使用new
关键字本质是调用构造器 初始化对象的值
Attention
:一旦定义有参构造 如果要使用无参构造就必须显式定义(不然会被覆盖?)
对象. 进行调用
alt+insert//生成构造器的快捷键
public Person(String name){
this.name = name;//this代表当前类 name是传进来的值
}
对象的内存解析
创建对象内存分析
Pet dog = new Pet();//的内存过程
输出dog
会得到对象的地址 栈里的引用变量名指向堆中的对象
方法区是堆里的一个特殊区域
方法区里都是类 为啥不叫类区 类==方法?
栈里是 方法 和 对象的引用(就是变量名)
方法的调用内存解析
对应着一个栈帧 方法内的变量 局部变量 也在栈帧里
new 是实打实的创建对象
java内存结构划分
栈帧内部结构
3.类的成员之一:属性
Field
区分成员变量 vs 局部变量
之前没有意识到局部变量的初始值问题
引用数据类型的变量 存的都是地址值 指向对应的new出来的结构
//类型@地址值
5.再谈方法
方法的定义
//方法名要见名知意
修饰符 返回值类型 方法名(参数列表){
//方法体
return 返回值;
}
break
跳出switch
,结束循环 return
结束程序
方法的调用
静态方法 static
类名.方法名
static的方法是和类一起加载的 类存在时它已存在
//静态方法间也可以互相调用?
非静态方法
普通方法类实例化以后才存在(new过对象) 可以直接调用别的普通方法或者static方法
形参和实参
形参是占位符 形参与实参要一一对应
1.方法重载
(参数的重新装载?)
重点:编译器是如何确定调用的某个具体的方法呢
同一个类 方法名相同 形参【参数列表】不同 (可以是类型不同【次序不同】 个数不同)
方法重载规则
两同一不同
方法名称必须相同
参数列表必须不同(个数不同、或类型不同、参数(类型)排列顺序不同等)
注意:方法的重载与形参的名、权限修饰符、返回值类型都没有关系。
int 和 double都存在的重载 调用时能不提升就不提升 会先选参数列表是int类型的去执行
println的重载 形参是char数组的时候会遍历出来
重载实现原理
方法名相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错。
命令行传参 给main方法传参 要运行class
文件需要找到类的包路径src
去传参
注释里有中文时要加上编码类型
2.可变参数 不定项
jdk5.0新特性
使用场景:在调用方法时,可能会出现方法形参的类型是确定的,但是参数的个数不确定。此时,我们就可以使用形参个数可变的方法
可变长参数的本质是数组 所以如果有一个形参是数组的重载方法时 其实是重复的(因为在5.0之前这个功能就是用数组实现的)
可变的形参必须放在参数列表的最后
public void test(int...i)
public void print(int ... nums){
System.out.println("1111");
for(int i=0;i < nums.length, i++){//遍历时候 和数组是一样的
System.out.printin(nums[1]);
}
这种方法重载的时候编译器会先去找对应个数确定的
编译器能通过 但是调用时会分不清 报错
3.方法的值传递机制
基本的数据类型 在加载完赋值的时候没有地址值一说 变 量存的就是具体的数据
【一个方法对应一个栈帧 方法调用完后就出栈了 】
指向堆空间中实体
- 对于方法内声明的局部变量来说: 如果出现赋值操作
- 如果是基本数据类型的变量,则将此变量保存的数据值传递出去
- 如果是引用数据类型的变量,则将此变量保存的地址值传递出去
2.2 规则:实参给形参赋值的过程 【赋值过程类似这个语句 形参类型 形参名 = 实参名】
- 如果形参是基本数据型的变量,则将实参保存的数据值赋给形参
- 如果形参是引用数据类型的变量,则将实参保存的地址值赋给形参
把“a=10”这种字面量放到前面 可以避免遇到空值报错
4.递归方法
方法自己调用自己
利用递归可以用简单的程序来解决一些复杂的问题。
它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。
递归的能力在于用有限的语句来定义对象的无限集合。
递归结构包括递归头和递归体
递归头定义了终止递归的边界条件 没有递归头会陷入死循环
递归体定义了调用自身方法的条件
应用举例:连续数值求和、阶乘、汉诺塔、快速排序、斐波那契数列(生兔子)、计算文件目录大小,遍历指定的文件目录中的所有的文件,删除指定的文件目录。
走楼梯 实际上是最后走上第十阶的时候 前一步在还9还是在8 包含这两种情况
简单小结类与对象
-
类与对象
类是一个模板:抽象,对象是一个具体的实例 -
方法
定义、调用! -
对象的引用
引用类型:对象是通过引用来操作的:栈--->堆
-
属性:字段Field 成员变量
默认初始化:
数值:char :u0000
boolean:false
引用:
null
修饰符 属性类型 属性名 = 属性值 -
对象的创建和使用
- 必须使用
new
关键字创建对象 通过构造方法 - 对象的属性
- 对象的方法
Person Amy = new Person(); Amy.name Amy.sleep()
- 必须使用
-
类
静态的属性 属性
动态的行为 方法
7.package与import关键字
package
-package:包
-package用于指明该文件中定义的类、接口等结构所在的包
-一个源文件只能有一个声明包的package语句
-package语句作为Java源文件的第一条语句出现。若缺省该语句,则指定为无名包。
-包名,属于标识符,满足标识符命名的规则和规范(全部小写)、见名知意
-包通常使用所在公司域名的倒置:com.atguigu.xxx。
-大家取包名时不要使用"java.xx'"包 类加载器在加载的时候会报错
-包对应于文件系统的目录,package语句中用“.”来指明包(目录)的层次,每.一次就表示一层文件目录。
-同一个包-可以声明多个结构(类、接口),但是不能定义同名的结构(类、接口)。不同的包下可以定义同名的结构
包的作用
-
包可以包含类和子包,划分"项目层次”,便于
-
管理帮助管理大型软件系统:将功能相近的类划分到同一个包中。比如:MVC的设计模式
-
解决'类命名冲突`的问题
-
控制访问权限 包相当于一层屏障 同一个包里的可以自由调用 不同包得import导进来
import
lang是核心的 不用import引
8.封装
该露的露,该藏的藏 随着我们系统越来越复杂,类会越来越多,那么类之间的访问边界必须把握好
电视机理论 给了用户遥控器去操作 实现细节在盒子里
程序设计要追求“高内聚,低耦合”。高内聚:类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用,尽量方便外部调用
封装(数据的隐藏)
通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏
记住这句话就够了:属性私有,get/set
如何实现数据封装
其他包的子类 指有继承关系
JAVA规定的四种修饰符的优先级:
//public > protected > default [缺省]> private
什么是封装性:可以使用4种权限修饰来修饰类及类的内部成员(属性、方法和构造器 )。当这些成员被调用时,体现可见性的大小
类里只有属性、方法和构造器 执行语句要放到方法里面
通过(get、set)方法限制对象对属性的调用【定了操作属性的规则 】
四种权限的具体使用
-
类:只能使用public、缺省修饰
-
类的内部成员:可以使用4种权限修饰进行修饰。
缺省就是包内用了
3.封装性的体现
场景1:私有化(private)类的属性,提供公共(public)的get和set方法,对此属性进行获取或修改
场景2:将类中不需要对外暴露的方法,设置为private仅在类内用到了
场景3:单例模式中构造器private的了,避免在类的外部创建实例。(放到static关键字后讲)
封装的意义
- 提高程序安全性 保护数据
- 隐藏代码实现细节
- 统一接口【
get/set
set
里可以进行数据安全性的判断】 - 增加系统可维护性 便于修改内部代码
9.构造器
2.构造器的作用
1:搭配new关键字,创建类的对象 new+构造器 造对象 只有构造器没有new不会创建对象
2:在创建对象的同时,可以给对象的相关属性赋值 主要就是用来初始化的
3.构造器的使用说明
构造器声明的格式:权限修饰符 类名(形参列表){} 与类同名 同名的类里才有 不会被子类继承
创建类以后,在没有显示提供任何构造器的情况下,系统会默认提供一个空参的构造器,且构造器的权限与类声明的权限相同。
一旦类中显示声明了构造器,则系统不再提供默认的空参的构造器。 要想使用这个空参的 就要再显式的声明出来
一个类中可以声明多个构造器,彼此之间构成重载。
匿名对象:创建的对象没有名
匿名对象往往只能被调用一次(没名字 没法调) 通常作为实参传给形参
10.阶段知识补充
实例变量赋值过程
一个类的多个实例共享一个static静态成员变量
实例变量 每一个对象都有一组自己的成员变量
1.在类的属性中,可以有哪些位置给属性赋值?
[通过代码块赋值]
对象创建时(初始化)
对象创建后
字段、方法、构造器 在类的成员里是并列关系构造器不是什么特殊的方法
在字节码文件里会把构造器转换成init方法
JAVABean
所谓JavaBean,是指符合如下标准的Java类:
-类是公共的
-有一个无参的公共的构造器 方便创建对象 属性通过get set赋值
-有属性,且有对应的get、set方法
UML类图
复习
1.(了解)面向过程 vs 面向对象
不管是面向过程、面向对象,都是程序设计的思路。
面向过程:以函数为基本单位,适合解决简单问题。比如:开车
面向对象:以类为基本单位,适合解决复杂问题。比如:造车
2.类、对象
-
类:抽象的,概念上的定义
-
对象:具体的,类的一个一个的实例。
-
面向对象完成具体功能的操作的三步流程(非常重要)
步骤1:创建类,并设计类的内部成员(属性、方法)
步骤2:创建类的对象。比如:Phonep1=newPhone();
步骤3:通过对象,调用其内部声明的属性或方法,完成相关的功能
- 对象的内存解析
创建类的一个对象;创建类的多个对象;方法的调用的内存解析
- Java中内存结构的划分
Java中内存结构划分为:虚拟机栈、堆、方法区
;程序计数器、本地方法栈
虚拟机栈: 以栈帧为基本单位,有入栈和出栈操作;每个栈帧入栈操作对应一个方法的执行;方法内的局C部变量 会存储在栈帧中。
堆空间: new 出来的结构(数组、对象):① 数组,数组的元素在堆中 ② 对象的成员变量在堆中。o
方法区: 加载的类的模板结构。
3.类的成员之一:属性(或成员变量)
- 属性 vs 局部变量
声明的位置
内存中存放的位置 属性在堆里 局部变量在栈里
作用域
权限修饰符
初始化值
生命周期
属性 <=>成员变量 <=>field <=>字段、域
4.类的成员之二:方法
- 方法的声明:权限修饰符 返回值类型 方法名(形参列表){//方法体)
重点:返回值类型、形参列表
- return关键字的使用
5.再谈方法
5.1方法的重载(overload)
- 方法的重载的要求:“两同一不同“
- 调用方法时,如何确定调用的是某个指定的方法呢?①方法名 ② 形参列表
5.2 可变个数形参的方法
- 格式:(int ... args)
5.3 方法的参数传递机制(重、难点)
如果形参是基本数据类型的变量,则将实参保存的数据值赋给形参。
如果形参是引用数据类型的变量,则将实参保存的地址值赋给形参。
5.4递归方法
- 递归方法构成了隐式的循环
- 对比:相较于循环结构,递归方法效率稍低,内存占用偏高。
6.对象数组
String[] Person[] Customer[]
7.package、import关键字的使用
package:指明声明的类所属的包。
import:当前类中,如果使用其它包下的类(除java.lang包),原则上就需要导入。
8.oop的特征之一:封装性答题
Java规定了4种权限修饰,分别是:private、缺省、protected、public。
我们可以使用4种权限修饰来修饰类及类的内部成员 。当这些成员被调用时,体现可见性的大小。
举例:
场景1:私有化(private)类的属性,提供公共(public)的get和set方法,对此属性进行获取或修改
场景2:将类中不需要对外暴露的方法,设置为private
场景3:单例模式中构造器private的了,避免在类的外部创建实例。(放到static关键字后讲)
9.类的成员之三:构造器
如何定义:权限修饰符 类名(形参列表){}
构造器的作用:① 搭配上new,用来创建对象 ② 初始化对象的成员变量
企业真题
栈上分配 是一种优化 试图把对象放进栈里 堆中垃圾回收 栈进出比较快
3.都是用来初始化的
标签:调用,形参,对象,构造,面向对象编程,basic,方法,属性 From: https://www.cnblogs.com/amy-5050/p/18183571