#第 1 章 Java入门
1.1 Java的地位
Java具有面向对象,与平台无关,安全,稳定和多线程等优良特性,是目前软件设计中优秀的编程语言
注意:如果源文件中有 多个类,那么只能有一个类是public类。
1.9 小结
<1>Java语言是面向对象编程语言,编写的软件与平台无关。Java语言涉及网络,多线程等重要的基础知识,特别适合于Internet应用的开发。很多新的技术领域都涉及了Java语言,学习和掌握Java已成为共识。
<2>Java源文件是由若干个书写形式互相独立的类组成。开发一个Java程序需经过三个步骤:编写源文件,编译源文件生成字节码和加载运行字节码。
<3>编写代码务必遵守行业的习惯及风格。
#第 2 章 基本数据类型与数组
2.1 标识符与关键字
2.1.1 标识符
用来标识类名,变量名,方法名,类型名,数组名及文件名的有效字符序列称为标识符,简单地说,标识符就是一个名字。以下是Java关于标识符的语法规则。
——标识符由字母,下画线,美元符号和数字组成,长度不受限制。
——标识符的第一个字符不能是数字字符。
——标识符不能是关键字
——标识符不能是true,false和null。
注意:标识符中的字母是区分大小写的。
2.1.2 Unicode字符集
Java语言使用Unicode标准字符集,最多可以识别65536个字符。
2.1.3 关键字
关键字就是具有特定用途或被赋予特定意义的一些单词,不可以把关键字作为标识符来用,以下是Java的50个关键字:
abstract assert boolean break byte case catch char class const continue default do double else enum extends final finally float for goto if implements import instanceof int interface long native new package private protected public return short static strictfp super switch synchronized this throw throws transient try void volatile while
2.2 基本数据类型
逻辑类型:boolean
整数类型:byte,short,int,long
字符类型:char
浮点类型:float,double
2.2.1 逻辑类型
——常量:true
——变量:使用关键字boolean来声明逻辑变量,声明时也可以赋给初值。
2.2.2 整数类型
<1>int型
——常量:6000(十进制),077(八进制),0x3ABC(十六进制)
——变量:使用关键字int来声明int型变量。(int型变量分配4个字节)
<2>byte型
——常量:Java中不存在byte型常量的表示法,但可以把一定范围的int型常量赋值给byte型变量
——变量:使用关键字byte来声明byte型变量。(byte型变量分配1个字节)
<3>short型
——常量:和byte型类似,Java中也不存在short型常量的表示法,但可以把一定范围内的int型常量赋值给short型变量。
——使用关键字short来声明short型变量(short型变量分配2个字节)
<4>long型
——常量:long型常量用后缀L来表示。
——变量:使用关键字long来声明long型变量(long型变量分配8个字节)
注意:Java没有无符号的byte,short,int和long。
2.2.3 字符类型
——常量:‘A’,‘b’,‘?’,‘好’,‘ \t ’等,即用单引号(需要英文输入法输入)括起的Unicode表中的一个字符
——变量:使用关键字char来声明char型变量。(char型变量分配2个字节)
注意:
<1>在Java中,可以用字符在Unicode表中排序位置的十六进制转义(需要用u做前缀)来表示该字符,例如:‘\u0041’表示字符A。
<2>要观察一个字符在Unicode表中的顺序位置,可以使用int型类型转换。如:(int)‘A’
<3>如果要得到一个0~65535之间的数所代表的Unicode表中相应位置上的字符,必须使用char型类型转换,如(char)65
2.2.4 浮点类型
<1>float类型
——常量:453.5439分,21379.987F,231.0f(小数表示法),2e40f(指数表示法)(注意:常量后面必须要有后缀f或F)
——变量:使用关键字float来声明float型变量。(float变量在存储float型数据时保留8位有效数字,float型变量分配4个字节)
<2>double型
——常量:2389.539d,0.05(小数表示法),1e-90(指数表示法)。注意:对于double常量,后面可以有后缀d或D,但允许省略该后缀。
——变量:使用关键字double来声明double型变量。(double变量在存储double型数据时保留16位有效数字,double型变量分配8个字节)
2.3 类型转换运算
将这些类型按精度从低到高排列:
byte short char int long float double
<1>当把级别低的变量的值赋给级别高的变量时,系统自动完成数据类型的转换。例如:float x = 100; (输出x的值,结果将是100.0)
<2>当把级别高的变量的值赋给级别低的变量时,必须使用类型转换运算。
例如:int x= (int)34.89.(输出x的结果将是34)
<3>当把一个int型常量赋值给一个byte,short和char型变量,不可超出这些变量的取值范围,否则必须进行类型转换运算。
2.4 输入,输出数据
2.4.1 输入基本型数据
Scanner是JDK新增的一个类,可以使用该类创建一个对象:
Scanner reader = new Scanner(System.in)
package 第2章;
import java.util.Scanner;
public class Example2_3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("请输入若个数,每输入一个数回车确认");
System.out.println("最后输入数字0结束输入操作");
Scanner reader = new Scanner(System.in);
double sum = 0;
double x = reader.nextDouble();
while(x!=0) {
sum = sum + x;
x = reader.nextDouble();
}
System.out.println("sum="+sum);
}
}
2.4.2 输出基本数据
System.out.println()或System.out.print()可输出串值,表达式的值,二者的区别是前者输出数据后换行,后者不换行。允许使用并置符号+将变量,表达式或一个常数值与一个字符串并置一起输出。
注意:在使用System.out.println()或System.out.print()输出字符串常量时不可以出现“ 回车 ”,字符串太长,可以将字符串分解成几部分,然后使用并置符号+将它们首尾相接。
新增格式:System.out.printf(“格式控制部分”,表达式1,表达式2,…,表达式n)
2.5 数组
数组时相同类型的变量按顺序组成的一种复合数据类型,称这些相同类型的变量为数组的元素或单元。数组通过数组名加索引来使用数组元素
2.5.1 声明数组
声明一维数组:
数组的元素类型 数组名[ ];
数组的元素类型 [ ] 数组名;
声明二维数组:
数组的元素类型 数组名 [ ] [ ];
数组的元素类型 [ ] [ ] 数组名;
注意:可以一次声明多个数组。与C/C++不同,Java不允许在声明数组中的方括号内指定数组元素的个数。
2.5.2 为数组分配元素
为数组分配元素的格式如下:
数组名 = new 数组元素的类型[ 数组元素的个数 ]
声明数组和创建数组数组可以一起完成。例如:float boy[ ] = new float[ 4];
注意:构造二维数组的一维数组不必有相同的长度
2.5.3 数组元素的使用
一维数组通过索引符访问自己的元素。
2.5.4 length的使用
数组的元素个数称作数组的长度。对于一维数组,“ 数组名.length ”的值就是数组中元素的个数;对于二维数组“ 数组名.length ”的值是它含有的一维数组的个数。
2.5.5 数组的初始化
创建数组后,系统会给数组的每个元素一个默认值,如float型是0.0.
在声明数组的同时也可以给数组的元素一个初始值。
float boy[ ] = {21.3f,2.9f} 相当于 float boy[ ] =new float[ 2 ],boy[1]=21.3f,boy[2]=2 .9f。
2.5.6 数组的引用
数组属于引用型变量,因此两个相同类型的数组如果具有相同的引用,它们就有完全相同的元素。
注意:对于char型数组a,System.out.println(a)不会输出数组a的引用而是输出数组a的全部元素的值。如果想输出引用,就让数组和字符串作并置运算。例如:
System.out.println(" "+ a);
#第 3 章 运算符,表达式和语句
3.1 运算符与表达式
3.1.1 算术运算符与算术表达式
3.1.2 自增,自减运算符
自增,自减运算符++,–是单目运算符,可以放在操作元之前,也可以放在操作元之后。操作元必须是一个整型或浮点型变量,作用是使变量的值增1或减1.
++x(–x)表示在使用x之前,先使x的值增(减)1
x++(x–)表示在使用x之后,使x的值增(减)1
3.1.1 算术混合运算的精度
精度从“ 低 ”到“ 高 排列”的顺序是:
byte short char int long float double
<1>如果表达式中有双精度浮点数(double型数据),则按双精度进行运算。
<2>如果表达式中最高精度是单精度浮点型(float型数据),则按单精度进行运算。
<3>如果表达式中最高精度是long型整数,则按long精度进行运算。
<4>如果表达式中最高精度低于int型整数,则按int精度进行运算。
<5>Java允许把不超过byte,short和char的取值范围的算术表达式的值赋给byte,short和char型变量。
3.1.4 关系运算符与关系表达式
关系运算符的运算结果是boolean型,当运算符对应的关系成立时,运算结果是true,否则是false。
3.1.5 逻辑运算符与逻辑表达式
逻辑运算符包括&&,||,!.其中&&,||为二目运算符,实现逻辑与,逻辑或;!为单目运算符,实现逻辑非。逻辑运算符的操作必须是boolean型数据,逻辑运算符可以用来连接关系表达式。
注意:
逻辑运算符&&和||也称作短路逻辑运算符,这是因为当op1的值是false时,&&运算符在进行运算时不再去计算op2的值,直接就得出op1&&op2的结果是false,当op1的值是true时,||运算符在进行运算时不再去计算op2的值,直接就得出op1||op2的结果是true。
3.1.6 赋值运算符与赋值表达式
3.1.7 位运算符
<1>按位与运算
如果a,b两个数据对应位都是1,则c的该位是1,否则是0.如果b的精度高于a,那么结果c的精度和b相同
<2>按位或运算
如果a,b两个数据对应位都是0,则c的该位是0,否则是1.如果b的精度高于a,那么结果c的精度和b相同
<3>按位非运算
如果a对应位是0,则c的该位是1,否则是0.(单目运算符)
<4>按位异或运算
如果a,b两个数据对应位相同,则c的该位是0,否则是1.如果b的精度高于a,那么结果c的精度和b相同
3.1.8 instanceof运算符
该运算符是二目运算符,左面的操作元是一个对象,右面是一个类。当左面的对象是右面的类或子类创建的对象时,该运算符运算的结果是true,否则是false。
3.1.9 运算符综述
3.2 语句概述
3.3 if条件分支语句
3.3.1 if语句
if(表达式){
若干语句
}
注意:表达式的值必须是boolean类型;在if语句中如果只有一条语句,{}可以省略不写。
3.3.2 if—else语句
if—else语句的语法格式:
if(表达式){
若干语句
}
else{
若干语句
}
注意:表达式的值必须是boolean类型;在if—else语句中,其中的复合语句中如果只有一条语句,{}可以省略不写。
3.3.3 if—else if—else语句
if—else if—else语句的语法格式:
if(表达式){
若干语句
}
else if(表达式){
若干语句
}
.
.
.
else{
若干语句
}
注意:表达式的值必须是boolean类型。在if—else if—else语句中,其中的复合语句中如果只有一条语句,{}可以省略不写。
3.4 switch开关语句
switch语句是单条件多分支的开关语句,它的一般格式定义如下(其中break是可选的):
switch(表达式)
{
case 常量值 1:
若干语句
break;
case 常量值 2:
若干语句
break;
.
.
.
case 常量值 n:
若干语句
break;
default:
若干语句
}
注意:switch语句中“ 表达式 ”的值可以为byte,short,int,char型;“ 常量值1 ”到“ 常量值n ”也可以为byte,short,int,char型,而且要互不相同。
3.5 循环语句
3.5.1 for循环语句
for语句的一般语法格式:
for(表达式1;表达式2;表达式3){
若干语句
}
注意:表达式2必须是一个求值为boolean型数据的表达式,而复合语句又称为循环体。循环体只有一条语句时,大括号{}可以省略。
for语句的执行规则是:
<1>计算表达式1,完成必要的初始化工作。
<2>判断表达式2的值,若表达式2的值为true,则进行<3>,否则进行<4>。
<3>执行循环体,然后计算表达式3,以便改变循环条件,进行<2>。
<4>结束for语句的执行。
package 第3章;
//计算8+88+888+8888+...的前12项和
public class Example3_5 {
public static void main(String[] args) {
// TODO Auto-generated method stub
long sum = 0,a = 8,item = a,n = 12,i = 1;
for(i=1;i<=n;i++) {
sum = sum + item;
item = item*10 + a;
}
System.out.println(sum);
}
}
3.5.2 while循环语句
while语句的语法格式:
while(表达式){
若干语句
}
注意:表达式必须是一个求值为boolean型数据的表达式,而复合语句又称为循环体。循环体只有一条语句时,大括号{}可以省略。
while的执行规则是:
<1>计算表达式的值,如果该值是true时,就进行<2>,否则执行<3>。
<2>执行循环体,再进行<1>。
<3>结束while语句的执行。
3.5.3 do—while循环语句
do—while语句语法格式如下:
do{
若干语句
}while(表达式);
3.6 break和continue语句
break和continue语句是用关键字break或continue加上分号构成的语句。
如果在某次循环中执行了break语句,那么整个循环语句就结束。
如果在某次循环中执行了continue语句,那么本次循环就结束,即不在执行本次循环中循环体中continue语句后面的语句,而转入进行下一次循环。
3.7 for语句与数组
JDK 1.5对for语句的功能给予扩充,增强,以便更好的便历数组。语法格式如下:
for(声明循环变量:数组的名字){
…
}
注意:声明的循环变量的类型必须和数组的类型相同
3.8 应用举例
package 第3章;
import java.util.*;
public class Example3_9 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner reader = new Scanner(System.in);
double sum = 0;
int m =0;
while(reader.hasNextDouble()) {
double x = reader.nextDouble();
m = m + 1;
sum = sum + x;
}
System.out.printf("%d个数的和为%f\n",m,sum);
System.out.printf("%d个数的平均值是%f\n",m,sum/m);
}
}
#**第 4 章 类和对象**
4.1 编程语言的几个发展阶段
4.1.1 面向机器语言
4.1.2 面向过程的语言
4.1.3 面向对象的语言
面向对象编程主要体现下列三个特性:
<1>封装性
<2>继承
<3>多态
4.2 类
类是Java程序的基本要素,一个Java应用程序就是由若干个类所构成。类是Java语言最重要的“ 数据类型 ”,类声明的变量被称作对象变量。
类的定义包括两部分:类声明和类体。基本格式为:
class 类名{
类体的内容
}
注意:class是关键字,用来定义类。“ class 类名 ”是类的声明部分,类名必须是合法的Java标识符。两个大括号之间的内容是类体。
4.2.1 类声明
类的名字要符合标识符规定。给类命名时,遵守下列编程风格:
<1>如果类名使用拉丁字母,那么名字的首字母使用大写字母。
<2>类名最好容易识别,见名知意。
4.2.2 类体
类的目的是抽象出一类事物共有的属性和行为,并用一定的语法格式来描述所抽象出的属性和行为。
类体的内容由如下两部分组成:
<1>变量的声明:用来存储属性的值(体现对象的属性)。
<2>方法的定义:方法可以对类中声明的变量进行操作,即给出算法(体现对象所具有的行为)。
下面是一个类名为Lader的类,类体中的声明变量部分声明了4个float类型变量;方法定义部分定义了两个方法;
class Lader{
float above;
float bottom;
float height;
float area;
float computerArea() {
area = (above+bottom)*height/2.0f;
return area;
}
void setHeight(float h) {
height = h;
}
}
4.2.3 成员变量
类体的内容分为两部分:
<1>变量的声明。
<2>方法的定义。
1,成员变量的类型
成员变量的类型可以是Java中的任何一种数据类型,包括基本类型:整型,浮点型,字符型,逻辑类型;引用类型:数组,对象和接口。
2,成员变量的有效范围
成员变量在整个类内都有效,其有效性与它在类体中书写的先后位置无关。
3,编程风格
<1>一行只声明一个变量。
<2>变量的名字除了符合标识符规定外,名字的首单词的首字母使用小写,如果变量的名字由多个单词组成,从第2个单词开始的其他单词的首字母使用大写(驼峰习惯)。
<3>变量的名字见名知意。
4.2.4 方法
一般格式为:
方法头{
方法体的内容
}
<1>方法头
方法头由方法的类型,名称和名称之后的一对小括号以及其中的参数列表所构成。
方法的名字必须符合标识符规定,给方法命名的习惯和给变量命名的习惯相同。
<2>方法体
方法声明之后的一对大括号{,}以及它们之间的内容称为方法的方法体。
和类的成员变量不同的是,局部变量只在方法内有效,而且与其声明的位置有关。方法的参数在整个方法内有效,方法内的局部变量从声明它的位置之后开始有效。如果局部变量的声明是在一个复合语句中,那么该局部变量的有效范围是该复合语句;如果局部变量的声明是在一个循环语句中,那么该局部变量的有效范围是该循环语句。
<3>区分成员变量和局部变量
如果局部变量的名字与成员变量的名字相同,那么成员变量被隐藏,即该成员变量在这个方法内暂时失效。如果想在方法中使用被隐藏的成员变量,必须使用关键字this。
<4>局部变量没有默认值
成员变量有默认值,但局部变量没有默认值,因此在使用局部变量之前,必须保证局部变量有具体的值。
4.2.5 需要注意的问题
注意:
<1>声明成员变量时可赋予初值。
<2>语句不是变量的声明,只能出现在方法体中,如赋值语句等
4.2.6 类的UML图
在类的UML图中,使用一个长方形描述一个类的主要构成,将长方形垂直地分为三层:
<1>顶部第1层是名字层,如果类的名字是常规字形,表明该类是具体类,如果类的名字是斜体字形,表明该类是抽象类。
<2>第2层是变量层,也称属性层,列出类的成员变量及类型,格式是“ 变量名字:类型 ”。在用UML表示类时,可以根据设计的需要只列出最重要的成员变量的名字。
<3>第3层是方法层,也称操作层,列出类中的方法,格式是“ 方法名字(参数列表):类型 ”。在用UML表示类时,可以根据设计的需要只列出最重要的方法。
4.3 构造方法与对象的创建
在面向对象语言中,用类声明的变量称为对象。和基本数据类型不同,在类声明对象后,还必须创建对象,即为声明的对象分配所拥有的变量(确定对象所具有的属性),当使用一个类创建一个对象时,也称给出了这个类的一个实例。
4.3.1 构造方法
构造方法是类中的一种特殊方法,当程序用类创建对象时需使用它的构造方法。类中的构造方法的名字必须与它所在的类的名字完全相同,而且没有类型。允许在一个类中编写若干构造方法,但必须保证它们的参数不同,参数不同是指:参数的个数不同,或参数个数相同,但参数列表中对应的某个参数的类型不同。
注意:如果类中没有编写构造方法,系统会默认该类只有一个构造方法,该默认的构造方法是无参数的,且方法体中没有语句。
1,默认构造方法与自定义构造方法
如果类里定义了一个或多个构造方法,那么Java不提供默认的构造方法。
2,构造方法没有类型
需要特别注意的是:构造方法没有类型。
4.3.2 创建对象
1,对象的声明
一般格式为:
类的名字 对象的名字;
2,为声明的对象分配变量
使用new运算符和类的构造方法为声明的对象分配变量,即创建对象。
class Point{
int x,y;
Point(int a,int b){
x = a;
y = b;
}
}
public class Example4_2{
public static void main(String args[]) {
Point p1,p2; //声明变量p1和p2
p1 = new Point(10,10);//为对象p1分配变量(使用new和类中的构造方法)
p2 = new Point(23,35);//为对象p2分配变量(使用new和类中的构造方法)
}
}
3,对象的内存模型
<1>声明对象时的内存模型
<2>为对象分配变量后的内存模型
——为各个变量分配内存,如果成员变量在声明时没有指定初值,所使用的构造方法也没有对成员变量进行初始化操作,那么,对于整型的成员变量,默认初值是0;对于浮点型,默认初值是0.0;对于boolean型,默认初值是false;对于引用型,默认初值是null。
——new运算符在为变量分配内存后,将计算出一个称作引用的值(该值包含着代表这些成员变量内存位置及相关的重要信息)
<3>创建多个不同的对象
一个类通过使用new运算符可以创建多个不同的对象,这些对象的变量将被分配不同的内存空间。
总结:new运算符只能和类的构造方法进行运算,运算的最后结果是一个是六进制的数,这个数称作对象的引用。
注意:对象的引用存在栈中,对象的实体(分配给对象的变量)存在堆中。
4.3.3 使用对象
1,对象操作自己的变量(体现对象的属性)
访问格式为:
对象.变量;
2,对象调用类中的方法(体现对象的行为)
调用格式为:
对象.方法;
3,体现封装
类中的方法可以操作成员变量。当对象调用方法是,方法中出现的成员变量就是指分配给该对象的变量。
类中的方法可以操作成员变量,当对象调用该方法时,方法中出现的成员变量就是指该对象的成员变量。
4.3.4 对象的引用和实体
类所声明的变量被称为对象,对象(变量)负责存放引用。
<1>避免使用空对象
<2>重要结论
一个类声明的两个对象如果具有相同的引用,二者就具有完全相同的变量(实体)。
——在Java中,对于同一个类的两个对象object1和object2,允许进行如下的赋值操作。
<3>垃圾收集
和C++不同的是,在Java语言中,类有构造函数,但没有析构函数,Java运行环境的“ 垃圾收集 ”发现堆中分配的实体不再被栈中任何对象所引用时,就会释放该实体在堆中占用的内存。
4.4 类与程序的基本结构
一个Java应用程序(也称为一个工程)由若干个类所构成,这些类可以在一个源文件中,也可以分布在若干源文件中。
4.5 参数传值
4.5.1 传值机制
4.5.2 基本数据类型参数的传值
对于基本数据类型的参数,向该参数传递的值的级别不可以高于该参数的级别。
4.5.3 引用类型参数的传值
当参数是引用类型时,“ 传值 ”传递的是变量中存放的“ 引用 ”,而不是变量所引用的实体。
4.5.4 可变参数
可变参数是指在声明方法时不给出参数列表中从某项开始直至最后一项参数的名字和个数,但这些参数的类型必须相同。
public void f(int…x)
称x是参数代表。“ 参数代表 ”必须是参数列表中的最后一个。
对于可变参数,Java也提供了增强的for语句。
for(声明循环变量:参数代表){
…
}
4.6 对象的组合
一个类可以把某个对象作为自己的一个成员变量。
4.6.1 组合与复用
如果一个对象a组合了对象b,那么对象a就可以委托对象b调用其方法,即对象a以组合的方式复用对象b的方法。
4.6.2 类的关联关系和依赖关系的UML图
<1> 关联关系
如果A类中的成员变量是用B类声明的对象,那么A和B的关系是关联关系。
<2> 依赖关系
如果A类中的某个方法的参数是用B类声明的对象或某个方法返回的数据类型是B类对象,那么A和B的关系是依赖关系。
4.7 实例成员与类成员
4.7.1 实例变量和类变量的声明
在声明成员变量时,用关键字static给予修饰的称作类变量(类变量也称为static变量,静态变量),否则称作实例变量。
4.7.2 实例变量和类变量的区别
<1>不同对象的实例变量互不相同。
<2>所有对象共享类变量。
<3>通过类名直接访问类变量。
——类变量是和该类创建的所有对象相关联的变量,改变其中一个对象的这个类变量就同时改变了其他对象的这个类变量。类变量不仅可以通过某个对象访问,也可以直接通过类名访问。
——实例变量仅仅是和相应的对象关联的变量,也就是说,不同对象的实例对象互不相同,即分配不同的存储空间。对象的实例变量可以通过该对象访问,但不能使用类名访问。
4.7.3 实例方法和类方法的定义
方法类型前面不加关键字static修饰的是实例方法,加static关键字修饰的是类方法(静态方法)。
4.7.4 实例方法和类方法的区别
1,对象调用实例方法
——只有该类创建对象后,类中的实例方法才分配入口地址,从而实例方法可以被类创建的任何对象调用执行。
——当我们创建第一个对象时,类中的实例方法就分配了入口地址,当再创建对象时,不再分配入口地址,也就是说,方法的入口地址呗所有的对象共享,当所有的对象都不存在时,方法的入口地址才被取消。
——实例方法中不仅可以操作实例变量,也可以操作类变量。
2,类名调用类方法
——对于类中的类方法,在该类被加载到内存时,就分配了相应的入口地址,从而类方法不仅可以被类创建的任何对象调用执行,也可以直接通过类名调用。
——类方法的入口地址直到程序退出才被取消。
——类方法不可以操作实例变量。
3,设计类方法的原则
4.8 方法重载
Java中存在两种多态:重载和重写,重写是与继承有关的多态。
4.8.1 方法重载的语法规则
方法重载的意思是:一个类中可以有多个方法具有相同的名字,但这些方法的参数必须不同。两个方法的参数不同是指满足下列之一:
——参数的个数不同
——参数个数相同,但参数列表中对应的某个参数的类型不同。
class People{
float hello(int a,int b) {
return a+b;
}
float hello(long a,int b) {
return a-b;
}
double hello(double a,int b) {
return a*b;
}
}
public class Example4_12{
public static void main(String args[]) {
People tom = new People();
System.out.println(tom.hello(10,20));
System.out.println(tom.hello(10L,20));
System.out.println(tom.hello(10.0,20));
}
}
注意:方法的返回类型和参数的名字不参与比较。
4.8.2 避免重载出现歧义
重载方法之间必须保证相互的参数不同。
4.9 this关键字
this是Java的一个关键字,表示某个对象。this可以出现在实例方法和构造方法中,但不可以出现在类方法中。
4.9.1 在构造方法中使用this
this关键字出现在类的构造方法中时,代表使用该构造方法所创建的对象。
public class People{
int leg,hand;
String name;
People(String s){
name = s;
this.init(); //此处可以省略this
}
void init() {
leg = 2;
hand = 2;
System.out.println(name+"有"+hand+"只手"+leg+"条腿");
}
public static void main(String args[]) {
People boshi = new People("布什");
//创建boshi时,构造方法中的this就是对象boshi
}
}
4.9.2 在实例方法中使用this
实例方法只能通过对象来调用,不能用类名来调用。当this关键字出现在实例方法中时,this就代表正在调用该方法的当前对象。
实例方法可以操作类的成员变量,当实例成员变量在实例方法中出现时,默认的格式是:
this.成员变量;
当static成员变量在实例方法中出现时,默认的格式是:
类名.成员变量;
class A{
int x;
static int y;
void f() {
this.x = 100;
A.y = 200;
}
}
注意:通常情况下,可以省略实例成员变量名字前面的“ this. ”以及static变量前面的" 类名. “。但是,当实例成员变量的名字和局部变量的名字相同时,成员变量名字前面的“ this. ”以及static变量前面的” 类名. "就不可以省略。
——类的实例方法可以调用类的其他方法。
对于实例方法调用的默认格式是:
this.方法;
对于类方法调用的默认格式是:
类名.方法;
class B{
void f() {
this.g();
B.h();
}
void g() {
System.out.println("ok");
}
static void h() {
System.out.println("hello");
}
}
——在上述B类中的方法f中出现了this,this代表调用方法f的当前对象。
——一个实例方法调用另一个方法时可以省略方法名字前面的“ this. ”或“ 类名. ”。
——this不能出现在类方法中,这是因为类方法可以通过类名直接调用,这时,可能还没有任何对象诞生。
4.10 包
包名的目的是有效地区分名字相同的类,不同Java源文件中的两个类名字相同时,它们可以通过隶属于不同的包来相互区分。
4.10.1 包语句
package语句的一般格式为:
package 包名;
包名可以是一个合法的标识符,也可以是若干个标识符加“ . ”分隔而成。
4.10.2 有包名的类的存储目录
4.10.3 运行有包名的主类
注意:Java语言不允许用户程序使用java作为包名的第一部分。
4.11 import语句如果一个类想要使用的类和它不在一个包中,这正是import语句要帮助完成的使命。
4.11.1 引入类库中的类
——使用import语句可以引入包中的类和接口。
——为了能使用Java提供的类,可以使用import语句引入包中的类和接口。在一个Java程序中可以有多个import语句,它们必须卸载packa语句和源文件中类的定义之间。
——如果要引入一个包中的全部类,则可以用通配符(*)来代替。
4.11.2 引入自定义中的类
4.12 访问权限
4.12.1 何谓访问权限
注意:在编写类的时候,类中的实例方法总是可以操作该类中的实例变量和类变量;类方法总是可以操作该类中的类变量,与访问限制符没有关系。
4.12.2 私有变量和私有方法
用关键字private修饰的成员变量和方法称为私有变量和私有方法。
如果不希望该对象直接访问自己的变量,即通过“ . ”运算符来操作自己的成员变量,就应当将该成员变量访问权限设置为private。
4.12.3 共有变量和共有方法
用public修饰的成员变量和方法被称为共有变量和共有方法。
4.12.4 友好变量和友好方法
不用private,public,protected修饰符修饰的成员变量和方法被称为友好变量和友好方法。
4.12.5 受保护的成员变量和方法
用protected修饰的成员变量和方法被称为受保护的成员变量和受保护的方法。
4.12.6 public类与友好类
如果在关键字class前面加上public关键字,就称这样的类是一个public类。
——可以在任何另外一个类中使用public类创建对象。
如果一个类不加public修饰,这样的类被称作友好类。
——那么另外一个类族中使用友好类创建对象时,要保证它们是在同一包中。
注意:
<1>不能用protected和private修饰类。
<2>访问限制修饰符按访问权限从高到低的排列顺序是public,protected,友好的,private。
4.14 对象数组
正确的使用对象数组:
Student [ ] stu;
stu = new Student[ 10 ];
stu[ 0 ] = new Student();
4.17 应用举例
——搭建流水线(歌手大赛分数处理问题)
public class SingGame {
public static void main(String[] args) {
// TODO Auto-generated method stub
Line line = new Line();
line.givePersonScore();
}
}
import java.util.Scanner;
public class InputScore {
DelScore del;
InputScore(DelScore del){
this.del = del;
}
public void inputScore() {
System.out.println("请输入评委数");
Scanner read = new Scanner(System.in);
int count = read.nextInt();
System.out.println("请输入各个评委的分数:");
double []a = new double[count];
for(int i=0;i<count;i++) {
a[i] = read.nextDouble();
}
del.doDelete(a);
}
}
public class DelScore {
ComputerAver computer;
DelScore(ComputerAver computer){
this.computer = computer;
}
public void doDelete(double [] a) {
java.util.Arrays.sort(a); //数组a升序排列
System.out.print("去掉一个最高分:"+a[a.length-1]+",");
System.out.print("去掉一个最低分:"+a[0]+"。");
double b[] = new double[a.length-2];
for(int i=1;i<a.length-1;i++) {
b[i-1] = a[i];
}
computer.giveAver(b);
}
}
public class ComputerAver {
public void giveAver(double [] b) {
double sum = 0;
for(int i=0;i<b.length;i++) {
sum = sum + b[i];
}
double aver = sum/b.length;
System.out.println("选手最后得分"+aver);
}
}
public class Line {
InputScore one;
DelScore two;
ComputerAver three;
Line(){
three = new ComputerAver();
two = new DelScore(three);
one = new InputScore(two);
}
public void givePersonScore() {
one.inputScore();
}
}
#第 5 章 子类与继承
5.1 子类与父类
——继承是一种由已有的类创建新类的机制。利用继承,可以先定义一个共有属性的一般类,根据该一般类再定义具有特殊属性的子类,子类继承一般类的属性和行为,并根据需要增加它自己的新的属性和行为。
——由继承得到的类称为子类,被继承的类称为父类(超类)。
注意:子类只能有一个父类。
5.1.1 子类
在类的声明中,通过使用关键字extends来定义一个类的子类,格式如下:
class 子类名 extends 父类名{
…
}
5.1.2 类的树形结构
如果C是B的子类,B又是A的子类,习惯上称C是A的子孙类。Java的类按照继承关系形成树形结构。
5.2 子类的继承性
——所谓子类继承父类的成员变量作为自己的一个成员变量,就好像它们是在子类中直接声明一样,可以被子类中自己定义的任何实例方法操作。
——所谓子类继承父类的方法作为子类中的一个方法,就像它们是在子类中直接定义了一样,可以被子类中自己定义的任何实例方法调用。
5.2.1 子类和父类在同一包中的继承性
如果子类和父类在同一个包中,那么,子类自然地继承了其父类中不是private的成员变量作为自己的成员变量,并且也自然地继承了父类中不是private的方法作为自己的方法,继承的成员变量或方法的访问权限保持不变。
5.2.2 子类和父类不在同一包中的继承性
当子类和父类不在同一个包中时,父类中的private和友好访问权限的成员变量不会被子类继承。
5.2.3 继承关系的UML图
如果一个类是另一个类的子类,那么UML通过使用一个实线连接两个类的UML图来表示二者之间的继承关系,实线的起始端是子类的UML图,终点端是父类的UML图,但终点端使用一个空心的三角形表示实线的结束。
5.2.4 protected的进一步说明
——对于子类D自己声明的protected成员变量和方法,只要Other类和D类在同一个包中,object对象就可以访问这些protected成员变量和方法。
——对于子类D从父类继承的protected成员变量或方法,需要追溯到这些protected成员变量或方法所在的“ 祖先 ”类,例如可能是A类,只要Other和A类在同一个包中,object对象能访问继承的protected变量和protected方法。
5.3 子类与对象
5.3.1 子类对象的特点
——当用子类的构造方法创建一个子类的对象时,不仅子类中声明的成员变量被分配了内存,而且父类的成员变量也都分配了内存空间。,但只将其中一部分,即子类继承的那部分成员变量,作为分配给子类对象的变量。
——子类中还有一部分方法是从父类继承的,这部分方法却可以操作这部分未继承的变量。
5.3.2 关于instanceof运算符
instanceof运算符是Java独有的双目运算符,其左面的操作元是对象,右面的操作元是类,当左面的操作元是右面的类或其子类所创建的对象时,instanceof运算的结果是true,否则是false。
5.4 成员变量的隐藏和方法重写
5.4.1 成员变量的隐藏
——在编写子类时,我们仍然可以声明成员变量,一种特殊的情况就是,所声明的成员变量的名字和从父类继承过来的成员变量的名字相同(声明的类型可以不同),在这种情况下,子类就会隐藏所继承的成员变量。
子类隐藏继承的成员变量的特点如下:
<1>子类对象以及子类自己定义的方法操作与父类同名的成员变量是指子类重新声明的这个成员。
<2>子类对象仍然可以调用从父类继承的方法操作被子类隐藏的成员变量,也就是说,子类继承的方法所操作的成员变量一定是被子类继承或隐藏的成员变量。
注意:子类继承的方法只能操作子类继承和隐藏的成员变量。子类新定义的方法可以操作子类继承和子类新声明的成员变量,但无法操作子类隐藏的成员变量。
5.4.2 方法重写
子类通过重写可以隐藏已继承的方法(方法重写称为方法的覆盖)。
1,重写 的语法规则
如果子类可以继承父类的某个方法,那么子类就有权利重写这个方法。
所谓重写,就是这个方法的类型和父类的方法类型一致。
2,重写的目的
——子类通过方法的重写可以隐藏继承的方法,子类通过方法的重写可以把父类的状态和行为改变为自身的状态和行为。
——重写的方法既可以操作继承的成员变量,调用继承的方法,也可以操作子类新声明的成员变量,调用新定义的其他方法,但无法操作被子类隐藏的成员变量和方法。
——如果子类想使用被隐藏的方法或成员变量,必须使用关键字super。
package 第4章;
class A{
float computer(float x,float y) {
return x + y;
}
public int g(int x,int y) {
return x + y;
}
}
class B extends A{
float computer(float x,float y) {
return x*y;
}
}
public class Example5_5 {
public static void main(String[] args) {
// TODO Auto-generated method stub
B b = new B();
double result = b.computer(8,9);
System.out.println(result);
int m = b.g(12, 8);
System.out.println(m);
}
}
3,重写的注意事项
重写父类的方法时,不允许降低方法的访问权限,但可以提高访问权限(访问权限修饰符按访问权限从高到低的排列顺序是public,protected,友好的,private)。
5.5 super关键字
5.5.1 用super操作被隐藏的成员变量和方法
子类一旦隐藏了继承的成员变量,那么子类创建的对象就不再拥有该变量,该变量将归关键字super所拥有,同样,子类一旦隐藏了继承的方法,那么子类创建的对象就不能调用被隐藏的方法,该方法的调用由关键字super负责。
注意:当super调用被隐藏的方法时,该方法中出现的成员变量是被子类隐藏的成员变量或继承的成员变量。
5.5.2 使用super调用父类的构造方法
当用子类的构造方法创建一个子类的对象时,子类的构造方法总是先调用父类的某个构造方法,也就是说,如果子类的构造方法没有明显地指明使用父类的哪个构造方法,子类就调用父类的不带参数的方法。
注意:当在父类中定义多个构造方法时,应当包括一个不带参数的构造方法,以防子类省略super时出现错误。
5.6 final关键字
final关键字可以修饰类,成员变量和方法中的局部变量。
5.6.1 final类
可以使用final将类声明为final类。final类不能被继承,即不能有子类。
5.6.2 final方法
如果用final修饰父类中的一个方法,那么这个方法不允许子类重写,也就是说,不允许子类隐藏可以继承的final方法。
5.6.3 常量
如果成员变量或局部变量被修饰为final,那它就是常量。(即没有默认值,在声明时必须指定该常量的值)。
5.7 对象的上转型对象
Animal a; //假设Animal类是Tiger类的父类
Tiger b = new Tiger();
a = b;
这时,称对象a是对象b的上转型对象(好比说老虎是动物)
<1>上转型对象不能操作子类新增的成员变量(失掉了这部分属性),不能调用子类新增的方法(失掉了一些行为)。
<2>上转型对象可以访问子类继承或隐藏的成员变量,也可以调用子类继承的方法或子类重写的实例方法。因此,如果子类重写了父类的某个实例方法后,当对象的上转型对象调用这个实例方法时一定是调用了子类重写的实例方法。
<3>不可以将父类创建的对象的引用赋值给子类声明的对象(不能说“ 人是美国人 ”)。
<4>如果子类重写了父类的静态方法,那么子类对象的上转型对象不能调用子类重写的静态方法,只能调用父类的静态方法。
<5>可以把上转型对象强制转化为子类的对象。
5.8 继承与多态
多态性就是指父类的某个方法被其子类重写是,可以各自产生自己的功能行为。
5.9 abstract类和abstract方法
用关键字abstract修饰的类称为abstract类(抽象类),例如:
abstract class A{
…
}
用关键字abstract修饰的方法称为abstract方法(抽象方法),例如:
abstract int min(int x,int y);
对于abstract方法,只允许声明,不允许实现(没有方法体),而且不允许使用final和abstract同时修饰一个方法或类,也不允许使用static修饰abstract方法,即abstract方法必须是实例方法。
1,abstract类中可以有abstract方法
非abstract类不能有abstract方法,abstract类也可以没有abstract方法。
2,abstract类不能用new运算符创建对象
3,abstract类的子类
如果一个非abstract类是abstract类的子类,它必须重写父类的abstract方法,即去掉abstract方法的abstract修饰,并给出方法体。
4,abstract类的对象作上转型对象
5.10 面向抽象编程
——使用多态进行程序设计的核心技术之一是使用上转型对象,即将abstract类声明的对象作为其子类对象的上转型对象,那么这个上转型对象就可以调用子类重写的方法。
——所谓面向抽象编程,是指当设计某种重要的类时,不让该类面向具体的类,而是面向抽象类,即所设计类中的重要数据是抽象类声明的对象,而不是具体类声明的对象。
——面向抽象编程的目的是为了应对用户需求的变化,将某个类中经常因需求变化而需要改动的代码从该类中分离出去。面向抽象编程的核心是让类中每种可能的变化对应地交给抽象类的一个子类去负责,从而让该类的设计者不去关心具体实现,避免所设计的类依赖于具体的实现。面向抽象编程使设计的类容易应对用户需求的变化。
5.11 开—闭原则
所谓“ 开—闭原则 ”,就是让设计的系统对扩展开放,对修改关闭。实际上,这句话的本质是指当系统中增加新的模块时,不需要修改现有的模块。
5.12 应用举例
public abstract class SIM {
public abstract void setNumber(String n);
public abstract String giveNumber();
public abstract String giveCorpName();
}
public class MobileTelephone {
SIM card;
public void useSIM(SIM card) {
this.card = card;
}
public void showMess() {
System.out.println("使用的卡是:"+card.giveCorpName()+"提供的");
System.out.println("手机号码是:"+card.giveNumber());
}
}
public class SIMOfChinaMobile extends SIM{
String number;
public void setNumber(String n) {
number = n;
}
public String giveNumber() {
return number;
}
public String giveCorpName() {
return "中国移动";
}
}
public class SIMOfChinaUnicom extends SIM{
String number;
public void setNumber(String n) {
number = n;
}
public String giveNumber() {
return number;
}
public String giveCorpName() {
return "中国联通";
}
}
public class Application {
public static void main(String[] args) {
// TODO Auto-generated method stub
MobileTelephone telephone = new MobileTelephone();
SIM sim = new SIMOfChinaMobile();
sim.setNumber("13887656432");
telephone.useSIM(sim);
telephone.showMess();
sim = new SIMofChinaUnicom();
sim.setNumber("13097656437");
telephone.useSIM(sim);
telephone.showMess();
}
}
#**第 6 章 接口与实现**
6.1 接口
使用关键字interface来定义一个接口。接口的定义和类的定义很相似,分为接口声明和接口体。
1,接口的声明
格式如下:
interface 接口的名字
2,接口体
接口体中包含常量的声明(没有变量)和抽象方法两部分。接口体中只有抽象方法,没有普通的方法,而且接口体中所有的常量的访问权限一定都是public,而且static常量(允许省略public,final和static修饰符),所有的抽象方法的访问权限一定都是public(允许省略public abstract修饰符)。
interface Printable{
public static final int MAX = 100; //等价于:int MAX = 100;
public abstract void add(); //等价于:void add();
public abstract float sum(float x,float y);
}
6.2 实现接口
1,类实现接口
在Java语言中,接口由类来实现以便使用接口中的方法。一个类需要在类声明中使用关键字implements声明该类实现一个或多个接口。如果实现多个接口,用逗号隔开接口名。
2,重写接口中的方法
如果一个非抽象类实现了某个接口,那么这个类必须重写这个接口中的所有方法。
注意:由于接口中的方法一定是public abstract方法,所以类在重写接口方法时不仅要去调abstract修饰符,给出方法体,而且方法的访问权限一定要明显地用public来修饰(否则就降低了访问权限,这是不允许的)。实现接口的非抽象类实现了该接口中的方法,即给出了方法的具体行为功能。
public interface Computable {
int MAX = 46;
int f(int x);
}
public class China implements Computable {
int number;
public int f(int x) {
int sum = 0;
for(int i=1;i<=x;i++) {
sum = sum + i;
}
return sum;
}
}
public class Japan implements Computable{
int number;
public int f(int x) {
return MAX+x;
}
}
public class Example6_1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
China zhang;
Japan henlu;
zhang = new China();
henlu = new Japan();
zhang.number = 32 + Computable.MAX;
henlu.number = 14 + Computable.MAX;
System.out.println("zhang的学号"+zhang.number+
",zhang求和结果"+zhang.f(100));
System.out.println("henlu的学号"+henlu.number+
",henlu求和结果"+henlu.f(100));
}
}
如果一个类声明实现一个接口,但没有重写接口中的所有方法,那么这个类必须是抽象类,也就是说,抽象类即可以重写接口的方法,也可以直接拥有接口中的方法。
interface Computable{
final int MAX = 100;
void speak(String s);
int f(int x);
float g(float x,float y);
}
abstract class A implements Computable{
public int f(int x) {
int sum = 0;
for(int i=1;i<=x;i++) {
sum = sum + i;
}
return sum;
}
}
3,接口的细节说明
——程序可以用接口名访问接口中的常量,但是如果一个类实现了接口,那么该类在类体中使用该接口中的常量。
——定义接口时,如果关键字interface前面加上public关键字,就称这样的接口是一个public接口。public接口可以被任何一个类实现。如果一个接口不加public修饰,就称友好接口,友好接口可以被与该接口在同一包中的类实现。
——如果父类实现了某个接口,那么子类也就自然实现了该接口,子类不必再显式地使用关键字implements声明实现这个接口。
——接口也可以被继承,即可以通过关键字extends声明一个接口是另一个接口的子接口。由于接口中的方法和常量都是public的,子接口将继承父接口中的全部方法和常量。
6.3 接口的UML图
将长方体垂直地分为三层:
<1>顶部第一层是名字层,接口的名字必须是斜体字形,而且需要用<>修饰名字,并且该修饰和名字分列在两行。
<2>第二层是常量层,列出接口中的常量及类型,格式是“ 常量名字:类型 ”。
<3>第三层是方法层,也称操作层,列出接口中的方法及返回类型,格式是“ 方法名字(参数列表):类型 ”。
如果一个类实现了一个接口,那么类和接口的关系是实现关系,称类实现接口。UML通过使用虚线谅解类和它所实现的接口,虚线的起始端是类,虚线的终点端是它实现的接口,但终点端使用一个空心的三角形表示虚线的结束。
6.4 接口回调
——和类一样,接口也是Java中一种重要的数据类型,用接口声明的变量称作接口变量。
——接口属于引用型变量,接口变量中可以存放实现该接口的类的实例的引用,即存放对象的引用。
接口回调是指:可以把实现某一接口的类创建的对象的引用赋值给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口方法。实际上,当接口变量调用被类实现的接口方法时,就是通知相应的对象调用这个方法。
注意:接口无法调用类中的其他的非接口方法
interface ShowMessage{
void 显示商标(String s);
}
class TV implements ShowMessage{
public void 显示商标(String s) {
System.out.println(s);
}
}
class PC implements ShowMessage{
public void 显示商标(String s) {
System.out.println(s);
}
}
public class Example6_2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
ShowMessage sm; //声明接口变量
sm = new TV(); //接口变量中存放对象的引用
sm.显示商标("长城牌电视机"); //接口回调
sm = new PC(); //接口变量中存放对象的引用
sm.显示商标("海信牌电视机"); //接口回调
}
}
6.5 理解接口
——接口可以抽象出重要的行为标准,该行为标准用抽象的方法来表示。
——可以把实现接口的类的对象的引用赋值给接口变量,该接口变量可以调用被类实现的接口方法,即体现该类根据接口里的行为标准给出的具体行为。
——接口的思想在于它可以要求某些类有相同名称的方法,但方法的具体内容(方法体的内容)可以不同,即要求这些类实现接口,以保证这些类一定有接口中所声明的方法(即所谓的方法绑定)。
6.6 接口与多态
即把实现接口的类的实例的引用赋值给接口变量后,该接口变量就可以回调类重写的接口方法。由接口产生的多态就是指不同的类在实现同一个接口时可能具有不同的实现方式,那么接口变量在回调接口方法时就可能具有多种形态。
interface CompurerAverage{
public double average(double a,double b);
}
class A implements CompurerAverage{
public double average(double a,double b) {
double aver = 0;
aver = (a+b)/2;
return aver;
}
}
class B implements CompurerAverage{
public double average(double a,double b) {
double aver;
aver = Math.sqrt(a*b);
return aver;
}
}
public class Example6_4 {
public static void main(String[] args) {
// TODO Auto-generated method stub
CompurerAverage computer;
double a = 11.23,b = 22.78;
computer = new A();
double result = computer.average(a, b);
System.out.printf("%5.2f和%5.2f的算术平均值:%5.2f\n",a,b,result);
computer = new B();
result = computer.average(a, b);
System.out.printf("%5.2f和%5.2f的几何平均值:%5.2f",a,b,result);
}
}
6.7 接口参数
如果一个方法的参数是接口类型,我们就可以将任何实现该接口的类的实例的引用传递给该接口参数,那么接口参数就可以回调类实现的接口方法。
interface SpeakHello{
void speakHello();
}
class Chinese implements SpeakHello{
public void speakHello() {
System.out.println("中国人习惯问候语:你好,吃饭了吗?");
}
}
class English implements SpeakHello{
public void speakHello() {
System.out.println("英国人习惯问候语:你好,天气不错");
}
}
class KindHello{
public void lookHello(SpeakHello hello) {
hello.speakHello();
}
}
public class Example6_5 {
public static void main(String[] args) {
// TODO Auto-generated method stub
KindHello kindHello = new KindHello();
kindHello.lookHello(new Chinese());
kindHello.lookHello(new English());
}
}
6.8 abstract类与接口的比较
abstract类和接口的比较如下:
——abstract类和接口都可以有abstract方法。
——接口中只可以有常量,不能有变量;而abstract类中既可以有常量,也可以有变量。
——abstract类中也可以有非abstract方法,接口不可以。
6.9 面向接口编程
6.10 应用举例
public interface Advertisement {
public void showAdvertisement();
public String getCorpName();
}
public class AdvertisementBoard {
public void show(Advertisement adver) {
System.out.println(adver.getCorpName()+"的广告词如下:");
adver.showAdvertisement();
}
}
public class BlackLandCorp implements Advertisement {
public void showAdvertisement() {
System.out.println("**********************");
System.out.println("劳动是爹\n土地是妈\n");
System.out.println("**********************");
}
public String getCorpName() {
return "黑土集团";
}
}
public class WhiteCloudCorp implements Advertisement {
public void showAdvertisement() {
System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@");
System.out.println("飞机中的战斗机,哎yes!\n");
System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@");
}
public String getCorpName() {
return "白云有限公司";
}
}
public class Example6_6 {
public static void main(String[] args) {
// TODO Auto-generated method stub
AdvertisementBoard board = new AdvertisementBoard();
board.show(new BlackLandCorp());
board.show(new WhiteCloudCorp());
}
}
#**第 7 章 内部类与异常类**
7.1 内部类
Java支持在一个类中定义另一个类,这样的类称作内部类,而包含内部类的类称为内部类的外嵌类。
内部类和外嵌类之间的重要关系如下:
——内部类的外嵌类的成员变量在内部类中仍然有效,内部类中的方法也可以调用外嵌类中的方法。
——内部类的类体中不可以声明类变量和类方法。外嵌类的类体中可以用内部类声明对象,作为外嵌类的成员。
——内部类仅供它的外嵌类使用,其他类不可以用某个类的内部类声明对象。
public class RedCowForm {
static String formName;
RedCow cow;
RedCowForm(){
}
RedCowForm(String s){
cow = new RedCow(150,112,5000);
formName = s;
}
public void showCowMess() {
cow.speak();
}
class RedCow{
String cowName = "红牛";
int height,weight,price;
RedCow(int h,int w,int p){
height =h;
weight = w;
price = p;
}
void speak() {
System.out.println("偶是"+cowName+",身高"+height
+"cm 体重:"+weight+"kg,生活在"+formName);
}
}
}
public class Example7_1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
RedCowForm form = new RedCowForm("红牛农场");
form.showCowMess();
form.cow.speak();
}
}
注意:内部类可以被修饰为static内部类,类是一种数据类型,那么static内部类就是外嵌类中的一种静态数据类型,这样一来,程序就可以在其他类中使用static内部类来创建对象了。但是,static内部类不能操作外嵌类中的实例成员变量。
注意:非内部类不可以是static类。
7.2 匿名类
7.2.1 和子类有关的匿名类
匿名类就是一个子类,由于无名可用,所以不可能用匿名类声明对象,但却可以直接用匿名类创建一个对象。
假设Bank是类,那么下列代码就是用Bank的一个子类(匿名类)创建对象。
new Bank(){
匿名类的类体
};
匿名类的特点:
——匿名类可以继承父类的方法也可以重写父类的方法。
——使用匿名类时,必然是在某个类中直接用匿名类创建对象,因此匿名类一定是内部类。
——匿名类可以访问外嵌类中的成员变量和方法,匿名类的类体中不可以声明static成员变量和方法。
——由于匿名类是一个子类,但没有类名,所以在用匿名类创建对象时,要直接使用父类的构造方法。
7.2.2 和接口有关的匿名类
假设Computable是一个接口,那么,Java允许直接用接口名和一个类体创建一个匿名对象,此类体被认为是实现了Computable接口的类去掉类声明后的类体,称作匿名类。
new Computable(){ //Computable接口的类 (匿名类)创建对象
实现接口的匿名类的类体
};
如果某个方法的参数是接口类型,那么可以使用接口名和类体组合创建一个匿名对象传递给方法的参数,类体必须要重写接口中的全部方法。
interface SpeakHello{
void speak();
}
class HelloMachine{
public void turnOn(SpeakHello hello) {
hello.speak();
}
}
public class Example7_3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
HelloMachine machine = new HelloMachine();
machine.turnOn(new SpeakHello() { //和接口SpeakHello有关的匿名类
public void speak() {
System.out.println("hello,you are welcome!");
}
});
}
}
7.3 异常类
所谓异常就是程序运行时可能出现的一些错误。
异常对象可以调用如下方法得到或输出有关的信息。
public String getMessage();
public void printStackTrace();
oublic String toString();
7.3.1 try—catch语句
Java使用try—catch语句来处理异常,将可能出现的异常操作放在try—catch语句的try部分,一旦try部分抛出异常对象,或调用某个可能抛出异常对象的方法,并且该方法抛出了异常对象,那么try部分将立刻结束执行,转向执行相应的catch部分。
try—catch语句的格式如下:
try{
包含可能发生异常的语句
}
catch(ExceptionSubClass1 e){
…
}
catch(ExceptionSubClass2 e){
…
}
7.3.2 自定义异常类
在编写程序的时可以扩展Exception类定义自己的异常类,然后根据程序的需要来规定哪些方法产生这样的异常。
注意:throw是Java的关键字,该关键字的作用就是抛出异常。
7.4 断言
断言语句在调试代码阶段非常有用,断言语句一般用于程序不准备通过捕获异常来处理的错误。
1,断言语句的语法格式。
使用关键字assert声明一条断言语句,断言语句有以下两种格式:
assert booleanExpression;
assert booleanExpression:messageException;
7.5 应用举例
#第 8 章 常用实用类
8.1 String类
String类不可以有子类。
8.1.1 构造String对象
String对象,习惯地被翻译为字符串对象。
1,常量对象
String常量也是对象,是用双引号括起的字符序列。Java把用户程序中的String常量放入常量池。因为String常量是对象,所以也有自己的引用和实体。
注意:常量池中的数据在程序运行期间再也不允许改变。
2,String对象
可以用String类声明对象并创建对象。例如:
String s = new String(“We are students”);变量s中存放着引用,表明自己的实体的位置