JAVA基础

(一)JAVA环境的搭建

1.下载并安装JDK

Java程序的编译和运行离不开jdk环境,JDK(Java Development kit)是用于开发Java程序的开发包,它提供了运行java的程序所要的各种工具和资源,本次学习jdk8
JRE是指java运行环境。
JDK是java开发工具包。包括了Java运行环境(JRE),一堆Java工具(javac/java/jdb等)和Java基础的类库(即Java API 包括rt.jar)。

JRE:JVM+Java语言的核心类库。
JDK:JRE+Java的开发工具。
JDK 包含JRE,JRE包含JVM。

jdk:常用的版本:本次在windows系统上安装,对应操作系统64位

网址:http://www.oracle.com/technetwork/java/javase/downloads/index.html

jdk的安装目录:

​ 1.bin目录:存放着编译,运行java程序的可执行文件

​ 2.lib目录:存放着java的类库文件

​ 3.jre目录:存放Java运行的环境文件

2.JDK环境变量的设置

​ 1.计算机(此电脑)----属性----高级设置—系统设置

​ 2.新建一个系统变量:变量名:JAVA_HOME,变量值:E:\jdk1.8\jdk

​ 3.添加到Path环境变量中:设置源变量值为:%JAVA_HOME%\bin

​ %表示连接符,相当于指向的作用。

​ 4.测试jdk是否安装成功:

​ win键+r键,输入cmd,进入DOS命令窗口:java -version ;然后再输入javac;看指令能否识别

​ 如果不能识别,报错:提示是外部命令

(二)编写一个JAVA程序

1.编写步骤

(1).创建一个Java源程序。Java源程序用以.java作为扩展名,可以使用任意的文本编译器去创建和编写

​ (2).编译源程序去生成字节码文件。字节码文件的后缀名是.class文件

​ (3).运行字节码文件。

2.实例

(1).打开记事本

​ (2).输入关键代码

​ (3).将文件以后缀名为.java保存

​ (4).测试运行

​ 1. 进入命令提示行:
先找到Person.java文件所在的上一级的位置:

​ DOS命令:cd 进入下以及目录(输入第一个字符后,tab可以逐个查找;
cd \返回全部上级目录;dir查看当前目录下的文件
cd…返回上级目录;F:去往F盘;

​ 本机的桌面的路径:C:\Users\86188\Desktop

​ 2.执行输入命令:

​ javac Person.java (生成了字节码文件)

​ 报错:

​ 提示:少了一个;

​ 报错:表示GBK的不可映射字符,因为我们使用了中文字符

​ 解决方案:

​ javac -encoding UTF-8 Person.java

​ java Person(这样就可以输出中文)

​ 3.执行输入命令:java Person

(三)安装IDEA与使用

1.安装IDEA

安装时勾上Java,和安装路径,快捷方式

2.使用

1.新建项目
2.添加JDK
在这里插入图片描述
点击 ADD JDK,添加JDK所在路径,之后next,不选择模板
3.设置Project name与存储路径(不要放C盘)
4.右击文件new—package可以创建新的包
5.选中项目,再点击File—new—module,可以创建新的模块(module),模块就是工程里的子项目,工程(preject)是最大的工作单元
6.选中包,new—Java class
7.在这里插入图片描述
File—Settings—Editor—Live Templates这里可以查看快捷的输入方式
比如打main就出public static void main(String[] args) {}
打cout就出System.out.println();
8.src文件夹下写代码(存放的是项目的源文件)
9.IDEA写代码不用保存
在IDEA中,项目>模块>包>类

(四)数据类型与运算

变量

1.变量的命名
Java中的标识符规则有4个:

​ (1).标识符由字符、数字、下划线(_)、或者$组成

​ (2).标识符的首字母以字母、下划线、美元符号开头,不能以数字开头

​ (3).标识符命名不能与关键字、布尔值(false、true)和null相同

​ (4).标识符区分大小写,没有长度限制、坚持以见名知义的有原则,使用驼峰命名法,如;studentName

2.关键字

  1. abstract: 用于声明抽象类,以及抽象方法。
  2. boolean: 用于将变量声明为布尔值类型,只有 true 和 false 两个值。
  3. break: 用于中断循环或 switch 语句。
  4. byte: 用于声明一个可以容纳 8 个比特的变量。
  5. case: 用于在 switch 语句中标记条件的值。
  6. catch: 用于捕获 try 语句中的异常。
  7. char: 用于声明一个可以容纳无符号 16 位比特的 Unicode 字符的变量。
  8. class: 用于声明一个类。
  9. continue: 用于继续下一个循环,可以在指定条件下跳过其余代码。
  10. default: 用于指定 switch 语句中除去 case 条件之外的默认代码块。
  11. do: 通常和 while 关键字配合使用,do 后紧跟循环体。
  12. double: 用于声明一个可以容纳 64 位浮点数的变量。
  13. else: 用于指示 if 语句中的备用分支。
  14. enum: 用于定义一组固定的常量(枚举)。
  15. extends: 用于指示一个类是从另一个类或接口继承的。
  16. final: 用于指示该变量是不可更改的。
  17. finally:try-catch 配合使用,表示无论是否处理异常,总是执行 finally 块中的代码。
  18. float: 用于声明一个可以容纳 32 位浮点数的变量。
  19. for: 用于声明一个 for 循环,如果循环次数是固定的,建议使用 for 循环。
  20. if: 用于指定条件,如果条件为真,则执行对应代码。
  21. implements: 用于实现接口。
  22. import: 用于导入对应的类或者接口。
  23. instanceof: 用于判断对象是否属于某个类型(class)。
  24. int: 用于声明一个可以容纳 32 位带符号的整数变量。
  25. interface: 用于声明接口。
  26. long: 用于声明一个可以容纳 64 位整数的变量。
  27. native: 用于指定一个方法是通过调用本机接口(非 Java)实现的。
  28. new: 用于创建一个新的对象。
  29. null: 如果一个变量是空的(什么引用也没有指向),就可以将它赋值为 null,和空指针异常息息相关。
  30. package: 用于声明类所在的包。
  31. private: 一个访问权限修饰符,表示方法或变量只对当前类可见。
  32. protected: 一个访问权限修饰符,表示方法或变量对同一包内的类和所有子类可见。
  33. public: 一个访问权限修饰符,除了可以声明方法和变量(所有类可见),还可以声明类。main() 方法必须声明为 public。
  34. return: 用于在代码执行完成后返回(一个值)。
  35. short: 用于声明一个可以容纳 16 位整数的变量。
  36. static: 表示该变量或方法是静态变量或静态方法。
  37. strictfp: 并不常见,通常用于修饰一个方法,确保方法体内的浮点数运算在每个平台上执行的结果相同。
  38. super: 可用于调用父类的方法或者字段。
  39. switch: 通常用于三个(以上)的条件判断。
  40. synchronized: 用于指定多线程代码中的同步方法、变量或者代码块。
  41. this: 可用于在方法或构造函数中引用当前对象。
  42. throw: 主动抛出异常。
  43. throws: 用于声明异常。
  44. transient: 修饰的字段不会被序列化。
  45. try: 于包裹要捕获异常的代码块。
  46. void: 用于指定方法没有返回值。
  47. volatile: 保证不同线程对它修饰的变量进行操作时的可见性,即一个线程修改了某个变量的值,新值对其他线程来说是立即可见的。
  48. while: 如果循环次数不固定,建议使用 while 循环

注释

​ java提供了注释有三种:1.单行注释、2.多行注释、文档注释

1.单行注释

​ 最简单类型的注释,只能写在一行的注释,

​ 快捷键:ctrl+/

​ 单行注释语法:

​ 以两个"/"开头

2.多行注释

​ 多行主要用于说明比较复杂的内容,或者说复杂的程序逻辑和算法原理,当一般有多行类容需要被注释的时候,才使用

​ 快捷键方式:ctrl+shift+/(是问好键下的斜杠)

语法:

​ 以“/”开头,以“/”结尾,中间的内容都被注释

3.文档注释:

​ API文档一样,可以在编写代码时使用文档注释

​ 在idea,输入/**,然后按enter键,iDEA会自动显示文档注释
在这里插入图片描述

在Settings----File and Code Templates----Includes中设置
设置后如图
在这里插入图片描述

(五)数据类型

Java是强类型的语言,在定义变量时,需要声明数据类型,在Java中主要分为两种数据类型:

​ 基本数据类型、引用数据类型

基本数据类型

整数型:(byte、short、int、long)

​ 浮点型:(float、double)

​ 字符型:char

​ 步尔型:boolean

​ 其中整数型和浮点型又叫数值型,int、double、long 等都是java定义的关键字

基本数据类型大小示例取值范围
boolean1字节,8位truetrue、false
byte1字节,8位有符号整数-12-128~+127
short2字节,16位有符号整数100-32768~+32767
int4字节,32位有符号整数12-2147483648~+2147483647
long8字节,64位有符号整数1000-2147438648~+2147438647
char2字节,16位Unicode‘a’0~65535
float4字节,32位浮点数(单精度)
有效数字6位
3.4f-3.4E38~3.4E38
double8字节,64位浮点数(双精度)
有效15位
-2.1e3D-1.7E308~1.7E308

常量

概念:指Java中在程序运行中,不能改变量,称为常量

变量

概念:与常量相对应,指程序中运行值可以改变的量。它是java程序中存储的一个基本单元

​ 变量的语法格式:

​ 变量类型 变量名 =[初始值]

​ 变量的类型可以在数据类型中选择的

​ “变量名”是定义变量的名称,要遵循表示符命名的规则

​ 中括号里面的值的内容为初始值,可选项

数据类型转换

概念:

​ 不同的基本数据类型之间进行运算时,需要类型转换,除布尔类型外,所有的基本数据类型进行运算时要考虑类型转换,主要应用在算术运算和赋值运算中

(1)自动类型转换

​ 将低级别的类型赋值给高级别的类型时进行的自动转换
byte<short<int<long<float<double
byte short char在运算时,会直接先提升为int,在进行运算
(2)强制类型转换

​ 将高级别的类型赋值给低级别的类型时,必须要进行的强制转换,在Java中,使用一对小括号进行表示强制类型转换,如:int a=1;byte num=(byte)a;
double a=3.14159;int n=(int)a

运算符

1.赋值运算

​ 赋值运算符号“=”用于给变量指定变量的值,并可以和算术运算符结合起来,组成复合赋值运算符。复合赋值运算符:“+=”、“-=”、“*=”、“/=”、“%=”

2.算术运算

​ 算术运算符包括:“+”,“-”,“*”,“/”,“%”、“++”、“–”

​ 其中:++表示自增运算
​ --表示自减运算
j=i++是i先赋值给j,再自增
j=++i是i先自增,再赋值给j
对于除法运算,如果两个操作数都是整数,结果也是整数,会舍去小数部分,如果两个数,有一个是浮点数,将会进行自动类型转换,结果也是浮点数,保留小数部分

​ 对于取模运算符,如果两个操作数均是整数,结果也是整数,如果两个操作数有一个浮点数结果也是浮点数,保留小数部分
3.关系运算符

​ 关系运算符有时又叫比较运算符,用于比较两个变量或常量的大小,运行的结果是布尔值:true

或false;

Java中有6个关系运算符:“==”、“!=” “>”,“<”,“>=”;“<=”

注意:

​ (1)."="表示是赋值运算符;”==“表示等于运算符

​ (2).”>“;“<”,“>=”;“<=”;只支持数值类型的比较

​ (3).“==”、“!=”支持所有数据类型的比较,包括数值类型、布尔类型、引用类型

​ (4).关系运算符,运算后的结果是一个布尔值

​ (5).“>”,“<”,“>=”;“<=”;运算符的优先级高于”==“、”!=“
4.逻辑运算符

​ 逻辑运算符用于对布尔类型操作数进行运算,其结果还是布尔值,逻辑运算如下

运算符含义运算规则
&逻辑与两个操作数都是true,结果才是true;不论左边取值,右边的表达式都会进行运算
|逻辑或两个操作数一个是true,结果也是true;不论左边取值,右边的表达式都会进行运算
^逻辑异或两个操作数相同,结果为false;两个操作数不同,结果为true
逻辑非操作数为true,结果为false;操作数为false,结果为true
&&短路与运算规则同“&”,不同在于如果左边为fasle,右边表达式不会进行运算
||短路或运算规则同“|”,不同在于如果运算符左边的值为true,右边的表达式不会进行运算

注意:

​ (1).操作数类型只能是布尔类型,操作的结果也是布尔类型

​ (2).优先级别:”!“>“&”>“^”>“|”>“&&”>“||”。

​ (3).&与&&的区别:当“&&”的左侧为fasle时,将不会计算其右侧的表达式,即左边false则fasle;无论任何情况,“&”两侧的表达式都会参与计算

​ (4).逻辑或和短路或:的区别和逻辑与与短路与类似

5.条件运算(三目运算符)

​ 是java中唯一需要3个操作数的运算符,又叫三元运算或三目运算

​ 条件运算符的语法格式:

​ 条件? 表达式1:表达式2

​ 运算过程:

​ (1).先对条件进行判断,结果为true,则返回表示式1的值

​ (2).如果结果为false,则返回表达式2的值

6.运算符的优先级:

​ 运算符的最低的级别是赋值运算,其次条件运算符

​ 单目运算包括:”!“、”~“、”++“、”–“优先级最高的

​ 可以通过”()“来控制表达式的运算顺序,”()“优先级别最高

​ 总体而言:优先顺序为算术运算符>关系运算符>逻辑运算符

(六)键盘录入

1.导包
import java.util.Scanner;(在idea中自动完成)
2.创建对象
Scanner sc = new Scanner(System.in);
3.接受数据
int i = sc.nextInt();
sc.next(); 字符串(只要字)
sc.nextInt(); 整型
sc.nextDouble(); double类型
sc.nextLine(); 字符(全都要,包括空格)

(七)流程控制

Java中有三种流程控制结构:顺序结构、选择结构、循环结构

​ 顺序结构:顺序结构指的是程序自上而下一次执行的每条语句,中没有任何的判断和跳转,前面所有的结构都是顺序结构

​ 选择结构:

​ 选择结构根据判断条件的结果来执行不同的代码

​ 循环结构:

​ 根据判断条件来重复执行某块代码。Java提供、while语句,do-while语句、for语句来实现循环结构

选择结构

(1)if语句的语法格式如下:

​ if(表达式){

​ 语句块

​ }

​ if是java中的关键字

​ 表达式是布尔类型的表达式,其结果是true或false

(2)if-else语句的语法如下:

​ if(表达式){

​ 语句块

​ }else{

​ 语句2

​ }

​ 当表达式为true时,执行语句块1;

​ 表达式为false时,执行语句块2

(3)多分支if语句的语法格式:

​ if(表达式1){

​ 语句块1

​ }else if(表达式2){

​ 语句块2

​ }else{

​ 语句块3

​ }

注意:Java中判断两个字符串是否相等,用equals()判断两个字符串的值是否相等,用“==”比较判断内存地址是否相等

(4)​ switch语句语法的格式:

​ switch(表达式){

​ case常量1:

​ 语句

​ break;

​ case常量2:

​ 语句

​ break;

​ …

​ default:

​ 语句;

​ break;

​ }

​ switch、case、break、default都是java中的关键字

​ switch的表达式只能是字符型、枚举型、整数型

​ case用于表达式匹配

​ default是选择的,当其他不匹配时,执行default

循环结构

​ (1)while循环的语法格式:

​ 变量的初始化

​ while(循环条件){

​ 循环体

​ }

while语句的执行步骤:

​ 1.首先对循环条件的结果进行判断,如果为真,则执行循环语句

​ 2.执行完毕后,继续对循环条件进行判断,如果为真,继续执行

​ 3.如果结果是假(false),跳出循环语句,去执行后面的语句

(2)do-while循环语句的语法格式如下:

​ 变量初始化

​ do{

​ 循环体

​ }while(循环条件)

注意:do-while先执行循环体,再执行循环条件,所以循环体至少执行一次,这点和while循环相反

(3)for循环的语法格式如下:

​ for(表达式1;表达式2;表达式3){

​ 循环体

​ }

for语句的执行步骤:

​ 1.首次执行表达式1,一般进行变量初始化的操作

​ 2.然后执行表达式2,即对循环条件进行判断

​ 3.如果结果为真,则执行循环体

​ 4.循环语句执行完毕后执行表达式3,改变循环的变量的值,再次执行表达式2;

​ 如果结果是真,继续循环

​ 5.如果结果是假,终止循环,执行后面的语句

注意:使用fori或变量.fori可以直接出来

跳转语句

Java语言中支持3种类型的跳转语句:continue语句、return语句,break;使用这些语句,可以把控制转移到循环甚至程序的其他地方。

(1).break语句
​ 作用: 在循环种终止当前循环,在switch语句中终止switch语句
(2).continue语句
​ 作用: 强制循环提前返回,也就是让循环跳过本次循环中剩余代码,然后进入下次循环

注意:在while循环和do-while循环中,continue执行完毕后,程序将直接判断循环条件,如果为true,则继续下次循环,否则,终止循环,而在for循环中continue使用程序先跳转到循环变量计算部分,然后再判断循环条件

(八)数组

一维数组

1.定义数组

​ 定义数组时一定要指定数组的名称和数组的类型

​ 必须的抒写方式“[]”,表示的就是定义一个数组,而不是一个普通的变量

​ "[数组长度]"决定了连续分配的空间长度,通过数组length属性可以获取数组长度

​ 数组的数据类型用于确定分配每个空间的大小
int [] a=new int [5];
int [] b={1,2,3,4}
​ 数组元素分配的初始值

数组元素的类型默认初始值
byte、short、int、long0
float、double0.0
char”\u0000“
booleanfalse
引用数据类型null

​ 2.获得数组元素的语法格式:

​ 数组名[下标值]

​ 例如

​ scorce[0] =65 //表示scorce数组的第一个元素赋值给他为65

​ scorce[1]=87 //表示scorce数组的第二个元素赋值给他为85

3.jdk1.5:之后为我们提供了一个增强for循环,用来实现对数组和集合中的访问,增强for循环的语法格式:

​ for(元素类型 变量名:要循环的数组或集合){ …}
​括号中的第一个元素类型指的时数组或集合中元素类型,变量名在循环时保存每个元素的值,冒号后面是我们要循环的数组或集合的名称

二维数组

int[][] s =new int[3][5];
表面上看是二维数组,但是从内存分配来看,实际上就是一个一维数组,数组名为s,包括了3个元素,分别是s[0]、s[1]、s[2],每个元素是整型数组类型,即一维数组类型。而s[0]又是一个数组的名称,包括了5个元素

分别是s[0][0]、s[0][1]、s[0][2]、s[0][3]、s[0][4]、每个元素都是整数类型。s[1]、s[2]、s[3]情况相同
所以二维数组实际上就是一个一维数组,每个元素又是一个一维数组。
s[1][0]、s[1][1]、s[1][2]、s[1][3]、s[1][4]

Arrays类

JDK中提供了一个专门用于操作数组的攻击类,即Array类,位于java.util包中,该类提供了一系列方法来操作数组,比如排序、复制、比较、填充等、用户直接调用这些方法即可,不需要自己编码去实现,降低开发难度。

方法返回值说明
equals(array1,array2)boolean比较两个数组是否相等
sort(array)void对数组arry元素的进行升序的排列
toString(arrry)string将一个数组arry转换一个字符串
fill(arry,val)void把array数组中所有的元素都赋值为val
copyOf(arry,length)与arry数据类型一致把数组arry复制成一个长度为length的新数组
binarySearch(array,val)int查询元素值val在数组arry中的下标

Arrays类的equals()方法·用于标胶两个数组是否相等,只有当两个数组长度相等,对应的位置的元素也就一一相等时,该方法就返回true否则返回false

toString()将一个数组转换成一个字符串,它按照顺寻把多个数组元素连接一起,多个元素之间使用英文逗号和空格隔开

Arrays类的copyOf(array,length)方法可以进行数组复制,把原数复制成一个新数组,其中length是新数组的长度。如果length小于原数组的长度,则新数组就是原数组的前面length个元素;如果length大于原来数组的长度,则新数组前面的元素的原数组的所有元素;后面元素是按数组类型补充默认的初始值,如整型补充0,浮点型补充0.0等。

(九)面向对象

对象和类

Java语言就是面向对象的语言。要使用Java进行面向对象编程,首先简历一个面向对象的思想。面向对象是一种直观而且程序结构简单的程序设计方法。它比较符合人类认识现实世界的思维,基本思想:把问题看成若干对象的组成,这些对象之间是独立,但是他们之间又可以相互配合,连接和协调,从而共同完成整个程序实现的任务。

​ 面向对象有三大特征:封装、继承、多态

对象就是用来描述客观事物的一个实体。
类是具有相同的属性和方法的一组对象集合。类定义了对象将会拥有一些特征(属性)和行为(方法)。
类与对象的关系就如同模具和用整个模具制作出的物品之间的关系。一个类给出它的全部对象的一个统一的定义,而它的每个对象则是符合这种定义的一个实体。因此类和对象的关系就是抽象和具体的关系。类是多个对象进行综合的抽象的结果,是实体对象的概念模型,而一个对象是一个类的实例。
(1).定义一个类

​ 定义"人" 类

​ 定义的语法格式:

​ [访问修饰符] class 类名{

​ …//省略类的内部代码

​ }

​ 1.访问符:如public、private、等可选的

​ 2.class表示声明类的关键字

​ 3.按照类名规范,首字母大写
(2).属性

​ Java中的类的内部主要就包括属性和方法,对象所拥有的特征再类中称为属性

​ 定义属性的语法格式:

​ [访问修饰符] 数据类型 属性名:

​ 1.访问修饰符可以选的

​ 2.除了访问修饰符之外,其他的语法和声明变量属性

(3).方法:

​ 对象执行操作的行为称为方法,例如:人有工作的行为,称工作这个行为就是人这个类中的一个方法

​ ”人“ 类还有其他的方法,如吃、喝、睡觉等。

​ 定义方法的语法格式:

​ [访问修饰符] 返回类型 方法名称(参数类型 参数名1,参数类型2 参数名2,。。。。){
方法体代码 }

​ 1.访问修饰符可以选择

​ 2.返回的类型可以是void,返回类型是void时,标明没有返回值,方法体中不必使用”return“关键字来返回具体数据,但是可以使用”return“关键字来退出方法

​ 3.返回类型不是void,那么再方法体中一定要使用”return“关键字,返回对应类型的结果,否则程序会出现编译错误。

​ 4.当需要再方法执行时,为方法传递参数时,蔡需要参数列表,如果不需要参数传递,参数列表可以省略

​ 不过小括号不能省略,传递多个参数使用,分隔。

(4).创建对象

​ 类是一个事物的集合和抽象,代表这类事物共有的属性和方法,以后个对象称为类的实例,是类的一次实例化的结果,例如”张三“ 一个”人“类的具体对象

​ 类的对象可以调用类中的成员,如属性,方法

​ 创建对象的语法格式:

​ 类名 对象名=new 类名()

​ 1.new 是关键字

​ 2.左边的类名为对象的数据类型

​ 3.右边的类名称为类的构造方法(后续会讲)

(5)。使用Java中的对象

​ 在java中,要引用对象的属性和方法,需要”.“

​ 使用java对象的语法格式:

​ 对象名.属性 //引用对象的属性

​ 对象名.方法 //引用对象的方法
(7).面向对象的优点:
​ 1.与人类的思维习惯一致:面向对象的思维方式是从人类考虑问题的角度出发,把人类解决问题的思维过程转变为程序能够理解的过程、面向对象程序设计使用"类"来模拟现实世界中的抽象概念,用"对象"来模拟现实世界的实体从而用计算机解决现实问题

​ 2.信息隐藏,提高了程序的可维护性和安全性:封装实现了模块化和信息隐藏,即将类的属性和行为封装在类中,这保证了对他们的修改不会影响到其他对象,利于维护。同时,封装使的在对象外部不能随意访问对象的属性和方法,避免了外部错误对它影响,提高了安全性

​ 3.提高了程序的可重用性:一个类可以创建多个对象实例,体现了重用性。

(十)成员方法

类中主要包括两部分:成员方法、成员变量
(1).方法重载
方法重载是指一个类中定义多个同名的方法,但要求每个方法具有不同的参数类型或参数个数。
​ 特点:
1.在同一个类中
​ 2.方法名相同
​ 3.参数个数或类型不同
​ 4.方法的返回值不能作为判断方法之间是否构成重载的依据

(2)成员变量:

1.成员变量的作用域:
​ 类中的属性,也就是直接在类中定义的变量称作为成员变量,它定义在方法的外部
​ 注意:
​ 成员变量可以在声明时开始赋值

2.局部变量作用域
​ 局部变量就是定义在我们方法中的变量
注意:
​ 虽然成员变量age和局部变量age名称一样,但是表示的却不是同一个变量,一般情况下,局部变量在使用前需要赋值,否则会出现编译错误

(3)。 成员变量和局部变量的区别

​ 1.作用域不同,局部变量的作用域仅限定义它的方法,在该方法外无法访问它。成员变量的作用域在整个类的内部可见,所有的成员的方法都可以使用它,如果访问权限允许的话,还可以在类的外部使用成员变量
​ 2.初始值不同,对于成员变量,如果类定义没有给它赋予初始值,Java会给它一个默认值,基本数据整数型是0,引用类型是null,但是Java不会给局部变量赋予初始值,因此局部变量必须要定义并复制后使用
​ 3.在同一个方法中,不允许有同名的变量,在不同的方法中,可以用同名的局部变量
​ 4.局部变量可以和成员变量同名,并且一起使用,局部变量更高的优先级别

(4).对比基本数据类型和引用数据类型的区别

​ 分析如下:

​ int为基本数据类型,当初始化num1并赋值后,将num1赋给num2,然后修改num2的值,运行后发现num1的值没有改变。

​ class为引用数据类型,当实例化person1对象并对其属性赋值后,将person1对象赋给person2对象,然后修改person2的值,运行后发现person1的属性值发生变化。

​ 几乎同样的操作,为什么会有完全相反的结果?这是因为int和class在内存种的存储方式不同,这也是基本数据类型和引用数据类型的主要区别。

​ 对于基本数据类型,不同的变量会分配不同的存储空间,并且存储空间中存储的是该变量的值,赋值操作传递的是变量的值,改变一个变量的值不会影响另外一个变量的值

​ 对于引用数据类型,赋值是把原对象的引用(可以理解内存地址)传递给另外一个引用,对数组而言,当用一个数组名直接给另一个数组赋值时,相当于传递一个引用,此时,这两个引用指向同一个数组,也就是指向同一内存空间。

(十一)构造方法

java中,当类创建一个对象时会自动调用该类的构造方法,构造方法分为默认构造方法和带参数的构造方法

​ 1.构造方法的主要作用是进行一些数据的初始化

​ 定义构造方法的语法格式:

​ [访问修饰符] 方法名(参数列表){
​ 方法体代码​ }

​ 当开发人员没有编写自定义构造方法时,Java会自动默认添加构造方法,默认构造方法时没有参数,也就是无参的构造方法

​ 注意:

​ 如果自定义一个或者多个构造方法时,则java不会自动添加默认构造方法
2.构造方法重载

​ 构造方法也可以重载,即在同一个类中可以定义多个重载的构造方法,如:
public Person(){};
public Person(String name,int age){
this.name=name;
this.age=age;}
在成员变量的示例中多次用到了this关键字,this的含义是什么呢?

​ this关键字是对一个对象的默认引用,每个实例方法内部都有一个this引用变量,指向调用这个方法的对象,其实就是指当前对象的引用,通俗点理解本对象自己

(1).this.属性名:

​ 表示本对象自己的属性使用this调用成员变量,解决变量和局部变量的同名冲突
(2)this.方法名:

表示本对象自己的方法
​ 我们给Person类增加了一个”打招呼”的方法叫做greet。在introduce方法当中,就可以通过”this.方法名”的方式来调用这个方法,表示调用的是”本对象自己的greet”方法。这是this关键字的第二种用法。当然,在introduce方法中并没有出现其他对象,所以方法名前面的this关键字也可以省略不写。
public void greet(){
System.out.println(“hello,大家好”);
}

public void introduce(){
this.greet();
System.out.println(“我叫”+name+“,今年”+age+“岁”);
}
(3)this关键字

​ 还有另外一种很重要的用法,那就是在this关键字的后面加上小括号,这样就表示调用了某个类自身的构造方法,为了讲解这种用法我们再来修改一下Person类:

​ 我们给Person类又增加了一个构造方法。这个构造方法只有2个参数,并且只初始化2个属性。为了讲述方便,我们把上面的3个参数的构造方法称之为”构造方法①”,把下面的2个参数的构造方法称之为”构造方法②”。通过观察不难发现,这两个构造方法当中前2行代码是相互重复的,为了避免这种重复性的代码出现,我们可以在”构造方法①”当中调用”构造方法②”。调用的方式如下:
//构造方法1
public Person(String name,int age,double height){
this(name,age); //调用构造方法2
this.height=height;
}

 //构造方法2
public Person(String name,int age){

    this.name=name;
    this.age=age;
}

(4).外部类名.this.属性

​ this关键字在我们编写内部类代码的时候,还有一种用途,那就是区分属性或方法的具体归属
public class Outter {

public int a=0; //外部类的属性

class Inner{
    public  int a=10;//内部类的属性
    public void printA(){
        System.out.println(a);//调用内部类的a属性,输出10
        System.out.println(this.a);//调用内部类的a属性,输出10
        System.out.println(Outter.this.a);//调用外部类的a属性,输出0
    }
}

}

(十二)封装

​ Java中封装的实质就是将类的状态信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法开实现对隐藏信息的操作和访问。

​ 封装反映了事物的相对独立性,有效避免了外部错误对此对象的影响,并且能对对象使用者由于大意产生的错误操作起到预防作用。同样面向对象编程提倡对象之间实现松耦合关系。

​ 封装的好处在于隐藏类的实现细节,让使用者只能通过程序员规定的方法来访问数据,可以方便的加入存取控制修饰符,来限制不合理的操作。
将Person类中的属性public修改为private即可
访问时需要通过set个get函数,使用Generate–来快捷定义set,get和构造函数

作用域\修饰符同一类中同一包中子孙类中其他包
private可以使用不可以使用不可以使用不可以使用
默认修饰符可以使用可以使用不可以使用不可以使用
protected可以使用可以使用不可以使用不可以使用
public可以使用可以使用可以使用可以使用

public:公有的
​ 被声明为public的类、方法、构造方法和接口能够被任何其他类访问。
如果几个相互访问的public类分布在不用的包中,则需要导入相应public类所在的包。由于类的继承性,类所有的公有方法和变量都能被其子类继承。Java程序的main() 方法必须设置成公有的,否则,Java解释器将不能运行该类

protected:受保护的
​ 被声明为protected的变量、方法和构造方法能被同一个包中的任何其他类访问,也能够被不同包中的子类访问。
protected访问修饰符不能修饰类和接口,方法和成员变量能够声明为protected,但是接口的成员变量和成员方法不能声明为protected。
子类能访问protected修饰符声明的方法和变量,这样就能保护不相关的类使用这些方法和变量。

private:私有的
​ 私有访问修饰符是最严格的访问级别,所以被声明为private的方法、变量和构造方法只能被所属类访问,并且类和接口不能声明为private。
声明为私有访问类型的变量只能通过类中公共的Getter/Setter方法被外部类访问。
private访问修饰符的使用主要用来隐藏类的实现细节和保护类的数据。

默认的:不使用任何关键字
不使用任何修饰符声明的属性和方法,对同一个包内的类是可见的。接口里的变量都隐式声明为public static final,而接口里的方法默认情况下访问权限为public。

static关键字
​ 一个类可以创建n个对象。如果n个对象中的某些数据需要共用,就需要使用static关键字修饰这些数据。
​ Java中,一般情况下调用类的成员都需要先创建类的对象,然后同过对象进行调用。使用static关键字可以实现通过类名加".“直接调用类的成员,不需要创建类的对象。使用staic修饰的属性和方法属于类,不属于具体的某个对象。
1.用static关键字修饰属性
​ 将Person类的name、gender和age属性保留,新建一个static修饰的属性,并调用。
​ 分析如下:
​ 使用static修饰的属性不依赖于任何对象,用类名直接加”."调用即可。
​ 使用static修饰的属性不依赖于任何对象,用类名直接加“.”调用即可。
​ *常量名一般由大写字母组成
​ *声明常量时一定要赋值初值
2.用static关键字修饰方法
​ 用staic修饰的方法称为静态方法或者类方法,不用static关键字修饰的方法称为实例方法
​ 静态方法只能访问静态成员,实例方法可以访问静态和实例成员。之所以不允许静态方法访问实例成员变量,是因为实例成员变量是属于某个对象的,而静态方法在执行时,并不一定存在对象。同样,因为实例方法可以访问实例成员变量,如果允许静态方法调用实例方法,将间接地允许它使用实例成员变量,所以它也不能调用实例方法。基于同样的道理,静态方法中也不能使用关键字this。
​ main()方法是一个典型的静态方法,它同样遵循一般静态方法的规则,所以它可以由系统在创建对象之前就调用。
//静态方法只能访问静态
//非静态方法可以访问所有
//静态方法没有this

(十三)包

​ Java中的包机制也是封装的一种形式。

​ 包的主要有以下方面的作用:

​ 1).包允许将类组合成较小的单元(类似文件夹),易于找到和使用相应的类文件

​ 2).防止命名冲突:Java中只有在不同包中的类才能重名。不同的程序员命名同名的类在所难免,类名就容易管理了,A定义了一个类Sort,封装在包A中,B定义了一个类Sort,封装在包B中,在使用时,为了区别A和B定义的Sort类,可以通过包名区分开,如A.Sort和B.Sort分别对应于A和B定义的Sort类。
​ 定义包的语法格式如下:

​ package包名:

​ package是关键字

​ 包的声明必须是Java源文件中的第一条非注释性语句,而且一个源文件只能有一个包声明语句,设计的

​ 包需要与文件系统结构相对应。因此,在命名包时,要遵守以下编码规范。

​ 1).一个唯一的包名前缀通常是全部小写的ASCII字母,并且是一个顶级域名com、edu、gov、net及org,通常使用组织的网络名的逆序。例如,如果域名为javagroup.net,可以声明包为“package net.javagroup.mypackage;”

​ 2) 包名的后续部分依次不同机构各自内部的规范不同而不同。这类名规范可能以特定目录名的组成来区分部门、项目、机器或注册名、如“package net.javagroup.research.powerproject”。research表示项目名,powerproject表示部门名
​ 例如,下面的代码中,为了Person类定义了包cn.shujia.pack1。
package cn.shujia.pack1;
​ public class Person{
​ //省略类的内代码}

(十四)继承和多态

继承

继承是面向对象的三大特性之一,继承可以解决编程中代码的冗余问题,是实现代码重用的重要手段。继承是软件可重用性的一种表现,新类可以在不增加自身代码的情况下,通过从现有的类中继承其属性和方法,来充实自身内容,这种现象或行为就称继承。此时新类称为子类,现有的类称为父类,继承最基本的作用就是使得代码可重用,增加软件的可扩充性。

Java中只支持单继承,每一类只能有一个父类。

(1).继承的语法格式:

​ [访问修饰符] class extends {}

​ 1.在Java中,通过extends关键字来实现,Subclass称为子类,SuperClass称为父类或者基类

​ 2.访问修饰符如果是public ,在整个项目中可用。

​ 3.如果不写访问修饰符,该类只能在当前包下

​ 4.在java中,子类可以在父类继承如下内容:

​ a.可以继承public 和protected修饰的属性和方法,不论子类和父类是否在同一包中

​ b.可以继承默认访问修饰符的属性和方法,但是子类和父类必须在一个包中

​ c.无法继承父类发的构造方法

(2).通过super关键字访问父类的成员的语法格式:

​ 访问父类的构造方法: super(参数)

​ 访问父类的属性和方法:super.<父类属性/方法>

​ 1).super只能出现在子类(子类的方法和构造方法中)而不是在其他位置

​ 2),super只能访问父类的成员:如属性、方法、构造方法

​ 3).具有访问权限的限制,如无法通过super访问父类的private的成员

(3).实例化子类对象

在Java中,一个类的构造方法在如下两种情况下总会被执行

​ a.创建类的对象(实例化)

​ b.创建该类的子类的对象(子类的实例对象)

​ 因此,子类在实例化时,会首先执行其父类的构造方法,然后再去执行该子类的构造方法,换言之,当在java语言中创建一个对象时,Java虚拟机会按照父类----子类的顺序一系列的构造方法。子类继承父类时,构造方法的调用规则:

​ 1.如果子类的构造方法中没有通过super显示调用父类的有参构造方法,也没有通过显示this显示调用自身的其他构造方法,则系统会按照默认先调用父类无参的构造方法,在这情况下,我们写不写"super()"语句,效果一样

​ 2.如果子类的构造方法中通过super显示的调用了父类的有参构造,那么将执行父类的相应构造方法,而不是执行无参的构造方法。

​ 3.如果子类的构造方法中通过this显示的调用了自身的其他构造方法,在相应得构造方法中遵循以上两条规则。
(4).多继承
​ 分析:当执行"postGraduate =new PostGraduate()"后,共创建了4个对象。按照创建的先后顺序,依次Object、Person、Student、PostGraduate。在执行Person()时就调用了Object无参构造方法,该方法内容为空

​ 当执行”postGraduate=new PostGraduate(“刘大大”,“北京大学”,“老王老师”);“,也是创建了4个对象,只是此次调用构造方法不同,依次Object(),Person(String name)、Student(String name,String school)、PostGraduate(String name,String school,String guide)

示例:

​ 如果B的父类中A没有自定义的构造方法时,系统会提供一盒无参方法体为空的构造方法,

​ 但是,当B的父类中A定义了构造方法时,系统将不会再提供一个无参的方法体为空的构造方法

​ 程序员必手动去添加一个无参的构造方法

(5).Object类

​ Object是所有类的父类,通常省略继承Object

方法说明
toString()返回当前对象本身的有关的信息,返回字符串对象
equals()比较两个对象是否是同一个对象,若是,返回true
clone()生成当前对象的一个副本,并返回
hashCode()返回该对象的哈希代码值
getClass()返回当前对象所属的类信息,返回Class对象

​ 注意:

​ equals()比较是否是同一个对象,java.lang.String类重写了Object的equals方法

(6).方法重写

PersonelDept对象personelDept的输出内容是继承来自父类Department的printDetail()方法的内容,所以不能显示PersonelDept的count信息,这显然不符合实际需求
​ 如果父类继承的方法不能满足子类的需求,可以izai子类中对父类的同名方法重写(覆盖),以符合需求。

方法重写必须满足以下要求:

​ a.重写的方法和被重写的方法必须具有相同的方法名

​ b.重写方法和被重写方法必须具有相同的参数列表

​ c.重写方法的返回值必须和被重写方法的返回值类型相同

​ d.重写的方法不能缩小被重写方法的访问权限。

重写和重载的区别

​ 1.重载涉及同一个类中的同名方法,要求方法名相同,参数列表不同,与返回值类型无关

​ 2.重写涉及的是子类和父类之间的同名方法,要求方法名相同,参数列表相同

多态

多态一词的通常含义是指能够呈现多种不同的形式或形态。而在程序设计的术语中,它意味着一个特定类型的变量可以引用不同类型的对象,并且能自动地调用引用的对象的方法,也就是根据作用到的不同对象类型,响应不同的操作。方法重写是实现多态的基础。
多态意味着在一次方法调用中根据包含的对象的实际类型(即实际的子类对象)来决定应该调用哪个方法,而不是由用来存储对象引用的变量的类型决定的。当调用一个方法时,为了实现多态的操作,这个方法既是在父类中声明过的,也必须是在子类中重写过的方法。

注意:

​ 1.抽象类不能被实例化

​ 2.子类如果不是抽象类,则必须重写抽象类中的全部抽象方法

​ 3.abstract修饰不能和final一起使用

​ 4.abstract修饰的方法没有方法体

​ 5.private不能修饰抽象方法
(1).向上转型

​ 子类向父类的转换向上转型

​ 向上转型的语法:

​ <父类型> <引用变量名> =new <子类型>()

1.将一个父类的引用指向子类对象称为向转型,系统自动类型转换

​ 2.此时通过父类引用变量调用方法时,子类覆盖或继承了父类的方法,不是父类的方法

​ 3.此时无法通过父类的引用变量调用子类特有的方法

(2).向下转型

​ 当向上转型发生后,将无法调用子类特有的方法,但是弱国需要调用子类特有的方法,可以通过把父类转换为子类的实现

​ 将一个指向子类对象的父类引用给一个子类引用,即父类类型转换为子类类型,称为向下转型,此时必须要强制类型转换

向下类型转换的语法:

​ <子类型> <引用变量名> =(子类类型)<父类类型的引用变量>

(3).instanceof运算符

​ 在向下转型的过程中,如果不是转换为真实的子类类型,会出现异常

使用instanceof 时,对象类型必须和instanceof后面的参数所指定的类有继承关系,否则会出现编译错误,

例如:代码“pet instanceof String”。=“pet是不是子类”。instanceof通常和强转类型转换结合使用

(4).使用父类作为方法的形参

​ 使用父类作为方法的参数,是java中实现和使用多态的主要方式

(5).使用父类作为方法的返回值
使用父类作为方法的返回,也是java中实现和使用多态的主要方式

(6).调用变量时,编译看左边,运行也看左边。
java编译时看左边有没有这个变量,有的话编译成功,运行时获取的是左边的父类变量。
(7).调用方法时,编译看左边,运行看右边。
java编译时会看左边有没有这个方法,有的话,编译成功,运行时运行的是右边子类的方法。所以不能调用子类特有方法,不过可以再转回子类类型,就可以调用了。
(8).静态方法,左边编译,左边运行

​ 使用父类作为方法的返回,也是java中实现和使用多态的主要方式

(十五)抽象类和接口

抽象方法与抽象类

( 1).区分普通方法和抽象方法

​ 在Java中,当一个类的方法被abstract关键字修饰的时候,被称为抽象方法。抽象方法所在的类必须定义为抽象类。

当一个方法被定义为抽象方法后,意味着该方法不会有具体的实现(没有方法体)。而是在抽象类的子类中通过方法重写进行实现,定义抽象方法的语法格式:

​ [访问修饰符] abstract<返回类型> <方法名>([参数列表]);

​ 普通方法和抽象方法的相比,主要有两点区别:

​ a.抽象方法需要用abstract修饰,普通方法不需要

​ b.普通方法有方法体,抽象方法没有方法体
(2).区分普通类和抽象类

​ 在java中,当一个类被abstract关键字修饰时,该类被称为抽象类.

​ 定义抽象类的语法格式:

​ abstract class <类名>{

​ }

​ 普通类和抽象类的区别:

​ 1.抽象类需要abstract 修饰,普通类不需要

​ 2.普通类可以实例化,抽象类不能实例化
(3).定义一个抽象类

​ 当一个类被定义为抽象类,她可以包含各种类型的成员,包括属性、方法,其中方法又分为普通方法和抽象方法。

​ 抽象类的结构:

​ public abstract class 类名称{

​ 访问修饰符 返回类型 方法名(){ 方法体 } }

注意:抽象方法只能定义在抽象类,但是抽象类中可以包含抽象方法,也可以包含普通方法,还可以包含普通类的一切成员

接口

(4)接口
通俗的来说,接口是一个不能实例化的类型,接口类型的定义的语法格式:
​ public interface 接口名{
​ //接口成员 }

​ 和抽象类的不同:定义接口使用的关键是interface修饰,访问修饰符只能是public

​ 接口中的成员可以是全局常量和公共的抽象方法。

​ 实现接口的语法 :

​ public 类名 implements 接口名{
​ 实现方法
​ 普通方法 }

​ a.实现接口使用implements关键字

​ b.实现接口的类必须实现接口中定义的所有的抽象方法。接口的实现类允许包含普通的方法。

类与类:
继承关系,只能单继承,可以多层继承。
类与接口:
实现关系,可以单实现,也可以多实现。
并且还可以在继承一个类的同时实现多个接口。
接口与接口:
继承关系,可以单继承,也可以多继承。

接口成员特点
成员变量;只能是常量,并且是静态的。
默认修饰符:public static final
建议:自己手动给出。
构造方法:接口没有构造方法。
成员方法:只能是抽象方法。
默认修饰符:public abstract
建议:自己手动给出。
所有的类都默认继承自一个类:Object。
类 Object 是类层次结构的父类。每个类都使用 Object 作父超类。

复杂接口

接口本身也可以继承接口

​ 接口继承的语法格式:

​ 【访问修饰符】 interfance 接口名 extends 父类接口1,父接接口2,…{

​ 常量的定义

​ 方法的定义

​ }

一个普通类只能继承一个父类,但是能同时实现多个接口,也可以同时继承抽象类和实现接口

实现多接口的语法格式:

​ class 类名 extends 父类名 implements 接口1,接口2,…{

​ }

注意:

​ 关于定义和实现接口所要注意的地方

​ 1.接口和类、抽象类是一个层次的概念,命名规则相同

​ 2.修饰符如果是public ,则该接口再整个项目中可见,如果省略修饰符,该接口只在当前包中可见

​ 3.接口中可以定义常量,不能定义变量,接口中的属性都默认用"public static final",即接口中的属性都是静态全局常量,接口中的常量必须在定义时给定初始值:

​ public static final int =3.14

​ int PI =3.14//在接口中,这两个定义语句效果相同

​ int PI;// 在接口中定义必须赋值初始化

​ d.接口中所有的方法都是抽象方法,接口中的方法默认时public

​ c.和抽象类一样,接口不能实例化,接口中不能有构造方法

​ e.类中只能继承一个父类,但是可以通过implements实现多个接口,一个类必须实现接口的全部方法,

否则必须定义为抽象类,若一个类在继承父类的同时又实现了多个接口,extends必须位于implements之前

(十六)面向对象设计的原则

在实际开发过程中,遵循以下原则,会让代码更具灵活性,更能适应变化。
1.摘取代码中变化的行为,形成接口
例如,在“愤怒的小鸟”游戏中,鸟叫的行为变化性很大,有的鸟叫,有的鸟不叫。各种鸟的叫声也不一样,这种行为最好定义为接口。

2.多用组合,少用继承
在“愤怒的小鸟”游戏中,通过在抽象类鸟中包含鸟叫的属性来实现组合,有效地减少了代码冗余。

3、针对接口编程,不依赖于具体实现
如果对一个类型有依赖,应该尽量依赖接口,尽量少依赖子类。因为子类一旦变化代码变动的可能性大,而接口要稳定得多。在具体的代码实现中,体现在方法参数尽量使用接口,方法的返回值尽量使用接口,属性类型尽量使用接口等。

4.针对扩展开放,针对改变关闭
如果项目中的需求发生了变化,应该添加一个新的接口或者类,而不要去修改原有的代码。
需要说明的是,这4个面向对象的原则比较抽象,可以先记住它,然后在实际的面向对象开发中尝试应用这些原则,然后加深对这些原则的理解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张天靖09

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值