java语言基础.docx
《java语言基础.docx》由会员分享,可在线阅读,更多相关《java语言基础.docx(14页珍藏版)》请在冰豆网上搜索。
![java语言基础.docx](https://file1.bdocx.com/fileroot1/2023-1/21/236d0236-d5ab-4d20-971b-c3c0f353c400/236d0236-d5ab-4d20-971b-c3c0f353c4001.gif)
java语言基础
1.基本数据类型
1.1Java的基本数据类型
Java支持的基本数据类型为:
int,long,short(整型);double,float(浮点类型);char(字符型);boolean(布尔型);void(空型)。
在java程序设计中多数情况用int定义整型变量,用double定义带小数的数据类型。
2.1基本数据类型
常量即基本数据类型的数据值的直接表示,java支持的常量格式为:
int,short(只包含数字);
long(与int型类似,但必须带后缀L);
double(包含小数点的资料或以科学计数法表示数值);
float(与double型类似,但必须后缀F);
char(单一的编码字符或控制字符);
boolean(true或false);
此外,java还包括null类型,它一般作为对象的空引用。
Java的基本数据类型的缺点是:
Boolean和char型的值存储空间小,但用途有限,因其值不能进行一般运算;
整型数据的值有效范围小,但指令周期很快,且是精确的;
Double型的值有效范围大,但指令周期慢,且结果不是精确的(包含舍入误差);
2.变量的声明和保存
2.1变数的命名
变量的命名必须符合变量的命名规则:
一个变量名必须以字符、‘$’或底线开始,其后可为字符或数字或底线,但不能包含空格,关键词不能作为变量名。
变量名区分大小写。
2.2变数的声明
定义一个特定类型的变量的语法为:
类型变量名1,变量名2,…,变量名n;
类型为基本数据类型之一,变量可在一个java程序的任何地方定义。
2.3变数的赋值
Java程序用“=”来表示给变量赋值,语法为:
变量名1=变量名2=…=表达式;
变量赋值即将右边的表达式的值赋给左边的变量,应该注意的是,值域较小的类型的变量值可以赋给值域较大的类型的变量,可同时给同类型的多个变量赋值:
类型变量名1=表达式1,变量名2=表达式2,…;
赋值时要保持变量的类型和值的类型一致或相容:
表2-1
变量类型
与之相容的类型
double
double
Int
int,double
Char
char,int,double
boolean
boolean
使用技巧:
使用的变量能定义成直观的变量名,增强程序的可读性;
应尽量定义变量的同时给变量赋值,若没有赋值,则成员变量和数值类型变量将为默认值0,boolean型变量为默认值false,其他类型的变量为默认值null,当使用局部变量时,此时编译会提示没有对其初始化。
变量尽可能的在被使用的地方附近定义。
3.数值类型的运算
3.1数值类型的基本运算
Java基本运算符有:
+(加),-(减),*(乘),/(除),%(求余)。
它们的优先级不同,但都为双目运算符。
3.2位运算
位运算符是对二进制位进行运算,操作数应为整数类型,结果也为整数类型。
位逻辑运算符和位算术运算符如下表3-1所示:
表3-1
位运算符
操作
位逻辑运算符
~
按位取反
&
与运算
|
或运算
^
异或运算
位算术运算符
<<
算术左移
>>
算术右移
>>>
逻辑右移
3.3数值类型的高级运算
Java提供大量的数学函数,数学函数的引用格式是“Math.”+函数名,除非特殊指明,否则函数返回值类型为double型。
Java提供的数学常量如表3-2所示:
表3-2
Math.E
自然对数e
Math.PI
圆周率
Double.POSITIVE_INFINITY
double型的正无穷
Double.NEGATIVE_INFINITY
double型的负无穷
Double.NaN
非数值(Not-a-Number)的表示
4.快捷运算符和类型转换
4.1增量和减量运算符
Java提供增量运算符++和减量运算符--。
可作为int,double和char型的变量的前(后)缀。
作为前缀时,首先变量+1或-1运算,然后所得的值在表达式中参与运算;作为后缀时,变量先参与运算,然后变量+1或-1运算。
i++比相同功能的表达式i=i+1运算快,但使用过多会降低程序的可读性,尽量避免在同一个表达式中同时使用增量(减量)和赋值操作符。
4.2简洁的计算操作符
Java提供的间接操作符:
+=,-=,*=,/=,%=。
+=和-=都是普遍使用且效率较高的运算符。
4.3简单的类型转换
将变量值的类型从一种转换成另一种。
如将类型A转换成类型B方法如下:
(类型B)类型A的表达式;
较大范围的数值类型可以匹配成较小类型的数值,但精度会降低;而较小范围的数值类型可以匹配成较大类型的数值。
类型匹配尽可能表达明确,不要依赖潜在的类型转换。
还有,尽可能避免将较大类型转换成较小类型,一般至少要用数值运算函数ceil,floor和round来确定数值不会损失太多的精确度。
5.逻辑和比较
5.1逻辑运算符
Java提供逻辑操作符来连接布尔变量和值:
&&(逻辑与),||(逻辑或),!
(逻辑非)。
&&(逻辑与)和||(逻辑或)连接复合逻辑语言从左到右依次执行,直到得到最终结果。
这些操作符主要用于测试和比较,&&和||具有短路功能:
&&的第一个操作数若为false,则不用检查第二个操作数,输出结果为false;||的第一个操作数若为true,则不用检查第二个操作数,输出结果为true。
5.2比较操作符及测试
比较操作符:
>、>=、<、<=、==、!
=
形式:
表达式比较操作符表达式;
不能将赋值符号“=”来替换比较操作符“==”,否则编译会出错。
使用“==”时,应注意其两边的类型必须一致,否则编译将出错。
对double等类型的数值进行比较时也很容易出现以外错误,因其类型的数值不精确。
5.3instanceof运算符
操作符instanceof按下列方法来确定一个引用变量是否为特定的类类型,其返回结果为true或false:
变量名instanceof类类型。
6.字符串操作
6.1字符串类String
字符串即字符的序列,定义的方法为:
Strings1=“Hellojava!
”;或Strings2=newString(“Hellojava!
”);
一般用“+“来对字符串进行连接和添加。
字符串长度是从0开始计算的,若一个字符串的字符数为N,即字符串长度为N,则该字符串的最后一个字符的位置为N-1。
String类型不是java提供的基本数据类型,所以不能用逻辑运算符来进行运算,但可以用java提供的equals或compareTo来比较两个字符串。
6.2字符串的内部操作符
每个字符串变量都可用“.“来引用,语法形式为:
字符串变量名.操作(输入值);
String类的部分操作如表6-1所示:
表6-1
操作
含义
Intlength()
返回串长度
CharcharAt(intindex)
返回指定下目标字符
Booleanequals(Strings)
若当前字符串与s相同则返回true
BooleanequalsIgnoreCase(Strings)
同equals,但忽略字符串的大小写
IntcompareTo(Strings)
若当期字符串与s相同则返回0,在字典序上小于s则返回负数,否则返回大于0的数
BooleanstartsWith(Stringprefix)
检查当前字符串是否以prefix为前缀
BooleanendsWith(Stringsuffix)
检查当前字符串是否以suffix为后缀
IntindexOf(Stringstr)
返回str在字符串中首次出现的位置,否则返回-1
Stringsubstring(intbegin,intend)
返回从begin开始到end-1之间的字符串
Stringreplace(Stringold,Stringnew)
用新的字符串替换老的字符串,并返回值
StringtoLowerCase()
将字符串改为小写并作为返回值
StringtoUpperCase()
将字符串改为大写并作为返回值
Stringtrim()
将字符串的首尾的空串去掉并作为返回值
6.3StringBuffer
StringBuffer是一个可变的字符串序列,其长度和组成元素为可变。
语法形式为:
StringBuffersb=newStringBuffer(“字符串序列“);
String类的+操作符实际上是先转换成StringBuffer的append和toString运算。
StringBuffer类的部分方法如表6-2所示:
表6-2
操作
含义
append(typet)
在原字符串后端追加t,t为任何类型
insert(intpos,typet)
在pos位置处插入t
delete(intstart,intend)
删除从start到end-1之间的字符
deleteCharAt(intpos)
删除pos处的字符
setCharAt(intpos,charch)
设置pos处的字符为ch
replace(intstart,intend,Stringstr)
用字符串str替换从start到end间的字符串
intlength()
返回当前存储的字符串个数
StringtoString()
将StringBuffer作为字符串返回
在需要字符串操作时,选择的依据为:
若需要对字符串进行添加或删除时,选择StringBuffer类;
若需要保证字符串的稳定时,选择String类;
7.数组
7.1声明数组
数组即一组顺序存储的同类型的固定数据结构。
数组用空括号声明,语法形式为:
类型数组名[];或类型[]数组名;
数组变量的默认值为null。
数组不论其中的元素是什么类型,它本身是引用类型变量,可被用作成员变量或局部变量,或者是方法的输入参数和返回值。
在声明中可不指定数组的大小,但在使用数组时必须指定其大小,以便向操作系统申请适当的内存空间。
7.2初始化数组
初始化数组前要先声明数组,初始化要指定数组的大小,语法形式为:
数组名=new类型[长度];
同时对数组进行声明并初始化的语法形式为:
类型数组名=new类型[长度];默认值为null
指定数组中的元素的值:
类型数组名[]={元素1,元素2,…,元素n};其中{}中的元素同类型
数组类型,输出存储数据的内存伪地址,除非变量指针指向null。
在程序开发中可利用System.out.println方法检查数组元素的状态,以确定初始化是否正确。
7.3访问数组的元素
数组的下标从0开始,数组长度为N的最后一个元素的下标为N-1;访问数组中的某个元素的语法形式为:
数组名[下标值];
每个数组都包含一个成员变量length,在初始化时设定数组的大小,可通过下列方法访问length变量:
数组名.length;
7.4数组作为方法的参数
数组可作为方法的输入参数和返回值,因数组是一个引用变量,所以在就将其作为方法输入参数时,必须注意它的特殊之处。
作为方法的输入时应注意:
声明时必须用方括号,并不能指定其大小;
在方法体内改变其数据元素则在方法体外可见;
8.注意点
(1)Java中字符串占用的存储空间为两个字节;
(2)If判断语句,个循环判断语句都必须为布尔型;
(3)只有成员变量,系统才自动赋默认值,字符串String变量必须对其初始化;
(4)数组为引用类型;
(5)String类型具有不可变性,因其不是基本的数据类型,在程序中不能随意对已初始化的String变量进行创建新的String变量值,但StringBuffer类型具有可变性,可随意更改其值;
(6)测试等于和赋值的类型匹配相反;
(7)局部变量一定要先初始化,再使用;
(8)Switch语句必须由一整型变量控制,if…else和if的复合语句允许在if之后跟任何类型的条件表达式;
(9)使用带标签的break语句可同时跳出两个或多个循环;
(10)跟踪:
程序员把自己模拟为计算机,执行程序的每一步,跟踪每个变量的值的改变情况。
可以在程序中插入适当的显示语句,以显示某些变量的执行结果,这个过程实际上就是调试过程。
(11)逻辑操作符&和|可操作布尔型和数值型,但不会产生短路;条件操作&&和||只能操作布尔型,但可以产生短路。
面向对象程序设计:
1.继承
1.1继承的概念
继承是一个类与别的类相关联的机制,它使一个类具有其他类的特征,被继承的类被称为超类(superclass)或父类,继承得到的类被称为子类(subclass)或派生类。
用关键词extends表示,语法如下:
[访问机制(modifier)]classSubClassNameextendsSuperClassName;
子类自动拥有超类的非私有成员和成员方法。
1.2继承的层次性
修改祖先类(即超类)代码,则其相关的派生类(即子类)也将同时被修改。
1.3继承的使用
子类所需的成员在超类中必须是非私有的,因为子类不能继承超类中的私有成员,但可以通过在超类中使用公有的set/get方法来访问其私有成员变量。
1.4继承的概念
当一个类被实例化(即创建类的对象)时,它的构造方法将被自动调用。
当一个子类被实例化时,它的子类和超类的构造方法都被自动地调用。
为避免隐秘地调用超类的构造方法,可以使用一下两种解决方法:
(1)每个子类都应明确地调用超类的一个构造方法,且必须在第一行调用;
(2)为每个可能成为超类的类提供一个无参的构造方法,如需要还得重载构造方法;
2.覆盖
2.1覆盖的概念
有时超类的构造的方法和变量不一定适合子类,在此情况下,子类可以对这些变量和方法进行重新定义,即所谓的覆盖。
覆盖后的方法,如还想访问子类中被子类覆盖的方法时,必须在此方法名前加关键词super和.来访问(即super.OverlapFunctionName)。
覆盖成员方法比重载方法更普遍,但应尽量避免覆盖成员变量,规则如下:
(1)若一个超类的方法不适合子类,则可在子类中使用与超类一样的方法头部进行覆盖,若继承来的方法还能使用,则可通过使用super关键词来访问;
(2)若重定义的方法的参数列表与超类中该方法的列表不一致时,则应该在超类中重载而不是在子类中覆盖;
(3)覆盖一个类的基本功能可能会造成一些问题,使代码难以理解。
若有许多变数要覆盖,则表明不应该从该超类中继承子类。
3.抽象
3.1抽象的概念
超类很抽象,只有某些行为的概念,不知道其具体要实现的方法,在这种情况下,类可以只提供一个方法的声明,但没有具体的实现,这样的类就称为抽象类。
3.2抽象方法和抽象类
抽象方法只有方法的声明,而没有方法的实现。
使用关键词abstract定义一个方法为抽象类。
拥有抽象方法的类是一个抽象类。
定义如下:
[public]abstractclassClassName[extendsName]
{
[modifier]abstractreturnTypemethodName(inputParameters);
抽象类不能进行实例化(即不能创建对象)。
声明一个抽象方法无需实现该方法,但必须确保在它的所有子类中实现该方法。
对实际应用问题进行抽象时按照以下几个原则进行创建java类:
(1)将一个现实世界的实体当作一个类进行处理,每个待出来的实体当作单独的一个类;
(2)对每个实体用(what’s、whattohave和whattodo)短语描述这个类的属性、成员变量,成员方法和它们之间的关系;
(3)确保每个类尽可能小,且方法简单;
(4)利用已有的泪,且使用覆盖、重载和继承来减少代码量;
(5)以包含main方法为主要的类,但大部分功能则由其他的类来完成;
(6)一个好的面向对象程序应像一个现代公司,普通类尽可能的独立;主类则必须了解每个普通类的功能以适当的分配和调用;最后实际的工作都交给普通类去完成。
3.3最终的方法和最终的类
最终方法,即不能被覆盖的方法。
最终类,即不可扩展的类。
一个类可以包含最终方法。
最终类和最终方法用关键词final声明,语法如下:
[public][final]className[extendsClassName]
{
[modifier][final]returnTypemethodName(inputParameters);
}
使用最终方法和最终类是为了保护类的完整性,假如Java的String类不是最终类,用户用自己设计的不好的String类将其代替则可能会导致整个java系统出现严重的问题,所幸Java的String类是最终类,因此不能从String类中派生出子类。
最常用关键词final的情况是常数,又由于static使该变量只存在一个备份,final使其不能改变,因此关键词final和static经常连用,用这些变量名来代替具体的常数值(如:
PI即圆周率常数)。
4.Java的基类Object
4.1基类Object概念
在Java中定义的每个类都源于一个叫Object的基类,且继承了该类所有的属性和方法。
其如下定义:
Publicclassjava.lang.Object
{
PublicObject();
PublicBooleanequals(Objectobj);
Protectedvoidfinalize();
PublicfinalvoidnotifyAll();
PublicStringtoString();
Publicfinalvoidwait(longtimeout);
}
每个Java类都为Object类的继承的两点好处如下:
(1)每个类都继承了Object类;
(2)每个类既为所定义的类类型,又属于Object类类型。
定义个Object类类型的数组,则它包含任何对象,在使用它包含的实际对象类型之前必须将其强制转换为实际类类型。
如果使用的方法为所有对象通用的方法则无需将对象进行强制转换。
5.界面
5.1多级继承与多重继承
多重继承:
一个超类的子类被另一个类继承。
Java支持这种多重继承。
多级继承:
一个类同时继承多个超类。
但Java不支持这种多重继承。
为弥补多重继承在Java中不能使用的缺点,Java提供了一个接口机制来代替它。
5.2界面
接口由一些抽象方法和常量所组成的集合。
接口保证了每个实现它的类都含该接口所声明的方法。
接口中的方法都默认为abstract,常量都默认为final。
一个接口不能用来实例化,因为它不是一个类。
接口一般应为public的访问机制,且能扩展其他的接口。
用关键词interface来定义,其语法格式如下:
PublicinterfaceInterfaceName[extendsInterfaceList]
一个类可通过关键词implements来继承一个或多个接口。
该类继承了接口中的抽象方法和常量,且除自身类型外,它还属于所继承的接口类型。
该类必须实现所继承的方法或被声明为abstract类。
其语法格式如下:
PublicclassClassName[extendsClass]implementsInterface1[,Interface2]
5.3接口的使用技巧
(1)如需要完成抽象的动作或具有概念型的属性时,那么在接口中定义该动作或概念;
(2)描述上一步的抽象方法的具体算法或流程,其在需要实现该接口的类中完成;
(3)在某个或多个类中使用第一步的方法或属性和第二步中提供的算法或流程。
6.多态性
6.1多态性的概念
多态性:
是面向对象程序设计中又一重要概念,它可以容易地在从超类继承来的新类上添加新功能。
多态性:
对象自动根据实际情况调用不同类层上适当的同名方法的一种现象。
在超类中使用抽象的方法,然后在子类中实现(或覆盖)该方法,这样就产生多态性。
如果在类中有多个被覆盖的方法,多态性会选择与对象类型最接近的方法。
7.注意点
(1)Java中实现多态的机制及重写和重载的区别:
●Java中实现多态的机制:
方法的重写Override和重载Overload是Java多态性的不同表现。
●重写和重载的区别:
重写Override是父类与子类间多态性的一种表现;重载Overload是一个类中多态性的一种表现。
(2)this和super的意义和作用:
●this表示当前对象的一个引用,利用this可使用当前对象的方法或域。
当一个类中的构造方法需要调用另一个构造方法时,可以使用关键词this,同时这个调用语句应为该构造方法的第一个可执行语句。
●Super是表示父类对象的关键词,super表示当前对象的直接父类,代表了当前父类对象的引用,利用super可使用父类的方法或域。
当一个类中的构造方法需要调用父类的一个构造方法时,使用super,同时这个调用语句应为该构造方法的第一个可执行语句。
(3)构造方法继承父类的原则:
●子类无条件地继承父类的无参数的构造方法;
●若子类未定义构造方法,则它将继承父类的无参构造方法作为自己的构造方法;
若子类定义了构造方法,则创建新对象时,将先执行继承自父类的无参数构造方法,然后再执行自己的构造方法;
●对于父类的带参数构造方法,子类可通过在自己的构造方法中使用super关键词来调用它,但这个调用语句必须是子类构造方法的第一个可执行语句;
●仅调用父类的无参构造方法;
●定义自己的一个或多个构造方法并调用父类的带参数的构造方法。
(4)域的隐藏和方法的覆盖的概念和区别:
●域的隐藏:
子类重新定义一个与从父类继承来的域变量完全相同的变量。
子类中定义了与父类同名的域变量,即子类变量对同名父类变数的隐藏。
●方法的覆盖:
子类重新定义从父类继承来的一个同名方法,此时子类将清除父类方法的影响,以此实现自身的行为;
●区别:
⏹子类隐藏父类的域只是使之不可见,父类的同名域仍占有自己独立的内存空间;
⏹子类发方法对父类同名方法的覆盖将清除父类的方法占用的内存空间,从而使父类方法在子类对象中不存在。
(5)方法的覆盖应注意的问题即原则:
●方法覆盖注意的问题:
⏹子类重新定义父类已有的方法时,应保持与父类完全相同的方法头部声明(即保持与父类有完全相同的方法名、返回类型和参数列表);
⏹在访问权限上只能放宽,否则编译将出错。
●方法覆盖的原则:
⏹覆盖方法的返回类型必须与它所覆盖的方法相同;
⏹覆盖方法不能比它所覆盖的方法的访问性差;
⏹覆盖的方法不能比它所覆盖的方法所抛出的异常多。
(6)有继承关系的父类对象和子类对象间可以在一定条件下互相转换,遵循的原则:
●子类对象可以被视为是父类的一个对象,反之不可;
●若一个方法的形参的类型是父类类型,则调用该方法的