锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

尚硅谷Java入门视频教程(在线答疑+Java面试真题)

时间:2023-06-17 22:07:00 19sb1j电连接器

Java核心技术

一、Java基本语法

1.关键字和保留字

定义和特征关键字

  • 被Java语言赋予特殊意义,用作特殊用途的字符串(单词)
  • 关键字中的所有字母都是小写

保留字的定义

  • 现有Java版本尚未使用,但版本可以作为未来的关键字使用。这些保留字应避免在命名标识符时使用。

总结:48个关键词,2个保留词,3个字面值

定义数据类型的关键字 class interface enum byte short int long float double char boolean void 用于定义流程控制的关键字 if else switch case default while do for break continue return 定义访问权限修改符的关键字 private protected public 定义类,函数,变量修饰符的关键字 abstract final static synchronized 定义类与类之间关系的关键词 extends implements 定义建立实例和引用实例,判断实例的关键字 new this super instanceof 用于异常处理的关键字 try catch finally throw throws 用于包的关键字 package import 其它修饰符关键字 native strictfp transient volatile assert  保留字 goto const  字面值用于定义数据类型值 true false null 

2、标识符

标识符的定义

  • Java命名各种变量、方法和类别元素时使用的字符序列称为标识符

技巧:任何能命名的地方都叫标志符

合法标识符规则的定义

  • 0-9,有26个英文字母,_或$组成
  • 数字不能开头
  • 不可以使用关键字和保留字,但能包含关键字和保留字
  • Java严格区分大小写,长度无限
  • 标识符不能包含空格

Java名称命名规范

  • 包名:多单词组成时所有字母都小写:xxxyyyzzz
  • 类名、界面名:当多个单词组成时,所有单词的首字母大写:XxxYyyZzz
  • 变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz
  • 常量名:所有字母都是大写的,每个单词都用下划线连接:XXX_YYY_ZZZ

注意点:
1.命名时,为了提高阅读性,要尽可能有意义,见名知意。
2、Java采用unicode字符集,所以汉字声明也可以用于标识符,但不建议使用。

3、变量

变量的概念

  • 内存中的一个存储区域
  • 该区域的数据可以在同一类型范围内不断变化
  • 变量是程序中最基本的存储单元,包括变量类型变量名存储的值

变量的作用

  • 在内存中保存数据

注意使用变量

  • Java使用前必须声明每个变量
  • 使用变量名访问该区域的数据
  • 变量作用域:定义一对{}
  • 变量只在其作用域内有效
  • 重名的变量不能在同一功能域定义

变量的分类

按数据类型进行分类

  • 基本数据类型
    • 数值型
      • 整数类型 (byte short int long)
      • 浮点类型 (float double)
    • 字符型 (char)
    • 布尔型 (boolean)
  • 引用数据类型
    • (class)
    • 接口 (interface)
    • 数组 ([])

按声明位置分类

  • 成员变量
    • 实例变量 (不以static修饰)
    • 类变量 (以static修饰)
  • 局部变量
    • 形参 (构造器中定义的方法和变量)
    • 局部变量的方法 (方法内部定义)
    • 局部变量代码块 (在代码块中定义)

整数变量:byte、short、int、long

  • Java每个整数类型都有固定的表数范围和字段长度,不受具体影响OS保证影响Java可移植程序。
  • Java默认为int型,声明long型常量须加l或者L
  • Java变量通常在程序中声明int型号,除非不足以表示较大的数字,否则只能使用long
类型 占用存储空间 表数范围
byte 1字节=8bit位 -128~127
short 2字节 - 2 15 2^{15} 215~ 2 15 2^{15} 215-1
int 4字节 - 2 31 2^{31} 231~ 2 31 2^{31} 231-1(约21亿)
long 8字节 - 2 63 2^{63} 263~ 2 63 2^{63} 263-1

bit:计算机中的最小存储单位。byte:计算机中基本存储单元。

浮点类型:float、double

  • 与整数类型类似,Java浮点类型也有固定的表数范围和字段长度,不受具体操作系统的影响
  • 浮点型常量有两种表示形式:
    • 十进制数形式
    • 科学计数法形式
  • float:单精度,尾数可以精确到7位有效数字。很多情况下,精度很难满足需求。
  • double:双精度,精度是float的两倍。通常采用此类型。
  • Java的浮点型常量默认是double型,声明float型常量,须后加fF
类型 占用存储空间 表数范围
float 4字节 -3.403E38~3.403E38
double 8字节 -1.798E308~1.798E308

注意点:float表示数值的范围比long还大

字符类型:char

  • char型数据用来表示通常意义上“字符”(2字节)
  • Java中所有字符都使用Unicode编码,故一个字符可以存储一个字母,一个汉字,或其他书面语的一个字符。
  • 字符型变量的三种表现形式:
    • 字符常量是用单引号’'括起来的单个字符。
    • Java中还允许使用转义字符’\'来将其后的字符转变为特殊字符型常量。
    • 直接使用Unicode值来表示字符型常量。
  • char类型是可以进行运算的。因为它都对应有Unicode编码。
char c1 = 'a'; // 编译通过
// char c2 = 'AB'; // 编译不通过
char c3 = '中'; // 编译通过
char c4 = '\n'; // 编译通过
char c5 = '\u0043'; // 编译通过
// char c6 = ''; // 编译不通过
char c7 = 97; // a, 开发中极其少见

常用ASCII码值: ‘a’ == 97; ‘A’ == 65;

布尔型:boolean

  • 只能取两个值之一:true、false
  • 常常在条件判断、循环结构中使用

基本数据类型转换

  • 自动类型转换:容量小的类型自动转换为容量大的数据类型。数据类型按容量大小排序为:char、byte、short --> int --> long --> float --> double
  • 有多种类型的数据混合运算时,系统首先自动将所有数据类型转换为容量最大的那种数据类型,然后再进行计算
  • byte,short,char之间不会互相转换,他们三者在计算时首先转换为int类型

Java在做运算的时候,如果操作数均在int范围内,那么一律在int的空间内运算。

  • boolean类型不能与其它数据类型运算
  • 当把任何基本数据类型的值和字符串(String)进行连接运算时(+),基本数据类型的值将自动转化为字符串(String)类型

说明:此时的容量大小指的是表示数的范围的大小。比如:float容量要大于long的容量

强制类型转换

  • 自动类型转换的逆过程,将容量大的数据类型转换为容量小的数据类型。使用时要加上强制转换符:(),但可能造成精度降低或溢出,格外要注意
  double d1 = 12.9;
  int i1 = (int)d1; // 12,截断操作

  int i2 = 128;
  byte b = (byte)i2; // -128
  • 通常,字符串不能直接转换为基本类型,但通过基本类型对应的包装类则可以实现把字符串转换为基本类型
  String a = "43";
  int i = Integer.parseInt(a);
  • boolean类型不可以转换为其它的数据类型

说明:整型常量,默认类型是int型;浮点型常量,默认类型是double型。

  byte b = 12;
  // byte b1 = b + 1; // 编译失败
  // float f1 = b + 12.3; // 编译失败

字符串类型:String

  • String不是基本数据类型,属于引用数据类型
  • 使用方式与基本数据类型一致。
  • 一个字符串可以串接另一个字符串,也可以直接串接其他类型的数据。
  String str = "abcd";
  str = str + "xyz";
  int n = 100;
  str = str + n; // abcdxyz100

4、进制

  • 所有数字在计算机底层都是以二进制形式存在。
  • 对于整数,有四种表示方式:
    • 二进制(binary):0,1,满2进1,以0b0B开头
    • 十进制(decimal):0-9,满10进1
    • 八进制(octal):0-7,满8进1,以数字0开头表示
    • 十六进制(hex):0-9及A-F,满16进1,以0x0X开头表示。此处的A-F不区分大小写。
  • Java整数常量默认是int类型,当用二进制定义整数时,其第32位(最高位)是符号位:当是long类型时,二进制默认占64位,第64位是符号位
  • 二进制的整数有如下三种形式:
    • 原码:直接将一个数值换成二进制数。最高位是符号位
    • 负数的反码:是对原码按位取反,只有最高位(符号位)确认为1
    • 负数的补码:其反码加1
  • 计算机以二进制补码的形式保持所有的整数
    • 正数的原码、反码、补码都相同
    • 负数的补码是其反码+1

5、运算符

运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。

  • 算术运算符
  • 赋值运算符
  • 比较运算符(关系运算符)
  • 逻辑运算符
  • 位运算符
  • 三元运算符

算术运算符

运算符 运算 范例 结果
+ 正号 +3 3
- 负号 b=4; -b -4
+ 5+5 10
- 6-4 2
* 3*4 12
/ 5/5 1
% 取模(取余) 7%5 2
++ 自增(前),先运算后取值 a=2;b=++a; a=3;b=3
++ 自增(后),先取值后运算 a=2;b=a++; a=3;b=2
自减(前),先运算后取值 a=2;b=–a; a=1;b=1
自减(后),先取值后运算 a=2;b=a–; a=1;b=2
+ 字符串连接 “He”+“llo” “Hello”

疑难点1:%取余运算,结果的符号与被模数的符号相同

int m1 = 12;
int n1 = 5;
System.out.println("m1 % n1 = " + m1 % n1); // m1 % n1 = 2
int m2 = -12;
int n2 = 5;
System.out.println("m1 % n1 = " + m2 % n2); // m1 % n1 = -2
int m3 = 12;
int n3 = -5;
System.out.println("m1 % n1 = " + m3 % n3); // m1 % n1 = 2
int m4 = -12;
int n4 = -5;
System.out.println("m1 % n1 = " + m4 % n4); // m1 % n1 = -2

疑难点2:++ 和 – 不会改变变量本身的数据类型

short s = 10;
//s = s + 1; //编译失败
s = (short) (s + 1); //正确
s++; //正确

byte b = 127;
b++;
System.out.println(b); //-128

赋值运算符

符号:= 拓展赋值运算符:+=,-=,*=,/=,%=

  • =两侧数据类型不一致时,可以使用自动类型转换或使用强制类型转换原则进行处理
  • 支持连续赋值
int i, j;
//连续赋值
i = j = 10;

疑难点:拓展赋值运算符不会改变变量本身的数据类型

short s = 10;
//s = s + 2; //编译失败
s += 2;
System.out.println(s); //12
int i = 1;
i *= 0.1;
System.out.println(i); // 0

比较运算符

运算符 运算 范例 结果
== 相等于 4==3 false
!= 不等于 4!=3 true
< 小于 4<3 false
> 大于 4>3 true
<= 小于等于 4<=3 false
>= 大于等于 4>=3 true
instanceof 检查是否是类的对象 “Hello” instanceof String true
  • 比较运算符的结果都是boolean型,也就是要么是true,要么是false。
  • 比较运算符==不能误写成=
  • > < >= <=:只能使用在数值类型的数据之间
  • ==:不仅可以使用在数值类型数据之间,还可以使用在其他引用类型变量之间。

逻辑运算符

&-逻辑与
|-逻辑或
!-逻辑非
&&-短路与
||-短路或
^-逻辑异或

a b a&b a&&b a|b a||b !a a^b
true true true true true true false false
true false false false true true false true
false true false false true true true true
false false false false false false true false

区分 & 与 &&

  • 相同点1:&与&&的运算结果相同
  • 相同点2:当符号左边为true时,二者都会执行符号右边的运算
  • 不同点:当符号左边为false时,&继续执行符号右边的运算,&&不再执行符号右边的运算

区分 | 与 ||

  • 相同点1:|与||的运算结果相同
  • 相同点2:当符号左边是false时,二者都会执行符号右边的运算
  • 不同点1:当符号左边是true时,|继续执行符号右边的运算,而||不再执行符号右边的运算

位运算符

运算符 运算 范例
<< 左移 3 << 2 = 12 --> 3*2*2=12
>> 右移 3 >> 1 = 1 --> 3/2=1
>>> 无符号右移 3 >>> 1 = 1 --> 3/2=1
& 与运算 6 & 3 = 2
| 或运算 6 | 3 = 7
^ 异或运算 6 ^ 3 = 5
~ 取反运算 ~6 = -7

位运算时直接对整数的二进制进行的运算

运算符 描述
<< 空位补0,被移除的高位丢弃,空缺位补0
>> 被移除的二进制最高位是0,右移后,空缺位补0,若最高位是1,空缺位补1
>>> 被移位二进制最高位无论是0或者是1,空缺位都用0补
& 二进制位进行&运算,只有1&1时结果是1,否则是0
| 二进制位进行|运算,只有0|0时结果是0,否则是1
^ 相同二进制进行^运算结果是0:1^1=0,0^0=0;不相同二进制位^运算结果是1:1^0=1,0^1=1
~ 各二进制码按补码各位取反

m = k ^ n = (m ^ n) ^ n

三元运算符

  • 格式:(条件表达式) ? 表达式1 : 表达式2;
  • 表达式1和表达式2为同种类型

三元运算符与if-else的联系与区别

  • 三元运算符可简化if-else语句
  • 三元运算符要求必须返回一个结果
  • if后的代码块可有多个语句

附加:运算符的优先级

. () {} ; ,
R–>L ++ -- ~ !(data type)
L–>R * / %
L–>R + -
L–>R << >> >>>
L–>R < > <= >= instanceof
L–>R == !=
L–>R &
L–>R ^
L–>R |
L–>R &&
L–>R ||
R–>L ? :
R–>L = *= /= %=
+= -= <<= >>=
>>>= &= ^= |=

6、程序流程控制

  • 程序控制语句是用来控制程序中各语句执行顺序的语句,可以把语句组合成能完成一定功能的小逻辑模块。
  • 其流程控制方式采用结构化程序设计中规定的三种基本流程结果,即:顺序结构、分支结构、循环结构

分支结构

if-else结构

  • else 结构是可选的
  • 针对与条件表达式:
    • 如果多个条件表达式之间是“互斥”关系(或没有交集的关系),哪个判断和执行语句声明在上面还是下面,无所谓。
    • 如果多个条件表达式之间有交集的关系,需要根据实际情况,考虑清楚应该将哪个结构声明在上面。
    • 如果多个条件表达式之间有包含关系,通常情况下,需要将范围小的声明在范围大的上面。否则,范围小的就没有机会执行
  • if-else 结构是可以互相嵌套的。
  • 如果if-else结构中的执行语句只有一行时,对应的一对{}可以省略的。但是,不建议大家省略。
  • 多个if-else时,if-else的配对方式采用就近原则进行配对

switch-case结构

switch(表达式){
  case 常量1:
    语句1;
    // break;
  case 常量2:
    语句2;
    // break;
  ... ...
  case 常量N:
    语句N;
    // break;
  default:
    语句;
    // break;
}
  • 根据switch表达式中的值,依次匹配各个case中的常量。一旦匹配成功,则进入相应的case结构中,调用其执行语句。当调用完执行语句以后,则仍然继续向下执行其他case结构中的执行语句,直到遇到break关键字或此switch-case结构末尾结束为止。
  • break,可以使用在switch-case结构中,表示一旦执行到此关键字,就跳出switch-case结构
  • switch结构中的表达式,只能是如下的6种数据类型之一:byte、short、char、int、枚举类型(JDK5.0新增)、String类型(JDK7.0新增)
  • case 之后只能声明常量,不能声明范围。
  • break 关键字是可选的
  • default:相当于if-else结构中的else。default结构是可选的,而且位置是灵活的。
int number = 0;
// Console: zero
switch(number) {
  default:
    System.out.println("other");
  case 0:
    System.out.println("zero");
    break;
  case 1:
    System.out.println("one");
    break;
}
  • 凡是可以使用switch-case的结构,都可以转换为if-else。反之,不成立。
  • 当发现既可以使用switch-case且switch中表达式的取值情况不太多,又可以使用if-else时,我们优先选择使用switch-case。原因:switch-case执行效率稍高。

循环结构

循环语句的四个组成部分

  • 初始化部分
  • 循环条件部分
  • 循环体部分
  • 迭代部分

for循环结构

for(初始化部分;循环条件部分;迭代部分) {
  循环体部分
}

执行过程:初始化部分-循环条件部分-循环体部分-迭代部分-循环条件部分-循环体部分-迭代部分- ... - 循环条件部分

while循环结构

初始化部分
while(循环条件部分) {
  循环体部分
  迭代部分
}

执行过程:初始化部分-循环条件部分-循环体部分-迭代部分-循环条件部分-循环体部分-迭代部分- ... - 循环条件部分
  • 写while循环千万小心不要丢了迭代条件。一旦丢了,就可能导致死循环!
  • 写程序需要避免出现死循环。
  • for循环和while循环是可以相互转换的。区别在于for循环和while循环的初始化条件部分的作用范围不同。

do-while循环结构

初始化部分
do{
  循环体部分
  迭代部分
}while(循环条件部分);

执行过程:初始化部分-循环体部分-迭代部分-循环条件部分-循环体部分-迭代部分- ... - 循环条件部分
  • do-while循环至少会执行一次循环体!
  • 开发中,使用for和while更多一些。较少使用do-while

特殊关键字的使用

适用范围 不同点 相同点
break switch-case和循环结构中 结束当前循环 关键字后面不能声明执行语句
continue 循环结构中 结束当次循环 关键字后面不能声明执行语句
label: for(int i = 1; i <= 4; i++) {
          for(int j = 1; j <= 10; j++) {
            if (j % 4 == 0) {
              //break; //默认跳出包裹此关键字最近的一层循环
              //continue;
              
              //break label; //结束指定标识的一层循环结构
              continue label; //结束指定标识的一层循环结构当次循环
            }
          }
        }
  • return:并非专门用于结束循环的,它的功能是结束一个方法。当一个方法执行到一个return语句时,这个方法将被结束。
  • 与break和continue不同的是,return直接结束整个方法,不管这个return处于多少层循环之内

7、数组

  • 数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。
  • 数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
  • 创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址。
  • 数组的长度一旦确定,就不能修改。
//1.一维数组的声明和初始化		
int[] ids;//声明
//1.1静态初始化:数组的初始化和数组元素的赋值操作同时进行
ids = new int[]{1001,1002,1003,1004};
//1.2动态初始化:数组的初始化和数组元素的赋值操作分开进行
String[] names = new String[5];

数组元素的默认初始化值

  • 数组元素是整型:0
  • 数组元素是浮点型:0.0
  • 数组元素是char型:0或者’\u0000’,而非’0’
  • 数组元素是boolean型:false
  • 数组元素是引用数据类型:null

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

//一些错误的写法
//int[] ids;
//ids = {1,2,2}; //编译错误
//一些正确但是不标准的写法
int[] arr1 = {1,2,2,3}; //类型推断
int[] arr2[] = new int[][]{
    
       {1,2,2},{4,5},{6,7,8}}; // 数组[]位置可以随意
int[] arr3[] = {
    
       {1,2,2},{4,5},{6,7,8}};
String[] strArray1[] = {
    
       {"222", "2222"},{"111", "3333", "5555"}};

附加:Arrays工具类的使用

  • java.util.Arrays类即为操作数组的工具类,包含了用来操作数组的各种方法
方法 作用
boolean equals(int[] a,int[] b) 判断两个数组是否相等
String toString(int[] a) 输出数组信息
void fill(int[] a,int val) 将指定值填充到数组之中
void sort(int[] a) 对数组进行排序
int binarySearch(int[] a,int key) 对排列后的数组进行二分法检索指定的值

二、面向对象编程

1、面向过程与面向对象

面向过程(POP)与面向对象(OOP)

  • 二者都是一种思想,面向对象是相对于面向过程而言的。面向过程,强调的是功能行为,以函数为最小单位,考虑怎么做。面向对象,将功能封装进对象,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。
  • 面向对象更加强调运用人类在日常的思维逻辑中采用的思想方法与原则,如抽象、分类、继承、聚合、多态等。

面向对象的三大特征

  • 封装性
  • 继承性
  • 多态性

面向对象的思想概述

  • 程序员从面向过程的执行者转化成了面向对象的指挥者
  • 面向对象分析方法分析问题的思路和步骤:
    • 根据问题需要,选择问题所针对的现实世界的实体
    • 从实体中寻找解决问题相关的属性和功能,这些属性和功能就形成了概念世界中的类
    • 把抽象的实体用计算机语言进行描述,形成计算机世界中的类的定义。即借助某种程序语言,把类构造成计算机能够识别和处理的数据结构。
    • 类实例化成计算机世界中的对象。对象是计算机世界中解决问题的最终工具。

2、Java语言基本元素:类和对象

类和对象

  • 类(Class)和对象(Object)是面向对象的核心概念。
    • 类是对一类事物的描述,是抽象的、概念上的定义
    • 对象是实际存在的的该类事物的每个个体,因而也称为实例

类和对象的使用(面向对象思想落地的实现)

  • 创建类,设计类的成员
  • 创建类的对象
  • 通过"对象.属性"或"对象.方法"调用对象的结构

如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的(非static的)属性。意味着:如果我们修改一个对象的属性a,则不影响另外一个对象属性a的值。

对象的创建和使用:内存解析

  • 堆(Heap),此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配。
  • 通常所说的栈(Stack),是指虚拟机栈。虚拟机栈用于存储局部变量等。局部变量表存放了编译期可知长度的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型,它不等同于对象本身,是对象在堆内存的首地址)。方法执行完,自动释放。
  • 方法区(Method Area),用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据

3、类的成员之一:属性

属性(成员变量) VS 局部变量

  • 相同点
    • 定义变量的格式:数据类型 变量名 = 变量值
    • 先声明,后使用
    • 变量都有其对应的作用域
  • 不同点
    • 在类中声明的位置不同。属性直接定义在类的一对{}内;局部变量声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量
    • 关于权限修饰符的不同。属性可以在声明属性时,指明其权限,使用权限修饰符。常用的权限修饰符:private、public、缺省、protected。局部变量不可以使用权限修饰符。
    • 默认初始化值的情况
      • 属性:类的属性,根据其类型,都有默认初始化值。整型(byte、short、int、long):0;浮点型(float、double):0.0;字符型(char):0(或’\u0000’);布尔型(boolean):false;引用数据类型(类、数组、接口):null
      • 局部变量:没有默认初始值。意味着,我们在调用局部变量之前,一定要显式赋值。特别地,形参在调用时,我们赋值即可。
    • 在内存中加载的位置:属性加载在堆空间中(非static);局部变量加载在栈空间

4、类的成员之二:方法

方法的声明

权限修饰符 返回值类型 方法名(形参列表){
  方法体
}
// 注意:static、final、abstract来修饰的方法,后面再讲

返回值类型:有返回值 VS 没有返回值

  • 如果方法有返回值,则必须在方法声明时,指定返回值的类型。同时,方法中,需要使用return关键字来返回指定类型的变量或常量:“return 数据”。
  • 如果方法没有返回值,则方法声明时,使用void来表示。通常,没有返回值的方法中,就不需要使用return。但是,如果使用的话,只能“return;”表示结束此方法的意思。

return 关键字的使用

  • 使用范围:使用在方法体中
  • 作用:1、结束方法;2、针对于有返回值类型的方法,使用"return 数据"方法返回所要的数据。
  • 注意点:return关键字后面不可以声明执行语句。

方法的使用

  • 方法的使用中,可以调用当前类的属性或方法。特殊的,方法A中又调用了方法A:递归方法
  • 方法中不可以定义方法。

理解“万事万物皆对象”

  • 在Java语言范畴中,我们都将功能、结构等封装到类中,通过类的实例化,来调用具体的功能接口
    • Scanner, String等
    • 文件:File
    • 网络资源:URL
  • 涉及到Java与前端Html、后端的数据库交互时,前后端的结构在Java层面交互时,都体现为类和对象。

方法的重载(overload)

  • 重载的概念:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
  • 重载的特点:与返回值类型无关,只看参数列表,且参数列表必须不同(参数个数或参数类型)。调用时,根据方法参数列表的不同来区分。
// 返回两个整数的和
int add(int x, int y) {return x+y;}
// 返回三个整数的和
int add(int x, int y, int z) {return x+y+z;}
// 返回两个小数的和
double add(double x, double y) {return x+y;}

可变个数的形参

JavaSE 5.0中提供了Varargs(variable number of arguments)机制,允许直接定义能和多个实参相匹配的形参。从而,可以用一种更简单的方式,来传递个数可以变的实参。

// JDK 5.0以前:采用数组形参来定义方法,传入多个同一类型的变量
public static void test(int a, String[] books);
// JDK 5.0:采用可变个数形参来定义方法,传入多个同一类型变量
public static void test(int a, String...books);
  • 声明格式:方法名(参数的类型名…参数名)
  • 可变参数:方法参数部分指定类型的参数个数是可变多个:0个,1个或多个
  • 可变个数形参的方法和同名的方法之间,彼此构成重载
  • 可变参数方法的使用与方法参数部分使用数组是一致的
  • 方法的参数部分有可变形参,需要放在形参声明的最后
  • 在一个方法的形参位置,最多只能声明一个可变个数形参
public static void main(String[] args) {
  DemoTest test = new DemoTest();
  test.show(12); // show(int i)
  test.show("hello"); // show(String s)
  test.show("hello","hello"); // show(String ... s)
  test.show(); // show(String ... s)
  test.show(new String[] {"AA", "BB", "CC"}); // show(String ... s)
}

public void show(int i) {
  System.out.println("show(int i)");
}

public void show(String s) {
  System.out.println("show(String s)");
}

public void show(String ... s) {
  System.out.println("show(String ... s)");
}

方法参数的值传递机制

Java的实参值如何传入方法呢?

  • Java里方法的参数传递方式只有一种:值传递。即将实际参数值的副本(复制品)传入方法内,而参数本身不受影响。
    • 形参是基本数据类型:将实参基本数据类型变量的“数据值”传递给形参
    • 形参是引用数据类型:将实参引用数据类型变量的“地址值”传递给形参
int[] arr = new int[] {1,2,3};
System.out.println(arr); //地址值
char[] arr1 = new char[] {'a', 'b', 'c'};
// println()方法被重载,所以输出的不是地址值
System.out.println(arr1); //abc

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

四种访问权限修饰符

  • Java权限修饰符public、protected、private置于类的成员定义前,用来限定对象对该类成员的访问权限
修饰符 类内部 同一个包 不同包的子类 同一个工程
private Yes
(缺省) Yes Yes
protected Yes Yes Yes
public Yes Yes Yes Yes

对于class的权限修饰只可以用public和default(缺省)。

  • public类可以在任意地方被访问。
  • default类只可以被同一个包内部的类访问。

什么是封装性?

  • 隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可拓展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露的暴露出去。这就是封装性的设计思想。

封装性的体现

  • Java规定的四种权限(从小到大排列):private、缺省、protected、public
  • 4种权限可以修饰类及类的内部结构:属性、方法、构造器、内部类
  • 具体的,4中权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类;修饰类的话,只能使用:缺省、public

总结:Java提供了4种权限修饰符来修饰类及类的内部结构,体现类及类的内部结构在被调用时的可见性的大小

6、类的成员之三:构造器

构造器的作用

  • 创建对象
  • 初始化对象的信息

说明

  • 如果没有显示的定义类的构造器的话,则系统默认提供一个空参的构造器,默认构造器的权限修饰符与类修饰符一致
  • 定义构造器的格式:权限修饰符 类名(形参列表){}
  • 一个类中定义的多个构造器,彼此构成重载
  • 一旦我们显式的定义了类的构造器之后,系统就不再提供默认的空参构造器
  • 一个类中,至少会有一个构造器

属性赋值的过程

  • 默认初始化
  • 显式初始化
  • 构造器中的初始化
  • 通过“对象.属性”或“对象.方法”的方式赋值

7、拓展知识

JavaBean

  • JavaBean是一种Java语言写成的可重用组件。
  • 所谓JavaBean,是指符合如下标准的Java类:
    • 类是公共的
    • 有一个无参的公共的构造器
    • 有属性,且有对应的get、set方法

UML类图

  • +表示public类型,-表示private类型,#表示protected类型
  • 方法的写法:方法的类型(+、-) 方法名(参数名: 参数类型): 返回值类型
  • 属性::前是属性名,:后是属性的类型

8、关键字:this

  • this可以用来修饰、调用:属性、方法、构造器
  • this修饰属性和方法时可以理解为:当前对象或当前正在创建的对象
    • 在类的方法中,我们可以使用“this.属性”或者“this.方法”的方式,调用当前对象属性或方法。但是通常情况下,我们都选择省略"this."。特殊情况下,如果方法的形参和类的属性同名时,我们必须显示的使用“this.变量”的方式,表明此变量是属性,而非形参。
    • 在类的构造器中,我们可以使用“this.属性”或“this.方法”的方式,调用当前正在创建的对象属性或方法,但是通常情况下,我们都选择省略"this."。特殊情况下,如果构造器的形参和类的属性同名时,我们必须显式的使用“this.变量”的方式,表明此变量是属性,而非形参。
  • this调用构造器
    • 我们在类的构造器中,可以显式的使用“this(形参列表)”方式,调用本类中指定的其他构造器
    • 构造器中不能通过“this(形参列表)”方式调用自己
    • 如果一个类中有n个构造器,则最多有n-1个构造器中使用了“this(形参列表)”
    • 规定,“this(形参列表)”必须声明在当前构造器的首行,因此构造器内部,最多只能声明一个“this(形参列表)”,用来调用其他的构造器

9、关键字:package

  • 为了更好的实现项目中类的管理,提供了包的概念
  • 使用package声明类或接口所属的包,声明在源文件的首行
  • 包,属于标识符,遵循标识符的命名规则、规范(xxxyyyzzz)、“见名知意”
  • 每“.”一次,就表示一层文件目录

补充:同一个包下,不能命名同名的接口、类;不同包下,可以命名同名的接口、类。

10、关键字:import

  • 在源文件中使用import显示的导入指定包下的类或接口
  • 声明在包的声明和类的声明之间
  • 如果需要导入多个类或者接口,那么就并列显式多个import语句即可
  • 举例:可以使用java.util.*的方式,一次性导入util包下的所有的类或接口
  • 如果导入的类或接口是java.lang包下的,或者是当前包下的,则可以省略此import语句
  • 如果在代码中使用不同包下的同名的类。那么就需要使用类的全类名的方式指明调用的是哪个类
  • 如果已导入java.a包下的类。那么如果需要使用a包的子包下的类的话,仍然需要导入。
  • import static组合的使用:调用指定类或接口下的静态的属性或方法

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

继承性的好处

  • 减少了代码的冗余,提高了代码的复用性
  • 便于功能的拓展
  • 为之后多态性的使用,提供了前提

继承性的说明

  • 继承性的格式: class A extends B{}
  • 体现:一旦子类A继承父类B以后,子类A中就获取了父类B中的声明的所有的属性和方法。特别的,父类中声明为private的属性或方法,子类继承父类以后,仍然认为获取了父类中的私有的结构。只是因为封装性的影响,使得子类不能直接调用父类的结构而已。
  • 子类继承父类以后,还可以声明自己特有的属性或方法:实现功能的拓展

Java中关于继承性的规定

  • 一个类可以被多个子类继承
  • Java中类的单继承性:一个类只能有一个父类
  • 子父类是相对的概念
  • 子类直接继承的父类称为直接父类;间接继承的父类称为间接父类
  • 子类继承父类以后,

相关文章