Java基础复习笔记 第06章:面向对象-基础

1. 理解:面向过程vs面向对象

简单的语言描述二者的区别
> 面向过程:以`函数`为组织单位。是一种“`执行者思维`”,适合解决简单问题。扩展能力差、后期维护难度较大。

> 面向对象:以`类`为组织单位。是一种“`设计者思维`”,适合解决复杂问题。代码扩展性强、可维护性高。

2.2 二者关系:在面向对象的编程中,具体的方法中,仍然会体现面向过程的思想。所以二者是合作关系。

2. 面向对象的要素:类、对象

  • 区分类与对象

    • 类:抽象的、概念上的定义
    • 对象:具体的,实实在在存在的,由类派生出来的
  • 设计类,就是设计类的成员:属性、方法

  • 面向对象完成具体功能的操作的三步流程(非常重要)

    步骤1:创建类,即设计类的内部成员(属性、方法)
    步骤2:创建类的对象。
    步骤3:通过"对象.属性" 或 "对象.方法"的方式,完成相关的功能。
    
  • 对象的内存解析

    • JVM内存分配:虚拟机栈、堆、方法区(目前用不到)、程序计数器(略)、本地方法栈(略)
      • 虚拟机栈:存放的是方法对应的栈帧,每个栈帧中存放方法中声明的局部变量。
      • 堆:new出来的"东西":数组实体、对象实体(含成员变量)
    • 创建类的1个对象、创建类的多个对象(内存解析图建议大家都自己画画)

3. 类的成员之一:属性(重点)

1.变量的分类:
- 角度一:按照数据类型来分:基本数据类型(8种)、引用数据类型(数组、类、接口;注解、枚举、记录)
- 角度二:按照变量在类中声明的位置来分:成员变量、局部变量

2. 成员变量的几个称谓:

成员变量 <=> 属性 <=> field(字段、域)

3. 区分成员变量   vs 局部变量
3.1 相同点:(了解)
> 都有三个要素(数据类型、变量名、变量值)
> 声明的格式相同:数据类型 变量名 = 变量值
> 变量都是先声明后使用
> 变量都有作用域,在其作用域内是有效的

3.2 不同点:
① 类中声明的位置的不同:
> 成员变量:声明在类内部、方法等结构的外部。
> 局部变量:声明在方法内部、方法的形参、构造器的内部、构造器的形参、代码块的内部等

② 在内存中分配的位置不同:
> 成员变量:随着对象实体在堆空间进行分配而分配(或存储)
> 局部变量:存储在栈空间。

③ 生命周期:
> 成员变量:随着对象的创建而产生,随着对象的消亡而消亡
> 局部变量:(以方法为例)随着方法的调用而产生,随着方法的调用结束而消亡。
      > 拓展:每一个方法的执行,都对应着一个栈帧加载进栈中。局部变量就存储在每个方法对应的栈帧中。
             当方法执行结束时,对应的栈帧就弹出栈,进而栈帧中的局部变量也弹出,进而消亡。

④ 作用域:
> 成员变量:在整个类的内部是有效的。---> 类的方法中是可以调用类中的成员变量的。
> 局部变量:以方法为例,作用域仅限于方法内部。

⑤ 是否可以有权限修饰符进行修饰:(超纲)
> 成员变量:可以被不同的权限修饰符进行修饰。(后面讲封装性时,具体说:private、public、protected、缺省)
> 局部变量:不可以被权限修饰符进行修饰。一旦修饰,编译不通过。


⑥ 是否有默认值:
> 成员变量:都有默认值
      默认值的情况与不同类型的一维数组的元素的默认值相同。
      > 整型:0
      > 浮点型:0.0
      > 字符型:0
      > 布尔型:false
      > 引用类型:null

> 局部变量:没有默认值。
   意味着在调用之前必须要显示赋值。如果不赋值,就报错。
       > 特别的:方法的形参在方法调用时赋值即可。

4. 类的成员之二:方法(重点)

4.1 方法的使用#
1. 使用方法的好处
将功能封装为方法的目的是,可以实现代码重用,减少冗余,简化代码。

2. 使用举例
- Math.random()的random()方法
- Math.sqrt(x)的sqrt(x)方法
- System.out.println(x)的println(x)方法
- new Scanner(System.in).nextInt()的nextInt()方法
- Arrays类中的binarySearch()方法、sort()方法、equals()方法

3. 方法声明的格式

举例:public void eat()
     public void sleep(int hour)
     public String getName()
     public String playGame(String game)

格式:
     权限修饰符  返回值类型 方法名(形参列表){
        方法体
     }

4. 具体的方法声明的细节

4.1 权限修饰符:体现此方法被调用时,是否能被调用的问题。(主要放到封装性的时候讲解)
    暂时,大家在声明方法时,先都使用public修饰即可。

4.2 返回值类型:(难点)
    > 分类:有具体的返回值的类型(指明具体的数据类型) 、 没有返回值类型(使用void)
    > 情况1:有具体的返回值的类型的要求:既然有返回值的类型,则要求此方法在执行完时,一定要返回
            满足此类型的一个变量或常量。
            > 内部使用"return 变量(或常量)"的方法,返回数据
    > 情况2:没有返回值类型:内部就不需要使用return结构了。
            > (难点)其实,我们在此方法中也可以使用return,仅表示结束此方法。

    开发中,设计一个方法时,是否需要设计返回值类型?
       > 根据题目的要求设计。
       > 具体问题具体分析:调用完此方法之后,是否需要一个结果性的数据,供之后使用。如果有必要,就设计有返回值类型的场景即可。

4.3 方法名:属性标识符,定义时需要满足标识符的命名规则、规范、"见名知意"。

4.4 形参列表:(难点)
       > 在一个方法的一对小括号中可以声明形参列表,形参的个数可以为0个、1个或多个。
       > 如果有形参的话,格式为: (数据类型1 形参名1,数据类型2 形参名2,...)

      开发中,设计一个方法时,是否需要提供形参呢?
         > 根据题目的要求设计。
         > 具体问题具体分析:调用此方法时,是否存在不确定性的数据。如果有,则以形参的方法传入此不确定的数据。

4.5 方法体:即为调用方法时,执行的代码。可以使用当前方法声明的形参,使用类中的成员变量。

5. 注意点
> Java里的方法`不能独立存在`,所有的方法必须定义在类里。
> 方法内可以使用类中的成员变量
> 方法内不可以定义方法,但是方法内可以调用本类中的其它方法。 ---> 递归方法中谈方法内自己调用自己。
> 类中不可以定义多个相同的方法。---> 方法的重载

4.2 return关键字
1. return的作用
> 作用1:结束当前方法的执行
> 作用2:"return + 变量/常量"结构在方法结束的同时,还可以返回一个数据。

2. 使用注意点:
与break、continue类似,其后不能声明执行语句。

5. 内存的分配使用

5.1 方法调用的内存解析
- 形参:方法声明时,一对小括号内声明的参数,简称:形参
- 实参:方法调用时,实际赋值给形参的值,称为:实参

过程概述:
每当调用一个方法时,方法就以栈帧的方法加载进虚拟机栈中。方法中声明的局部变量存放在栈帧中。
当方法执行结束时,栈帧就会弹出栈。栈帧中存放的局部变量也随之消亡。
5.2 目前为止,内存分析(重要)
  • 基本原则

1、JVM中内存划分

  • 栈:以栈帧为基本单位(每个方法对应一个栈帧);栈帧里存放局部变量。
  • 堆:new 出来的"东西":数组实体(含数组元素)、对象实体(含成员变量)

2、区分清成员变量(类内部、方法外声明的)、局部变量(方法的形参、方法内定义的变量、构造器内定义的变量、构造器的形参、代码块内部等)

3、值传递机制:

  • 如果参数是基本数据类型,传递的是基本数据类型变量存储的数据值
  • 如果参数是引用数据类型,传递的是引用数据类型变量存储的地址值

6. 再谈方法

6.1 方法的重载(overload )
1. 定义:
在同一个类中,允许存在一个以上的同名方法,只要它们的参数列表不同即可。满足这样特点的多个方法彼此之间称为
方法的重载。

2. 总结为:"两同一不同":同一个类、相同的方法名;形参列表不同(参数的个数不同,参数的类型不同)
> 重载与否与形参名没有关系、返回值类型没有关系、权限修饰符没有关系

3. 举例
> Arrays中的重载的binarySearch(xxx) \ equals(xxx,xxx) \ toString(xxx)
> System.out的多个重载的println();

4. 如何判断两个方法是相同的呢?(换句话说,编译器是如何确定调用的某个具体的方法呢?)
> 在同一个类中,只要两个方法的方法名相同,且参数列表相同(参数的个数相同且参数类型相同),
   则认为这两个方法是相同的。
        > 与方法的权限修饰符、返回值类型、形参名都没有关系。

> 在同一个类,不能编写两个相同的方法的。

后续会讲:方法的重写(overwrite / override)

面试题:方法的重载与重写的区别?

throw \ throws
Collection \ Collections
final \ finally \ finalize
String \ StringBuffer \ StringBuilder
ArrayList \ LinkedList 
。。。
== 、equals()
抽象类、接口
6.2 可变个数形参的方法
1. 使用场景
JDK5.0的新特性。

如果方法在调用时,参数的类型是确定的,但是参数的个数不确定,则可以考虑使用可变个数形参的方法。

2. 格式:类型 ... 变量名


3. 说明:
> 可变个数形参的方法在调用时,可以传入0个,1个或多个参数。
> 可变个数形参的方法与参数是其它类型的同名方法构成重载。
> 可变个数形参的方法与参数是同样类型的数组参数构成的方法,在方法名相同的情况下,不构成重载。即两个方法不能
  同时存在。
        > 可变个数的形参在编译器看来就是同一个类型的数组参数
> 规定:可变个数的形参需要声明在方法形参列表的最后
> 一个方法的形参位置,最多只能有一个可变个数的形参
/*
String sql1 = "update customers set name = ?,salary = ? where id = ?";
String sql2 = "delete from customs where id = ?";

public void update(String sql,Object ... objs){
	//使用可变形参objs中的各个元素值给形参sql中的?赋值
}
*/
6.3方法的参数传递机制(难点、重点)
1. 对于方法内声明的局部变量来说:

> 如果此局部变量是基本数据类型的,则将基本数据类型变量保存的数据值传递出去
> 如果此局部变量是引用数据类型的,则将引用数据类型变量保存的地址值传递出去


2. 方法的参数的传递机制:值传递

2.1 概念(复习)
形参:方法声明时,一对小括号内声明的参数,简称:形参
实参:方法调用时,实际赋值给形参的值,称为:实参

2.2 规则
> 如果此形参是基本数据类型的,则将基本数据类型的实参保存的数据值传递给形参
> 如果此形参是引用数据类型的,则将引用数据类型的实参保存的地址值传递给形参


3. 面试题:Java中的参数传递机制是什么? 值传递机制。
6.4 递归方法(熟悉)
1. 何为递归方法?
方法自己调用自己的现象就称为递归。


2. 递归方法分类
直接递归、间接递归。

3. 使用说明:
- 递归方法包含了一种`隐式的循环`。
- 递归方法会`重复执行`某段代码,但这种重复执行无须循环控制。
- 递归一定要向`已知方向`递归,否则这种递归就变成了无穷递归,停不下来,类似于`死循环`。最终发生`栈内存溢出`。

7. 对象数组(难点)

1. 何为对象数组?如何理解?

数组中的元素,如果存储的是对象的话,则称此数组为对象数组。

2. 举例:
String[] arr = new String[10];
arr[0] = "hello";
arr[1] = new String("abc");

Person[] arr1 = new Person[10];
arr1[0] = new Person();

Phone[] arr2 = new Phone[10];

3. 内存解析:
数组名(比如:stus)存储在栈空间
创建的20个学生对象,存储在堆空间中。学生对象的地址值存储在数组的每个元素中。

8. 关键字:package、import#

  • package:包,指明了Java中的类、接口等结构所在的包。声明在文件的首行
  • import:导入。指明在当前类中使用的其它包中的结构。声明在package下,类的声明之前。
一、package关键字的使用

1. 说明
- package,称为包,用于指明该文件中定义的类、接口等结构所在的包。
- 一个源文件只能有一个声明包的package语句
- package语句作为Java源文件的第一条语句出现。若缺省该语句,则指定为无名包。以后声明源文件时,不要使用无名包。
- 包名,属于标识符,满足标识符命名的规则和规范(全部小写)、见名知意
  - 包名推荐使用所在公司域名的倒置:com.atguigu.xxx。
  - 大家取包名时不要使用"`java.xx`"包,否则运行会报错
- 包对应于文件系统的目录,package语句中用 “.” 来指明包(目录)的层次,每.一次就表示一层文件目录。
- 同一个包下可以声明多个结构(类、接口),但是不能定义同名的结构(类、接口)。不同的包下可以定义同名的结构(类、接口)


2. 包的作用
- 包可以包含类和子包,划分`项目层次`,便于管理
- 帮助`管理大型软件`系统:将功能相近的类划分到同一个包中。比如:MVC的设计模式
- 解决`类命名冲突`的问题 ---> 不同包下可以命名同名的类。
- 控制`访问权限` ---> 讲了封装性,大家就清楚了。


二、import关键字的使用
- import:导入,后面跟一个具体包下的类或接口等结构。

-为了使用定义在其它包中的Java类,需用import语句来显式引入指定包下所需要的类。
相当于`import语句告诉编译器到哪里去寻找这个类`。

- import语句,声明在包的声明和类的声明之间。

- 如果需要导入多个类或接口,那么就并列显式多个import语句即可

- 如果使用`a.*`导入结构,表示可以导入a包下的所有的结构。
  举例:可以使用java.util.*的方式,一次性导入util包下所有的类或接口。

- 如果导入的类或接口是java.lang包下的,或者是当前包下的,则可以省略此import语句。

- 如果已经导入java.a包下的类,那么如果需要使用a包的子包下的类的话,仍然需要导入。

- 如果在代码中使用不同包下的同名的类,那么就需要使用类的全类名的方式指明调用的是哪个类。

- (了解)`import static`组合的使用:调用指定类或接口下的静态的属性或方法

9. 面向对象的特征一:封装性

  • 什么是封装性?
在Java实现项目时,将不用功能的代码封装进不同的方法。使用Java给我们提供的4种权限修饰对类及类的内部成员进行修饰。
体现被修饰的结构在调用时的可见性的大小。
  • 如何体现封装性?
> 举例1:类中的属性私有化,提供公共的get()和set()方法,用于获取或设置此属性的值。
> 举例2:如果类中存在一些方法,这些方法只在类的内部使用,不希望对外暴露,则可以将这些方法声明为私有的。
> 举例3:单例设计模式。(后面讲static的时候说)
  • 为什么需要封装性?
-  `高内聚`:类的内部数据操作细节自己完成,不允许外部干涉;
-  `低耦合`:仅暴露少量的方法给外部使用,尽量方便外部调用。


- 通俗的讲,把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想。

10. 类的成员之三:构造器

1. 构造器的理解

体会1: Scanner scan = new Scanner(System.in);
      Person per = new Person();

体会2:
construct : v. 建设、建造
construction: n. 建设、建造    CCB 中国建设银行  ICBC
constructor : n.建设者,建造者

2. 构造器的作用
>作用1:搭配new关键一起,用于对象的创建
>作用2:用于初始化对象中的成员变量

3. 构造器的使用说明
> 一个类中,如果没有显式提供构造器的话,则JVM会默认提供一个空参的构造器。(其权限修饰符与类的权限修饰符相同)
> 声明格式:权限修饰符 类名(形参列表){}
> 一个类的多个构造器,彼此构成重载
> 如果一个类中,一旦显式的声明了构造器,则JVM不再提供默认的空参的构造器了。
> 结论:凡是类,都有构造器(自始至终都是对的)

11. 其它几个小知识

11.1 类中实例变量的赋值位置及顺序
0.实例变量:属于属性(或成员变量),不使用static修饰即可。

1. 在类的属性中,可以有哪些位置给属性赋值?
> ① 默认初始化 ---> 只执行一次
> ② 显式初始化 ---> 只执行一次
> ③ 构造器中初始化  ---> 只执行一次
*********************************
> ④ 创建对象以后,通过"对象.属性" 或"对象.方法"的方式,给属性赋值  ---> 可以多次执行


2. 这些位置执行的先后顺序是怎样?
① - ② - ③ - ④



3. 以上操作在对象创建过程中可以执行的次数如何?
①、②、③:只执行一次
④:可以多次执行
11.2 JavaBean
所谓JavaBean,是指符合如下标准的Java类:
- 类是公共的
- 有一个无参的公共的构造器
- 有属性,且有对应的get、set方法
11.3 UML类图

理解

11.4 匿名对象
//匿名对象
System.out.println(new Circle(2.5).findArea());
//知识点1:如上写法的匿名对象,只能被调用一次。
System.out.println(new Circle(2.5).getRadius());
//知识点2:开发中,常常将匿名对象作为参数传递给方法的形参。
Test4_5 test = new Test4_5();

test.show(new Circle(3.4));
  • 21
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值