数组和面向对象

数组和面向对象

一,数组

1.1 Java中如何定义数组

数据类型[] 数组名 = new 数据类型[容量];
/*
赋值左侧
数据类型:
  告知编译器,当前数组中能够保存的数据类型到底是什么?并且在确定数据类
  型之后,整个数组中保存的数据类型无法修改!!!
 []:
  1. 告知编译器这里定义的是一个数组类型数据。
  2. 明确告知编译器,数组名是一个【引用数据类型】
数组名:
  1. 操作数据非常重要的数据!!!
  2. 数组名是一个【引用数据类型】
  小拓展: int(*) (void *, void *)
赋值号右侧:
new:
  申请【XX】内存空间,并且清空整个内存空间中所有二进制位,所有的二进制
  位都是0
数据类型:
  前后呼应,告知编译器这里支持存储的数据类型到底是什么? 
 【容量】:
  容量==> Capacity
  告知编译器,当前数组中能够存放的对应数据类型的数据,最大存储多少
  个!! 
 【注意】
   一旦确定容量,针对于当前数组,后期容量无法修改
*/

1.2 数组的下标

 规定
	 数组中的下标是从0开始,到数组的容量 - 1
 例如:
	 数组容量为10
	 有效下标范围: 0 ~ 9
	 超出有效下标范围,都是无效下标,后期考虑数组处理异常问题,负数使用问题
操作会出现的问题:
	 1. 数组下标越界
	  ArrayIndexOutOfBoundsException

1.3数组算法

1.3.1完成一个数组逆序过程

public static void reverse(int[] arr) {
    int temp = 0;
    for (int i = 0; i < arr.length / 2; i++) {
        /*
        arr[0] = arr[9]
        arr[1] = arr[8]
        arr[2] = arr[7]
        arr[3] = arr[6]
        arr[4] = arr[5]
        */
        temp = arr[i];
        arr[i] = arr[arr.length - 1 - i];
        arr[arr.length - 1 - i] = temp;
    }
}

1.3.2 找出数组中最大值所在下标位置

/**
* 返回指定int类型数组中最大值的下标位置
*
* @param arr int类型数组
* @return 返回值是最大值所在的下标位置
*/
public static int maxIndexOf(int[] arr) {
    // 
    int maxIndex = 0;
}

1.3.3 找出数组中指定元素所在的第一次出现下标位置

*/
/**
* 找出指定数组中,指定元素的下标位置,通过返回值返回
*
* @param arr 指定的int类型源数据数组
* @param find 指定需要查询的数据
* @return 返回值大于等于0,表示找到对应的数据,否则返回-1
*/
public static int indexOf(int[] arr, int find) {
 // 首先假设对应查询的数据是不存在的!!!
 int index = -1;
 
 // 利用循环,从下标为0的元素开始到最大下标,比对是否存在find
     for (int i = 0; i < arr.length; i++) {
	  // 发现指定find元素和下标为i的元素一致
	 if (find == arr[i]) {
	   // 使用index保留对应的下标i
	   index = i;
	   // 终止循环!!!
	   break;
	  }
     }
	 
	 return index;
}

1.3.4 获取数组中指定下标的元素

/*
需求
 找出指定下标的元素
方法分析:
 public static 不要问
 返回值类型:
  数组为int类型,这里返回值也是int类型
 方法名:
  get
 形式参数列表
  指定的数组 int[] arr
  指定的下标 int index
  0 ~ arr.length - 1
方法声明:
 public static int get(int[] arr, int index)
*/
/**
* 找出数组中指定下标的元素
*
* @param arr 指定的int类型数组  
* @param int 指定查询的下标位置
* @return 返回对应下标位置的元素
*/
public static int get(int[] arr, int index) {
 // 用户指定的index不能超出有效下标范围
    if (index < 0 || index > arr.length - 1) {
	  /*
	  返回任何的数据类型都不合适,可以考虑终止方法,
	  并且告知用户错误是什么
	  后期课程中可以使用到异常处理
	  【用户输入参数合法性判断】
	  */
	  System.out.println("Input Parameter is Invalid!");
	  // 当前方法退出!!!
	  System.exit(0);
     }
	 
	 return arr[index];
}

二,面向对象

2.1 生活中什么是面向对象

面向对象:
 想吃烤羊排
 1. 去馕坑烤肉店
 2. 两个人点一斤羊排
 3. 等25分钟
 4. 吃
 5. 付款走人
面向过程:
 自己做烤羊排
 1. 从JD上买羊排,洋葱,大葱,姜,烧烤料,孜然粉,辣椒面
 2. 解冻羊排,准备辅料
 3. 切羊排,腌制,撒盐,腌制30分钟
 4. 烤箱预热5分钟,220度
 5. 烤制 25分钟 15分钟翻面
 6. 吃!!!蘸料~~~
 7. 收拾东西
从生活角度看面向对象:
	 找合适的人,做合适事
从生活角度看面向过程:
	 亲力亲为,自力更生,体验人生疾苦

2.2 类与对象

类:
 对于一类事物的统称,对当前事物的一些描述,属性描述和行为描述
对象:
 独立,唯一,特殊的个体

2.3 Java中定义类的格式

/*
class ClassName {
 // 属性描述
 // 行为描述
}
要求:
 1. ClassName要求符合大驼峰命名法,并且要做到见名知意!!!
 2. 属性描述,是用于描述当前类拥有的一些特征,这里可以使用变量
 该变量有一个特定的名字【成员变量】 Field
 3. 行为描述,是用于描述当前类可以做到一些事情,这里使用方法。
 该方法有一个特定的名字【成员方法】Method
*/

2.4 类对象使用

2.4.1 Java中创建类对象的形式

/*
new 对象!!!
*/
// 获取一个扫描器的类对象!!!
Scanner sc = new Scanner(System.in);
/*
java.util.Scanner : 
 数据类型,Scanner类型。创建的【变量】是Scanner的类对象,同时也是一个引用
 数据类型
sc : 
 类对象,变量
 Scanner的类对象,sc是对象名
/*
new 对象!!!
*/
// 获取一个扫描器的类对象!!!
Scanner sc = new Scanner(System.in);
/*
java.util.Scanner : 
 数据类型,Scanner类型。创建的【变量】是Scanner的类对象,同时也是一个引用
 数据类型
sc : 
 类对象,变量
 Scanner的类对象,sc是对象名
 总结:
 类名 对象名 = new 构造方法(所需参数);
*/
// 这里创建了一个Person类对象,对象名person                               
Person person = new Person();                               
System.out.println(person);                                 
/*                                                          
 * com.qfedu.a_object.Person@15db9742                       
 * com.qfedu.a_object 完整的包名                                 
 * Person 数据类型,这里创建的对象是一个Person类对象                      
 * @15db9742 当前类对象在内存空间的中首地址!!!十六进制展示方式           
 */        
Person person1 = new Person();                              
System.out.println(person1);                                
/*                                                          
 * com.qfedu.a_object.Person@6d06d69c                       
 * 发现第二个Person类对象 person1空间首地址6d06d69c 和第一个对象不一致     
 * 这里就意味着两个对象的空间首地址不一致,不是同一个对象!!!            
 */     

2.4.2 Java中使用类对象调用成员变量

/*
int[] arr = new int[10];
获取数组的容量:
 arr.length
 获取一个数组中【的】length属性
格式:
 对象名.属性名/成员变量名;
 . ==> 的
 可以操作取值或者赋值操作。
*/     

2.4.3 Java中使用对象调用成员变量

/*
得到了一个Scanner类对象sc
Scanner sc = new Scanner(System.in);
使用过以下方法:
 sc.nextInt();
 sc.nextFloat();
 sc.nextLine().charAt(0);
格式:
 类对象.方法名(必要的参数);
 . ==> 的
*/

2.5 自定义使用构造方法

构造方法功能:
 初始化当前类对象中保存的成员变量数据。
目前创建对象的方式;
 new 构造方法(有可能需要的参数);
new:
 1. 根据构造方法提供的数据类型申请对应的堆区内存空间。
 2. 擦除整个空间中所有的数据。
构造方法:
 初始化在当前内存堆区空间的成员变量对应的数据
格式:
 public 类名(初始化形式参数列表) {
  初始化赋值语句;
 }
要求:
 1. 无论什么时候一定要留有一个无参数构造方法备用
 2. 根据所需情况完成构造方法参数选择
 3. 一个class可以有多个构造方法【方法的重载】

2.6 方法重载

总结:
 1. 所有的方法名字都是一致的!!!
 2. 所有的方法参数都是不一样的!!!
 3. 同一个类内!!!
这就是方法的重载!!!
优点:
 1. 简化了开发压力
 2. 简化了记忆压力
 3. 更快捷的调用方法,同时又满足了不同的情况!!!
规范:
 重载情况下,在同一个类内,不可以出现相同方法名和相同参数数据类型的方法!!! 
基本原理:
 方法名一致的情况下,通过形式参数列表数据类型的不同来选择不同的方法执行。
 反射 ==>Constructor Method

2.7 this关键字

2.7.1 this关键字特征

package com.qfedu.a_object;
class SingleDog {
 public SingleDog() {
  System.out.println("Constructor : " + this);
 } 
 public void test() {
  System.out.println("Method Called : " + this);
 }
}
/*
 * this关键字特征:
 * this关键字表示调用当前方法的类对象,
 * 或者是当前构造方法中初始化的类对象
 */
public class Demo4 {
 public static void main(String[] args) {
  SingleDog singleDog = new SingleDog(); 
  System.out.println("Instance : " + singleDog);
  singleDog.test();
 }
}

2.7.2 解决就近原则

/**                                          
 * 使用String类型参数和int类型参数初始化类对象成员变量数据       
 *                                           
 * @param name String类型数据 用于初始化name属性        
 * @param age int类型数据 用于初始化age属性             
 */                                          
public Cat(String name, int age) {           
 name = name;                             
 age = age;                               
 System.out.println("带有两个参数的构造方法");       
}                                            
/*
我们期望使用比较直观的参数名方式,告知调用者这里需要的数据到底是什么?
但是会导致【就近原则】问题
 在构造方法中所有的name,age都会被看作是一个局部变量,而不是成员变量
期望:
 可以有一种参数方式告知编译器这里操作的是一个成员变量,而不是一个局部变量!!!
*/
--------------------------修改方式----------------------------
 /**                                             
 * 使用String类型参数和int类型参数初始化类对象成员变量数据       
 *                                              
 * @param name String类型数据 用于初始化name属性           
 * @param age int类型数据 用于初始化age属性                
 */                                             
public Cat(String name, int age) {              
 /*                                          
  * 使用this关键字明确告知编译器这里使用的是一个成员变量,而不是         
  * 局部变量,解决就近原则问题                            
  */                                         
 this.name = name;                           
 this.age = age;                                       
}  

2.8 成员变量和局部变量的对比

区别               
作用
属性描述,描述当前类拥有哪些属性(成员变量)
在方法运行的过程中保存必要的数据(局部变量)
位置
成员变量定义在class大括号以内,其他大括号之外(成员变量)
在方法大括号或者代码块大括号以内(局部变量)
初始值
成员变量在没有被构造方法赋值的情况下,是对应数据类型的"零"值未(成员变量)
赋值不能参与除赋值之外的其他运算。(局部变量)
作用域
成员变量存储于类对象中,在内存的堆区,哪里持有当前类对象的空间首地址,作用域就在哪里(成员变量)
有且只在当前大括号以内(局部变量)
生存期
成员变量的生存期是随着类对象的创建而开始,当对象被JVM的GC销毁时,成员变量的生存期终止(成员变量)
从定义位置开始,到当前大括号结束(局部变量)

补充知识点“零”值

new关键字申请内存空间,并且擦除的一干二净
对应每一个数据类型的"零"值
基本数据类型
 byte short int   0
 long             0L
 float            0.0F
 double           0.0
 char             '\0' ==> nul
 boolean          false
引用数据类型
 全部为null
 Person person  null
 String str     null
 int[] arr      null
null 
 是内存地址中非常特殊的东西!!!

JVM的GC机制

new关键字申请内存空间,并且擦除的一干二净
对应每一个数据类型的"零"值
基本数据类型
 byte short int   0
 long             0L
 float            0.0F
 double           0.0
 char             '\0' ==> nul
 boolean          false
引用数据类型
 全部为null
 Person person  null
 String str     null
 int[] arr      null
null 
 是内存地址中非常特殊的东西!!!

二分法查找

特征:
 1. 要求查询的数组必须是一个经过排序之后的数组
 2. 多个指定数据的情况下,无法告知到底是第几个数据出现
 3. 没有找到数据返回负数
演示:
 1 3 5 7 9 11 13 15 17 19
例如:
 查询元素 13的下标位置
 第一步:
  中间下标元素是 下标为4 元素值=9 
  最小下标为0
  最大下标为9
  9 < 13 
  需要修改最小下标 ==> 中间下标 + 1 ==> 5
 第二步:
  中间下标元素是 下标为7 元素值=15
  最小下标为5
  最大下标为9
  15 > 13
  需要修改最大下标 ==> 中间下标 - 1 ==> 6
 第三步:
  中间下标元素是 下标为5 元素值=11
  最小下标为5
  最大下标为6
  11 < 13 
  需要修改最小下标 ==> 中间下标 + 1 ==> 6
 第四步:
  得到结果

三,面向对象三大特征

封装,继承,多态

1 封装

方法的封装
工具类的封装
框架的封装
需要拥有封装的思想!!!可以用于整合的知识点!!!
一段代码,你写了三遍 ==> 封装成方法
一堆方法,你用了三遍 ==> 封装成工具类
一个工具类,你使用了三遍 ==> 写好对应的注释,完成对应的API
一个类注释自己修改了三遍,==> 写成博客

2 符合JavaBean规范的类封装过程

代码规范非常重要
 后期可以有效的提供我们的开发效率!!!
在Java中定义符合JavaBean规范的类有什么要求
 1. 所有的成员变量全部私有化 ==> private
 2. 必须提供一个无参数构造方法
 3. 要求使用private修饰的成员变量提供对应的操作方法 ==> Setter Getter

3 private关键字

private关键字是一个权限修饰符
 private修饰的成员变量,成员方法,【构造方法】都是私有化内容,有且只能在类内使用,类外没有任何的操作权限!!!

4 Setter和Getter方法

private修饰的成员变量类外是没有任何操作权限,这里需要提供对应的操作方法,setter和getter方法
Setter方法格式:
 public void set成员变量名(对应成员变量的数据类型 成员变量的形式参数) {
  this.成员变量名 = 成员变量的形式参数;
 } 
 例如:
 public void setName(String name) {
  this.name = name;
 }
Getter方法格式:
 public 对应成员变量的数据类型 get成员变量名() {
  return 成员变量;
 }
 例如:
 public String getName() {
  return name;
 }
如果成员变量是一个boolean类型,Getter方法有所不同
 boolean married;
 格式:
  public boolean isMarried() {
   return married;
  }

5 匿名对象

Factory factory = new Factory();                              
// 通过修理店对象,调用修理电脑的方法                  
// 需要的参数是Computer类对象                  
factory.repair(computer);       
/*
Factory类对象
 1. 有且只使用了一次
 2. 该对象中的设置操作是没有什么作用的
问题:
 1. 代码操作感觉不方便
 2. 浪费时间浪费资源,内存资源,JVM效率问题
*/
匿名对象:
 new 构造方法(必要的参数);
匿名对象的用途:
 1. 使用匿名对象直接调用类内的成员方法
 2. 匿名对象直接作为方法的参数
注意:
 使用匿名对象不要操作成员变量,有可能是有去无回
优势:
 1. 阅后即焚,匿名对象在使用之后 立即被JVM GC收回
 2. 解决内存空间,提高效率,简化代码书写

6 Java中实现继承的方法

继承使用的关键字
 extends
格式:
 class A extends B {
 }
 A类是B类的一个子类
 B类是A类的唯一父类
 Java中的继承是一个单继承模式
基本要求:
 1. 子类继承父类之后,可以使用父类的非私有化成员变量和成员方法
   【非私有化成员】
 2. 子类不能继承得到父类的私有化内容。

6.1 为什么会自动执行父类的无参数构造方法

这里有一个super关键字
 1. 调用父类成员方法和成员变量的关键字。
  [解决就近原则问题]
 2. 用于显式调用父类的构造方法。
super关键字调用父类的构造方法
 super(实际参数);
 Java编译器会根据实际参数的数据类型,参数顺序,选择对应的父类构造方法执行,初始化父类的成员空间,方法重载机制。
特征:
 1. 如果没有显式调用父类的构造方法,默认Java编译器会调用无参父类构造方法使用
 2. 根据数据类型选择对应方法
 3. super调用构造方法,必须在当前构造方法的第一行

7 方法的重写

 解决的问题就是在开发中,父类的方法不适用于子类情况,子类可以重写父类的方法,完成自定义的方法使用
 重写之后,在没有增加新的方法名的情况下,重写方法体内容,让方法满足子类,降低了开发压力,提高了效率。
@Override
 严格格式检查
 要求重写方法的和父类中的方法,声明完成一致,返回值类型,方法名和形式参数列表

8 abstract关键字

abstract使用总结:
 1. abstract修饰的方法没有方法体
 2. abstract修饰的方法必须定义在abstract修饰的类内或者interface接口内
 3. 一个普通类【非abstract】修饰的类,继承了一个abstract类,那么必须实现在abstract类内的所有abstract,强制要求
 4. 如果一个abstract A类继承另一个abstract B类,A类可以选择实现B类中abstract方法。
 5. abstract修饰的类内允许普通方法
 6. abstract修饰的类不能创建自己的类对象!!!
 【原因】
  abstract修饰的类内有可能存在abstract修饰的方法,而abstract修饰的方
  法是么有方法体的,如果说创建了abstract修饰类对应的对象,不能执行没
  有方法体的abstract方法
 7. 一个类内没有abstract修饰的方法,那么这个类定义成abstract类有意义吗?
 没有必要的!!!无意义的!!!

9 final关键字

final修饰的成员变量
	 final修饰的成员变量定义时必须初始化,并且赋值之后无法修改,一般用于类内带有名字的常量使用
final修饰的成员方法
	 final修饰的成员变量不能被子类重写,为最终方法,可以用于一些安全性方法的定义
final修饰的局部变量
	 final修饰的局部变量一旦被赋值,不能修改!
final修饰的类
	 final修饰的类没有子类,不能被继承。
	 abstract修饰的类不能被final修饰。

10 static关键字

10.1 静态成员变量使用注意事项

1. 静态成员变量是使用static修饰的成员变量,定义在内存的【数据区】
2. 静态成员变量不推荐使用类对象调用,会提示警告
 The static field SingleDog.info should be accessed in a static way
 使用static修饰的SingleDog类内的info成员变量,应该通过静态方式访问
3. 静态成员变量使用类名调用是没有任何的问题。【墙裂推荐方式】
4. 在代码中没有创建对象时,可以通过类名直接使用静态成员变量,和【对象无关】
5. 代码中对象已经被JVM的GC销毁时,依然可以通过类名调用静态成员变量,和【对象无关】
6. 不管通过哪一种方式调用静态成员变量,修改对应的静态成员变量数据,所有使用到当前静态成员变量的位置,都会受到影响。

10.2 为什么静态成员变量和对象无关

1. 从内存角度出发分析
 静态成员变量是保存在内存的数据区
 类对象占用的实际内存空间是在内存的堆区
 这两个区域是完全不同的,所有可以说静态成员变量和对象没有关系 【没有对象】
2. 从静态成员变量以及类对象生命周期来分析
 静态成员变量是随着类文件(.class) 字节码文件的加载过程中,直接定义在内存的数据区。静态成员变量从程序运行开始就已经存在。
 类对象是在代码的运行过程中,有可能被创建的。程序的运行过中,有可能会被JVM的CG垃圾回收机制销毁,程序在退出之前一定会销毁掉当前Java程序使用到的所有内存。
 静态成员变量在程序退出之后,才会销毁 
 静态成员变量的生命周期是从程序开始,到程序结束
 类对象只是从创建开始,而且随时有可能被JVM的GC销毁
 生命周期不在同一个时间线上,所以静态成员变量和类对象无关,【没有对象】

10.3 静态成员方法注意事项

1. 静态成员方法推荐使用静态方式调用,通过类名调用【墙裂推荐的】
 不推荐使用类对象调用,因为【没有对象】
2. 静态成员方法中不能使用非静态成员 ==> (非静态成员方法和非静态成员变量) 
 因为【没有对象】
3. 静态成员方法中不能使用this关键字
 因为【没有对象】
4. 静态成员方法中可以使用类内的其他静态成员【难兄难弟】
5. 静态成员方法中可以通过new 构造方法创建对象
 单身狗可以找对象
 不能挖墙脚但是能自己找

10.4 静态成员方法特征解释

1. 静态成员方法加载时间问题
 静态成员方法是随着.class字节码文件的加载而直接定义在内存的【方法区】,而且此时的静态成员方法已经可以直接运行。可以通过类名直接调用,而此时没有对象存在。【没有对象】
2. 为什么静态成员方法不能使用非静态成员
 非静态成员变量和非静态成员方法时需要类对象调用的,在静态成员方法中,是可以通过类名直接执行的,而此时是【没有对象】的。
3. 为什么静态成员方法不能使用this关键字
 this关键字表示的是调用当前方法的类对象,但是静态成员方法可以通过类名调用,this不能代表类名,同时也是【没有对象】
4. 静态成员方法可以使用其他静态成员
 生命周期一致,调用方式一致

补充知识点 代码块

构造代码块
 初始化当前类的所有类对象,只要调用构造方法,一定会执行对应的构造代码块 
静态代码块
 初始化程序,只要类文件加载,静态代码块中所有内容全部执行 
局部代码块
 提高效率,解决内存,让JVM回收内存的效率提升。 
 for () {
  {
   int num
  }
 }
发布了6 篇原创文章 · 获赞 0 · 访问量 259

猜你喜欢

转载自blog.csdn.net/qq_39544980/article/details/104325996