Java程序设计

1 Java发展史(了解)
https://zhuanlan.zhihu.com/p/465034540#Java%E5%8F%91%E5%B1%95%E5%8F%B2
0.2 Java运行环境
安装教程
专业术语
jdk(java develope kid)java开发工具
jre(java run environment)java运行环境
jvm (java virtual machine)java虚拟机
JavaSE     java基础版     
JavaEE     java进阶版web模块
JavaME   java进阶版但是过时了 常用于遥控器等电子设备
使用java前的必备配置
package 包(目录,文件夹)
Class      类,Java源代码
open  打开
close 关闭
cancel 取消
root  权限
install  安装
software  软件
VM  虚拟机
https://blog.csdn.net/daiyi666/article/details/116333121
0.3 java开发工具
新手推荐
记事本 (纯手搓)
eclipse (免费、功能基本齐全)
官网
官网 Eclipse Downloads | The Eclipse Foundation
教程
https://blog.csdn.net/qq_45344586/article/details/123942685
掌握基本功
IDEA (资源丰富,符合人体工程学)
安装教程 
https://www.cnblogs.com/bsytz/p/15346827.html
0.4 注释
1、java中的注释的种类:
单行注释、多行注释、文档注释(java特有)
2、单行注释多行注释的作用:
①对程序的代码进行解释说明
②对程序进行调试
3、注意:
①单行注释和多行注释中声明的信息,不参与编译。换句话说,编译以后声明的字节码文件中不包含单行注释和多行注释中的信息
②多行注释不能嵌套使用
4、文档注释:
文档注释内容可以被JDK提供的工具Javadoc所解析,生成一套以网页文件形式体现的该程序的说明文档
javadoc -d mydoc -author comment.java
生成文档注释
// 单行注释
 
/*
   多行注释
*/
 
/**
*  文档注释
*  @author
*  @xxx
*/
0.5 标识符
标识符
1、什么是标识符?java中的变量、方法、类等要素命名时使用的字符序列,称为标识符。
技巧:凡是自己可以起的名字的地方都叫标识符。比如:类名、方法名、变量名、包名、常量名等
2、标识符的命名规则(必须遵守!!!否则,编译不通过)
>由26个英文字母大小写,0-9,_或$组成
>数字不可以开头
>不可以使用关键字和保留字,但能包含关键字和保留字。
>java中严格区分大小写,长度无限制。
>标识符不能包含空格
3、标识符命名规范
>包名:多单词组成时所有字母都小写
>类名、接口名:多单词组成时,所有单词的首字母都要大写
>变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始时首字母大写
>常量名:所有字母都大写。多单词时每个单词用下划线连接
说明:大家在定义标识符时,要注意“见名知意”
一、顺序结构
1.1 常量和变量
常量
Java中不可以改变的量就是常量,使用final关键字来定义的常量叫做符号常量
常量也有划分:
整型常量:二进制(0b开头,如 0b123)、八进制(0开头,如 0123)、十进制(阿拉伯数字,如 123)、十六进制(0x开头,如 0x123)
实型常量:单精度常量(数据最后带f或F,如 3.14f)和双精度常量(如 3.14)
字符型常量:使用单引号定界符,如 'b'
逻辑型常量:true 和 false
字符串常量:使用双引号定界符,如 "java"
注意:
① 必须在常量声明时候对其初始化
② final表示最终的,不能再被改变
③ 符号常量通常用大写字母表示
变量
1、变量的理解:内存中的一个储存区域,该区域的数据可以在同一类型的范围内变化不断
2、变量的构成包含三个要素:数据类型、变量名、储存的值
3、java中变量声明的格式:数据类型 变量名 = 变量值;
4、定义变量时,变量名要遵循标识符命令的规则和规范。
5、说明:
①变量都有其作用域。变量只在作用域内是有效的,出了作用域就失效了。
②在同一个作用域内,不能声明两个同名的变量
③定义好变量以后,就可以通过变量名的方式对变量进行调用和运算。
④变量值在赋值时,必须满足变量的数据类型,并且在数据类型有效的范围内变化
1.2 数据类型 
java中的变量按照数据类型来分类:
基本数据类型(8种):
整型:byte,short,int,long
浮点型:float,double
字符型:char
布尔型:boolean
引用数据类型:
字符串 (String)
类(class)
数组(array)
接口(interface)
枚举(enum)
注解(annotation)
记录(record)
1.3 类型转换
1、运算不包含Boolean类型
2、运算规则包括:
   ①自动类型提升
   ②强制类型转换
3、测试自动类型提升
规则:当容量小的变量与容量大的变量做运算时,结果自动转换为容量大的数据类型
   byte-->short-->int-->long-->float-->double
   特别的:byte、short、char类型的变量之间做运算,结果为int类型
说明:此时的容量小或者大,并非指占用的内存空间的大小,而是指表示数据的范围的大小
整型常量,规定是int类型
浮点型常量,规定是double类型
为什么变量不允许数字开头,为了“自洽”
规则:
1、如果需要将容量大的变量的类型转换为容量小的变量的类型,需要使用强制类型转换
2、强制类型转换需要使用强转符:()。在()内指明要转换为的数据类型。
3、强制类型转换过程中,可能导致精度损失。
1.4 运算符和表达式
算术运算符
+ - * / % (前)++ (后)++ (前)-- (后)-- ++
String连接符,String与其他类型的变量间的运算,运算结果也是String类型
基本数据类型与String的运算
关于String的理解
1、String类,属于引用数据类型,俗称字符串。
2、String类型的变量,可以使用一对""的方式进行赋值。
3、String声明的字符串内部,可以包含0个,1个或多个字符。
String与基本数据类型变量间的运算
1、这里的基本数据类型包括Boolean在内的8种。
2、String与基本数据类型变量间只能做连接运算,使用“+”表示。
3、运算的结果是String类型
位运算符
1、<<  >>  >>>  &  |  ^  ~
2、说明:
①<<  >>  >>>  &  |  ^  ~:针对数值类型运算结果也是数值类型
②<<:在一定范围内,每向左移一位,结果就在原有的基础上*2(正负都可以)
③>>:在一定范围内,每向右移一位,结果就在原有的基础上/2(正负都可以)
④&:与,两个1才为1,否则为0
⑤|:或,有1则为1
⑥^:异或,相反为1
⑦~:非,0为1,1为0
赋值运算符
1、=、+=、-=、*=、/=、%=
2、
① 当“=”两侧数据类型不一致时,可以使用自动类型转换或强制类型转换原则进行处理。
② 支持连续赋值
③ +=、-=、*=、/=、%= 操作,不会改变变量本身的数据类型。
1.5 顺序结构编程思想
思路:定义变量、输入、处理、输入
Java的输入输出
输入
Scanner 变量名 = new Scanner(System.in);
如 变量名.nextInt()等,可以输入int、float、double、字符串等数据类型
输入一个英文字母可以使用System.in.read();方法实现
输出
① System.out.println(); 可以换行输出括号里的内容
② System.out.print(); 可以在一行内输出括号里的内容
③ System.out.printf("%s:%",name,age); 格式化输出
二、选择结构
2.1 关系运算符和逻辑运算符
关系运算符
1、==、!=、<、>、<=、>=、instanceof
2、说明
①instanceof 在面向对象多态性中
②==、!=、<、>、<=、>= 适用于除Boolean类型之外的其他7种基本数据类型
运算结果为boolean类型
③==、!= 可以适用于引用数据类型,boolean数据类型
④区分= 和==
逻辑运算符
1、&、&&、|、||、!、^
2、说明
①逻辑运算符针对的都是Boolean类型的变量进行的操作
②逻辑运算符运算的结果也是Boolean类型
③逻辑运算符常使用条件、判断、循环结构中
2.2 条件运算符
1、(条件表达式)?表达式1:表达式2
2、说明
①条件表达式的结果是boolean类型
②如果条件表达式的结果是true,则执行表达式1,如果是false,则执行表达式2
③表达式1和表达式2需要是相同的类型或兼容类型
2.3 运算符优先级(了解)
https://blog.csdn.net/PursueLuo/article/details/108807576
优先级不够时,使用括号()来提升
2.4 if语句
分支结构1:if-else条件判断语句
1、格式
格式1:
if(条件表达式){
   语句块;
}
格式2:
if(条件表达式){
   语句块1;
}else{
   语句块2;
}
格式3:
if(条件表达式1){
   语句块1;
}else if(条件表达式2){
   语句块2
}
...
else if(条件表达式n){
   语句块n;  
}
else{
   语句块n+1;
}
2.5 switch语句
分支结构之Switch-case的使用
1、语法格式
switch(表达式){
   case 常量1:
   执行语句;
   break;
   case 常量2:
   执行语句;
   break;
   ...
   default
   执行语句;
   break;
}
2、执行流程
依次匹配case值,碰到相等的直接执行,break跳出;没有符合条件default执行,break跳出。
3、说明
①switch中的表达式只能式特定的数据类型
byte、short、char、int、枚举(JDK5.0新增)、String(JDK7.0新增)
②case后都是跟的常量,使用表达式与这些常量做相等判断,不能做范围判断
③开发中,使用switch-case时,通常case匹配的情况都是有限的
④break 执行跳出switch-case语句
⑤default 是可选的位置灵活
4、switch-case 与 if-else之间的转换
①可以使用switch-case结构都可以使用if-else
②能使用switch-case尽量使用,效率稍高,穿透性
三、循环结构
3.1 while循环和do...while循环
循环结构之一:while循环
1、凡是循环结构,就一定会有4个要素
①初始化条件
②循环条件  变量或表达式为boolean
③循环体
④迭代部分
2、while的格式

while(②){


}
执行过程:①→②→③→④→②→③→...→②
for和while可以相互转换
循环结构之一:do-while循环
1、凡是循环结构,就一定会有4个要素
①初始化条件
②循环条件  变量或表达式为boolean
③循环体
④迭代部分
2、while的格式

do{


}while(②);
执行过程:①→③→④→②→③→④...→②
3、说明:
①do-while循环至少执行一次循环体
②三循环可以相互转换
③开发中,do-while结构使用少
3.2 for循环
循环结构之一:for循环
1、java中规范了3种循环结构:for、while、do-while
2、凡是循环结构,就一定会有4个要素
①初始化条件
②循环条件  变量或表达式为boolean
③循环体
④迭代部分
3、for循环的格式
for(①;②;④){
   ③;
}
   
执行过程:①→②→③→④→②→③→...→②
“无限”循环的结果的使用
1、格式:while(true)或for(;;)
嵌套循环的使用
1、嵌套循环:是指一个循环结构A的循环体是另一个循环结构B
-外层循环:循环结构A
-内层循环:循环结构B
2、说明:
①内层循环充当外层循环的循环体
②两层嵌套循环,外层循环控制行数,内层循环处理列数
③外层执行m次,内层循环执行n,内层循环的循环体执行m*n次
④实际开发基本不会出现三层循环,三层的循环结构少见
                   //菱形    
//上半部分
        for(int i=1;i<=5;i++){
            for(int j=1;j<=10-2*i;j++){                                        System.out.print(" ");            
            }
            for(int k=1;k<=2*i-1;k++){                                        System.out.print("* ");            
            }
            System.out.println();
        }
//下半部分
        for(int i=4;i>=1;i--){
            for(int j=1;j<=10-2*i;j++){                                        System.out.print(" ");            
            }
            for(int k=1;k<=2*i-1;k++){                                        System.out.print("* ");            
            }
            System.out.println();
        }

3.3 跳转语句

3.4 Scanner基本使用

如何从键盘获取不同类型(基本数据类型、String类型)的变量:使用Scanner类

1、使用Scanner获取不同类型数据的步骤
步骤1:导包 import java.util.Scanner;
步骤2:提供(或创建)一个Scanner类的实例 

Scanner sc = new Scanner(System.in);//sc为类名自定义

步骤3:调用Scanner类中的方法,获取指定类型的变量

int num = sc.nextInt();//使用int类型接收数据,还可以使用其它类型

步骤4:关闭资源,调用Scanner类的close();方法
四、数组

4.1 一维数组

1、数组的概念(Arrays)

概念:多个相同类型数据按一定数据按一定顺序排列的组合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理

简称:多个数据组合

java中的容器:数组、集合框架:在内存中对多个数据储存

2、几个相关概念
>数组名
>数组的元素(即内部储存的多个元素)
>数组的下标、角标、下角标、索引、index(即找到指定数组元素所使用的编号)
>数组长度(即数组容器中储存的元素个数)

3、数组的特点:
>数组中的元素在内存中是依次紧密排列的、有序的。
>数组属于引用数据类型的变量,数组元素既可以是基本数据类型也可以是引用数据类型
>数组,一旦初始化完成,其长度不可改变
>创建数组对象会在内存中开辟一整块“连续的空间”。占据的空间的大小,取决于数组的长度和数组中元素的类型。

复习:变量按照数据类型分类

4.1 基本数据类型:byte、short、int、long、float、double、char、Boolean

4.2 引用数据类型:类、数组、接口、枚举、注解、记录

5、数组的分类

5.1 按照元素的类型:基本数据类型元素的数组,引用数据类型元素的数组

5.2 按照数组的维数来分:一维数组、二维数组

6、一维数组的使用(6个基本点)
>数组的声明和初始化
>调用数组的指定元素
>数组的属性:length,表示数组的长度
>数组的遍历
>数组的默认初始化值
>一维数组的内存解析

7、数组元素的默认初始化值的情况
注意:以数组的动态初始化方式为例
>整数型数组元素的默认初始化值:0
>浮点型数组元素的默认初始化值:0.0
>字符型数组元素的默认初始化值:0或'\u0000'
>布尔型数组元素的默认初始化值:false
>引用型数组元素的默认初始化值:null

8、一维数组的内存解析
8.1 java中的内存结构是如何划分的?(主要关心JVM运行时的内存环境)
>将内存区域划分为5个部分:程序计数器、虚拟机栈、本地方法栈、堆、方法区
>与目前数组相关的结构:比如:int[] arr = new int[]{1,2,3};
    >虚拟机栈:用于存放方法中声明的变量。比如:arr
    >堆:用于存放数组的实体(即数组中的所有元素)。比如:1,2,3

栈(stack) 堆(heap)
基本使用
        //1.数组的声明和初始化
        //复习:变量的定义格式:数据类型 变量名 = 变量值;
        int num1= 10;
 
        //声明数组
        double[] prices;
        //数组的初始化
        //静态初始化:数组变量的赋值与数组元素的赋值操作同时进行
        prices = new double[]{20.32,43.21,43.22};
 
        //数组声明和初始化
        //动态初始化:数组变量的赋值与数组元素的赋值操作分开进行
        String[] foods = new String[4];
 
        //其它正确方式
        int arr[] = new int[]{1,2,3,4};
        //类型推断
        int arr1[] = {1,2,3};
 
        //2.数组元素的调用
        //通过角标的方式,获取数组的元素
        //角标范围从0到数组长度-1
        System.out.println(prices[0]);
        System.out.println(prices[2]);
        //System.out.println(prices[3]);数组越界:ArrayIndexOutOfBoundsException
 
        foods[0] = "拌海蜇";
        foods[1] = "龙须菜";
        foods[2] = "炝冬笋";
        foods[3] = "玉兰片";
 
        //3.数组长度:用来描述数组容器中容量的大小
        //使用length属性表示
        System.out.println(prices.length);
        System.out.println(foods.length);
 
        //4.如何遍历数组
        for (int i = 0; i < foods.length-1; i++) {
            System.out.println(foods[i]);
        }
4.2 二维数组

1、二维数组的理解

- 对于二维数组的理解,可以看成一个一维数组又作为另一个一位数组的元素存在。
- 其实,从底层运行机制来看,没有多维数组。

2、二维数组的使用(6个基本点)

>二数组的声明和初始化
>调用二数组的指定元素
>二数组的属性:length,表示数组的长度
>二数组的遍历
>二数组的默认初始化值
>二维数组的内存解析

3、二维数组元素的默认初始化值

3.1 动态初始化方式1:(比如:int[][] arr = new int[3][4];)

外层元素,默认储存地址值
内层元素
>整数型数组元素的默认初始化值:0
>浮点型数组元素的默认初始化值:0.0
>字符型数组元素的默认初始化值:0或'\u0000'
>布尔型数组元素的默认初始化值:false
>引用型数组元素的默认初始化值:null


3.2 动态初始化方式2:(比如:int[][] arr = new int[3][];)

外层元素,默认储存null
内层元素,不存在的。如果调用报错(NullPointerException)
基本使用
        //1.数组的声明和初始化
        //复习:
        int arr1[] = new int[]{1,2,3};
 
        //声明数组
        //数组的初始化
        //静态初始化:数组变量的赋值与数组元素的赋值操作同时进行
        int arr2[][] = new int[][]{{1,2,3},{4,5},{6}};
 
        //数组声明和初始化
        //动态初始化:数组变量的赋值与数组元素的赋值操作分开进行
        String[][] arr3 = new String[4][3];
        //动态初始化2:
        double[][] arr4 = new double[4][];
 
        //其它正确方式
        int[][] arr5 = new int[][]{{1},{2}};
        int[] arr6 []= new int[][]{{1},{2}};
        //类型推断
        int[][] arr7 ={{1},{2}};
 
        //2.数组元素的调用
        //通过角标的方式,获取数组的元素
        //角标范围从0到数组长度-1
        //  针对arr2来说,外层元素:{1,2,3},{4,5,6},{7,8,9},内层元素:123456789
        //调用内层元素
        System.out.println(arr2[0][0]);//7
        //调用外层元素
        System.out.println(arr2[0]);//[I@1b6d3586
 
        //测试arr3、arr4
        arr3[0][0]="tom";
        System.out.println(arr3[0][0]);//tom
        System.out.println(arr3[0]);//[Ljava.lang.String;@4554617c
 
        arr4[0] = new double[4];
        arr4[0][0] = 1.0;
 
        //3.数组长度:用来描述数组容器中容量的大小
        //使用length属性表示
        System.out.println(arr2.length);//根据外层长度(元素个数)判断
        System.out.println(arr2[0].length);//3
        System.out.println(arr2[1].length);//2
        System.out.println(arr2[2].length);//1
 
        //4.如何遍历数组
        for (int i = 0; i < arr2.length; i++) {
            for (int j = 0; j < arr2[i].length; j++) {
                System.out.print(arr2[i][j] + "\t");
            }
            System.out.println();
        }
五、方法

1、方法的声明语法
方法是为了完成一个功能而组合在一起的语句块
方法的声明由方法名、参数、返回值类型及函数体组成。声明如下:
修饰符 返回值类型 方法名(参数列表)[throws 异常列表]{
               //方法体 
}
方法头:定义方法的访问特性(如:public)、使用特性(如:static)、返回值类型、方法名称、参数和抛出异常等
 
方法的返回值
通过return语句将方法的结果返回给调用者,return语句返回的值类型和函数头中声明的返回值类型要一致,void类型没有返回值
方法的参数
方法头中的变量称形式参数简称形参,方法可以不包含参数,没有参数的方法称为无参方法
2、方法的调用
方法名(实际参数值); 无参方法直接调用,不用传参
方法的参数传递
如果参数是基本数据类型,实参单元和形参单元存储的均为数据本身。参数传递就是将实参单元的数据复制给形参单元,在方法内修改形参的值,不影响实参
如果参数是数组或对象,则参数单元存放的是引用地址,也就是将实参单元存放的地址复制给形参单元,实参和形参将指向同一数据或对象。对形参数组或对象的操作访问,实际上是对实参数组或对象的操作访问。因此,在方法内修改参数的内容将影响实参 
3、递归调用
递归就是方法调用自身,这个过程称为递归,调用自己的方法称为递归方法
递归的两个基本要素
边界条件,显示确定递归到何时终止,也称为递归出口
递归模式,显示大问题是如何分解为小问题,也称为递归体
六、初识面向对象

1.面向对象内容的三条主线
- Java类及类的成员:(重点)属性、方法、构造器;(熟悉)代码块、内部类
-面向对象的特征:封装 、继承、多态、(抽象)
-其他关键字的使用:this、super、package、import、static、final、interface、abstract等

2.面向过程编程(POP) VS 面向对象编程(OOP)

2.1 简单的语言描述二者区别

>面向过程(Process-Oriented Programming):
        -以函数为组织单位
        -是一种执行者思维,适合解决简单问题。扩展能力差、后期维护难度较大

>面向对象(Object Oriented Programming):
        -以类为组织单位。每种事物都具备自己的属性和行为/功能。
        -是一种设计者思维。适合解决复杂问题。代码扩展性强、可维护性高

2.2 二者关系
相辅相成

3.
>面向对象的两个概念:
    类:具有相同特征的事物的抽象描述,是抽象的、概念上的定义。
    对象:实际存在的该类事物的每个个体,是具体的,因而也称为实例(instance)。
>谈谈对这两个概念的理解?

4. 类的声明和使用
4.1 体会:设计类,其实就是设计类的成员
class person{

}

4.2 类的内部成员一、二
成员之一:属性、成员变量、field(字段、域)
成员之二:(成员)方法、函数、method

4.3 类的实例化
等价描述:类的实例化 <=> 创建类的对象 <=> 创建类的实例
格式:类类型 对象名 = 通过new创建的对象实体
举例:
Phone p1 = new Phone();
Scanner sc = new Scanner(System.in);
String str = new String();

5. 面向对象完成具体功能的操作的三步流程(非常重要)
步骤1.创建类,并设计类的内部成员(属性、方法)
步骤2.创建类的对象。比如:Phone p1 = new Phone();
步骤3.通过对象,调用其内部声明的属性或方法,完成相关功能
类的成员之一:属性

1.变量的分类
-角度一:按数据类型来分:基本数据类型(8种)、引用数据类型(数组、类、接口、枚举、注解、记录)
-角度二:按照变量在类中声明的位置的不同:成员变量(属性)、局部变量(方法内、方法形参、构造器内、构造器形参、代码块内等)

2.属性的几个称谓:成员变量、属性、field(字段、域)

3.区分成员变量 VS 局部变量
3.1 相同点
>变量声明的格式相同:数据类型 变量名 = 变量值
>变量都有其作用域。出了作用域就失效了。
>变量必须先声明后赋值

3.2 不同点:
①类中声明的位置不同
    属性:声明在类内,方法外的变量
    局部变量:声明方法、构造器内部的变量

②在内存中分配的位置不同(难点):
    属性:随着对象的创建,存储在堆空间
    局部变量:存储在栈空间

③生命周期:
    属性:随着对象的创建而创建,随着对象的消亡而消亡。
    局部变量:随着方法对应的栈针入栈,局部变量会在栈中分配;随着方法对应的栈针出栈,局部变量消亡。

④作用域:
    属性:在整个类的内部都是有效的
    局部变量:仅限于声明此局部变量所在的方法(或构造器、代码块)中

⑤是否可以有权限修饰符进行修饰:(难)
    都有哪些权限修饰符:public、protected、缺省、private。(用于表名所修饰的结构可调用的范围的大小)

    属性:可以使用权限修饰符进行修饰
    局部变量:不能使用任何权限修饰符进行修饰

⑥是否有默认值:
    属性:都有初始化默认值
    如果调用之前没有初始化,使用默认初始化值

    局部变量:都没有默认初始化值
    如果调用之前没有初始化值,直接报错,使用前必须赋值
    注意:对于方法的形参,在调用方法时,给形参赋值即可
类的成员之二:方法(method)

1、使用方法的好处

方法的理解:‘方法’是类或对象行为特征的抽象,用来完成某个功能操作
方法的好处:实现代码重用,减少冗余,简化代码

2、使用举例

-Math.random()的random()方法
-Math.sqrt()的sqrt()方法
-System.out.println()println()方法
-new Scanner(System.in) .nextInt()方法
-Arrays类中的binarySearch()方法、equals()方法

3、声明举例
    public void eat()
    public void sleep(int hour)
    public String interests(String hobby)

4、方法声明格式

权限修饰符[其他修饰符] 返回值类型 方法名(形参列表)[异常类型]{
    //方法体
}

注:[]中的不是必须的

5、具体的方法声明的细节

5、1权限修饰符
    java规定的修饰符 有四种:private\缺省\protected\public

5、2返回值类型:描述调用完此方法时,是否需要返回一个结果
       分类:
       >无返回值类型,使用void表示即可
       >有返回值类型,使用基本数据类型或引用数据类型表示即可
            >需要使用return + 返回值类型的变量或常量

5、3方法名:属于标识符。需要满足标识符的规定和规范。“见名知意”

5、4形参列表:形参,属于局部变量。
        格式:(形参类型1,形参1,形参类型2,,形参2,...)
        分类:无形参列表,有形参列表
        >无形参列表,不能省略()
        >有形参列表,根据方法调用需要不确定变量的类型和个数,确定形参的类型和个数

5.5方法体:当我们调用一个方法时,真正执行的代码。体现了此方法的功能

6、注意点
>java方法‘不能独立存在’,所有方法必须定义在类里
>java方法不调用不执行,每调用一次,执行一次
>java方法内可以调用本类中的(其它)方法或属性,方法内不能定义方法

7、关键字:return
7.1return的作用
    -作用1:结束一个方法
    -作用2:结束一个方法的同时,可以返回数据给方法的调用者

7.2注意点
    return后面不能声明执行语句

方法调用内存解析:
-形参:方法在声明时,一对()内声明一个或多个形式参数,简称为形参
-实参:方法被调用时,传递给形参的变量或常量,称为实参

过程概述:main方法进栈成栈针 → 生成 类 → 赋值 → 调用方法 方法调用完后出栈 → 执行 main方法 执行完成后 → 垃圾回收
类的成员之三:构造器(constructor)

1.构造器的理解
constructor:建造、构造、建设

2.构造器的作用
作用1:搭配new关键字,创建类对象
作用2:在创建对象的同时,可以给对象的相关属性赋值

3.构造器的使用说明
-构造器的声明格式:权限修饰符 类名(形参列表){}
-创建类以后,在没有显示提供任何构造器的情况下,系统默认提供一个空参的构造器
 ,且构造器的权限 与类声明的权限相同。
-如果类中显示声明构造器,系统不在提供默认的空参的构造器
-一个类中可以声明多个构造器,彼此之间构成重载

6.1 封装性

面向对象特征之一:封装性

1.为什么需要封装?
理论上:
    -高内聚:类的内部数据操作细节自己完成,不允许外部干涉
    -低耦合:仅暴露少量的方法给外部使用,尽量方便外部调用

通俗的说:把该隐藏的隐藏起来,该暴露的暴露出来。

2.如何实现数据封装?

2.1 权限修饰符
    java规定了4种权限修饰符,分别是:private、缺省、protected、public
    本类内部(private)、本包内(缺省)、其他包的子类(protected)、其他包非子类(public)
    每一个修饰符所在位置,包含前一个的范围

2.2 作用
    我们可以使用4种权限修饰符来修饰类及类的内部成员。当这些成员被调用时,体现可见性的大小

2.3 实际案例:
    在题目中给Animal的对象legs属性赋值。在实际常识中,legs不能为负数,如果直接调用属性legs
    不能加入判断逻辑,解决如下:
    -将legs属性私有化(private),禁止在Animal类的外部直接调用此属性
    -提供legs属性赋值的setLegs()方法,在此方法中加入legs属性赋值的判断逻辑if(legs >= 0 && legs % 2 == 0)
     将此方法暴露出去,使得在Animal类的外部调用此方法,对legs赋值
    -提供legs属性获取的getLegs()方法,此方法对外暴露,使得在Animal类的外部还可以调用此属性的值

2.4 4种权限具体使用
    -类:只能使用public、缺省修饰
    -类的内部成员:可以使用4种修饰符

2.5 开发中4种权限修饰符的使用情况
    比较高:public、private
    比较低:缺省、protected

3 封装性的体现
-场景一:私有化(private)类的属性,提供公共(public)的get和set方法,对此属性进行获取或修改
-场景二:将类中不需要对外暴露的方法,设置private
-场景三:单例模式中构造器private,避免在类的外部创建实例
this关键字的使用

1.目前可能出现的问题?以及解决方案?
当声明一个属性对应的SetXxx方法时,通过形参给对应的属性赋值。如果形参名和属性名同名,如何在方法中区分变量?

解决方案:使用this。使用this修饰的变量,表示属性,没有this修饰的变量,表示形参

2.this可以调用的结构:成员变量、方法、构造器

3.this的理解:当前对象(方法调用时)或当前正在创建的对象(在构造器调用时)

4.1 this调用属性和方法
针对于方法内的使用情况(非static修饰的方法):

一般情况:我们通过对象a调用方法,可以在方法内调用当前对象a的属性或其他方法。此时,我们可以在属性和其他方法前使用“this.”,
表示当前属性或方法所属的对象a。但是,一般情况下,我们都选择省略次“this.”结构

特殊情况:如果方法的形参与对象属性同名了,我们必须使用“this.”进行区分。使用this.修饰的变量即为属性(或成员变量)
没有使用this.修饰的变量,即为局部变量

针对于构造器内的使用情况:

一般情况:我们通过构造器创建对象时,可以在构造器内调用当前正在创建的对象的属性或方法。此时,我们可以在属性和方法前使用“this.”,
表示当前属性或方法所属的对象a。但是,一般情况下,我们都选择省略次“this.”结构

特殊情况:如果构造器的形参与正在创建的对象的属性同名了,我们必须使用“this.”进行区分。使用this.修饰的变量即为属性(或成员变量)
没有使用this.修饰的变量,即为局部变量

4.2 this调用构造器
-格式:“this(形参列表)”
-我们可以在类的构造器中,调用当前类中指定的其它构造器
-要求:“this(形参列表)”必须声明在当前构造器的首行
-结论:“this(形参列表)”在构造器中最多声明一个
-如果一个类中声明了n个构造器,则最多有n-1个构造器可以声明有“this(形参列表)”的结构
6.2 继承性

面向对象特征之二:继承性

1.继承性的理解
-生活上:财产、血缘的继承
-代码层面
    -自上而下:定义一个A类,在定义另一个B类时,发现B类的功能与A类相似,考虑B类继承于A类
    -自下而上:定义了类B、C、C等,发现B、C、D有类似的属性和方法,则可以考虑将相同的属性和方法进行抽取,
     封装到A类中,让类B、C、D继承于类A,同时类B、C、D中的相似的功能就可以删除了

2.继承性的好处
-继承的出现减少了代码的冗余,提高了代码的复用性
-有利于功能的扩展
-继承的出现让类与类之间产生了‘is-a’的关系,为多态提供了前提
-继承描述事物之间的所属关系‘is-a',父类更通用、一般,子类更具体

3.继承性的格式
class A{

}

class B extends A{

}

继承中的基本概念
-类A:父类、supperClass、超类、基类
-类b:子类,subClass、派生类

4.有了继承性以后
-子类获取父类中声明的所有属性和方法
-由于封装性的影响,可能子类不能直接调用父类中声明的属性或方法
-子类在继承父类以后,还可以扩展自己特有的功能(体现:增加特有的属性、方法)
 extends:延展、扩展,延伸
-继承之前,判断一下是否有is a的关系
-子类和父类,要区分集合和子集

5.默认的父类
java中声明的类,如果没有显示的声明其父类时,则默认继承于java.lang.Object

6.补充说明
-java支持多层继承
-直接父类、间接父类
-java中的子类的概念是相对的
-java中的一个父类可以声明多个子类,一个子类只有一个父类(java的单继承性)
一、super关键字的使用

1.为什么需要super?
子类需要继承父类的属性、方法

如何调用?使用super关键字

2.super的理解:父类的

3.super可以调用的结构:属性、方法、构造器

3.1 super调用属性、方法
-子类继承父类以后,我们就可以在子类的方法或结构中,调用父类中声明的属性或方法(满足封装性的前提下)
-可使用“super.”的结构,表示调用父类的属性或方法
-一般情况下,我们可以考虑省略“super.”的结构,但是,如果出现子类重写父类的方法或子父类中出现相同的属性或方法,
 必须使用“super.”声明,显示调用父类被重写的方法或父类中声明的同名的属性

3.2 super调用构造器
①子类继承父类时,不会继承父类的构造器。只能通过“super.(形参列表)”,调用父类指定的构造器
②规定:“super(形参列表)”,必须声明在构造器的首行
③在构造器的首行可以使用“this(形参列表)”,调用本类中重载的构造器
 在构造器的首行,“this(形参列表)”和“super(形参列表)”只能二选一
④如果子类构造器的首行既没有调用“this(形参列表)”也没有调用“super(形参列表)”,
  则子类构造器默认调用“super(形参列表)”,即调用父类中空参的构造器
⑤子类的任何一个构造器,要么调用本类中重载的构造器,要么调用父类的构造器
⑥一个类声明n个构造器,最多有n-1个构造器中使用“this(形参列表)”
  剩下那个一定使用“super(形参列表)”

--> 我们在通过子类的构造器创建对象时,一定在调用子类构造器的过程中,直接或间接调用到父类的构造器
    调用父类构造器,才能将父类中声明的属性或方法加载到内存中,供子类对象使用

二、子类对象实例化过程

class Creature{//生物类
    //属性、方法、构造器
}
class Animal extends Creature{//动物类

}
class Dog extends Animal{//狗类

}
class DogTest{
    public static void main(String args){
        Dog dog = new Dog();
    }
}

1.从结果角度来看:类的继承性

创建对象后,子类对象就获取了其父类中声明的所有属性和方法,在权限允许的情况下可以直接调用

2.从过程角度来看:

当通过子类的构造器创建对象时,子类的构造器一定会直接或者间接的调用到其父类的构造器,父类也会一层一层往父类调用,
直到调用默认父类Object中的构造器为止

3.创建子类对象的过程中,内存中到底有几个对象
  只有一个对象!即为当前new后面构造器对应的类的对象

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值