1、JAVA 语法/C+语法比较一一、关键字与标识符1-1 、关键字不能被用作类、变量、方法或者其他任何内容的标识符。1-2 、所有关键字都以小写字母开头。1-3 、关键字是发展变化的。jdk1.5 中加入了 enum 枚举关键字。1-4 、true 、fasle 、null 、const 以及 goto 不是关键字,但也不能用作标识符。如:boolean const = true; 是不能编译的。1-5 、不要把 Java 的关键字和其他语言混淆了。如: C+ 的 include 、unsigned 等。1-6 、标识符由字母、数字、下划线(_) 、美元符号($) 、人民币符号 ( ¥) 组成,
2、并且第一个字符不能是数字,也不能把 JAVA 中的关键字和保留关键字作为标识符。另外,标识符可以使用汉字、日文片假名等 Unicode 字符,如:boolean 吃饱了吗 = true; 。Unicode 字符集的前 128 个是 ASCII 码表。二、常量和所有原始数据类型的范围2-1 、基本类型的存储空间。byte-8 位,short-16 位,int-32 位,long-64 位,float-32 位,double-64 位。这六种数字类型都是有符号的。固定的存储空间正是 Java 可移植性、跨平台的原因之一!2-1 、基本类型的存在导致了 Java OOP 的不纯粹性。因为基本类型不是
3、对象,一切皆对象是个小小的谎言。这是出于执行效率的权衡。2-2 、使用公式-2 的(位数-1 )次幂到 2 的(位数-1 )次幂-1 确定整数类型的范围(byte 、short 、int 、long ) 。2-3 、char 是 16 位 Unicode 字符或者说是 16 位无符号整数,范围从 0 到 65535 。即便如此,可以强制转换非法的数据,如:char c1 = (char) 10000; char c2 = (char) -200; 。可以从二进制存储的角度理解这点。2-4 、整数有八进制(以 0 开头的整数) 、十进制、十六进制(以 0x 或 0X 开头的整数)表示。2-5 、
4、char 可以用单引号表示单个字符,如: 良 。也可以用 unicode 值“ucafe (四位十六进制数) 。2-6 、布尔型 boolean 。布尔型只能是 true 或者 false ,并且测试它为真还是假。它不能进行任何其他的运算,或者转化为其他类型。正例:boolean b1 = 1 2; 反例:int seen = button.isVisible();实践:简洁是美德,请不要这样写:if ( is = true 是错误的。2-7 、默认的整数类型是 int 型,要想使用长整型可在后面加“l ”或“L ”,如:1000L 。 (小写 l 容易被误认为 1 ,不推荐用)2-8 、fl
5、oat 可以精确到 7 位有效数字,第 8 位的数字是第 9 位数字四舍五入上取得的;double 可以精确到 16 位有效数字,第 17 位的数字是第 18 位数字四舍五入上取得的。盖茨到底有多少钱?要用 double 表示,用 float 是装不下的2-9 、如果要求精确的答案,请不要使用 float 和 double ,因为它们是为了在广域数值范围上提供较为精确的快速近似运算而精心设计的。然而,它们没有提供完全精确的结果。尤其是对货币计算尤为不适合,因为要让一个 float 或 double 精确地表达 0.1 (或者 10 的任何)2-10 、BigInteger 支持任意精度的整数。
6、BigDecimal 支持任意精度的定点数。2-11 、初始化无论怎么强调都不过分!Java 为所有的成员变量提供了默认初始化:byte 、short 、 int 、long-0 float-0.0f double-0.0 boolean-false char-“u0000 ,特别地对象类型的引用全被初始化为 null 。 (注意!除了数组之外的局部变量是得不到这种优待的,需要你自己初始化。另外,默认初始化的值是你想要的吗?所以最好明确地对变量进行初始化,一般是在构造函数中。 )2-12 、基本类型之间的转化。Java 的类型检查很严格,从低精度转换到高精度是无须显式转换的,double d
7、= 123; 。但是反过来,进行窄化转换,由高精度向低精度,或者一种类型到另一种类型,则必须使用强制类型转化。Java 提供了安全转化机制,但是结果是否是期望的,你自己保证吧。double d = 12.5;float f = (int) d; / 结果不是 13 ,而是 12 !浮点型转化为整型时,不进行四舍五入,直接截断小数点后面的数。2-13 、提升。各种基本数据类型进行混合运算,结果会是表达能力最强的那种。如:int 和 long 运算,结果是 long ,整型和浮点型运算结果是浮点型。特殊的一点是:只要类型比 int 小(如 char 、byte 、short ) ,那么在运算之前,
8、这些值会自动地转换成 int 。例子:byte b1 = 12;byte b2 = b1 + 1; / 在编译时出错了!因为 b1+1 已经是 int 型了!切记!2-14 、浮点类型的科学表示法。在数学中 e 代表自然对数(Math.E 给出了 double 值) ,而在 Java 中 e 代表 10 的幂次。浮点型的数可以这样表示 float f = 1e-27f; 代表 1 乘以 10 的负 27 次幂。三、数组3-1 、数组不是集合,它只能保存同种类型的多个原始类型或者对象的引用。 (注意保存的是对象的引用,而不是对象本身。 )3-2 、数组本身就是对象,Java 中对象是在堆中的,因
9、此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。3-3 、数组声明的两种形式:一、 int arr; 二、int arr; 推荐使用前者,这符合 Sun 的命名规范,而且容易了解到关键点,这是一个 int 数组对象,而不是一个 int 原始类型。3-4 、在数组声明中包含数组长度永远是不合法的!如:int5 arr; 。因为,声明的时候并没有实例化任何对象,只有在实例化数组对象时,JVM 才分配空间,这时才与长度有关。3-5 、在数组构造的时候必须指定长度,因为 JVM 要知道需要在堆上分配多少空间。反例:int arr = new int;3-6 、多维数组的声明。int a
10、rr; 是三维 int 型数组。3-7 、一维数组的构造。形如:String sa = new String5; 或者分成两句:String sa; sa = new String5;3-8 、原始类型数组元素的默认值。对于原始类型数组,在用 new 构造完成而没有初始化时,JVM 自动对其进行初始化。默认值:byte 、short 、 int 、long-0 float-0.0f double-0.0 boolean-false char-“u0000 。 (无论该数组是成员变量还是局部变量)3-9 、对象类型数组中的引用被默认初始化为 null 。如: Car myCar = new Ca
11、r10; 相当于从 myCar0 到 myCar9 都这样被自动初始化为 myCar = null; 3-10 、对象类型的数组虽然被默认初始化了,但是并没有调用其构造函数。也就是说:Car myCar = new Car10; 只创建了一个 myCar 数组对象!并没有创建 Car 对象的任何实例! 3-11 、多维数组的构造。float ratings = new float9; 第一维的长度必须给出,其余的可以不写,因为 JVM 只需要知道赋给变量 ratings 的对象的长度。 3-12 、数组索引的范围。数组中各个元素的索引是从 0 开始的,到 length-1 。每个数组对象都有一
12、个 length 属性,它保存了该数组对象的长度。 (注意和 String 对象的 length() 方法区分开来,这两者没有统一起来是很遗憾的。 ) 3-13 、Java 有数组下标检查,当访问超出索引范围时,将产生ArrayIndexOutOfBoundsException 运行时异常。注意,这种下标检查不是在编译时刻进行的,而是在运行时!也就是说 int arr = new int10; arr100 = 100; 这么明显的错误可以通过编译,但在运行时抛出!Java 的数组下标检查是需要额外开销的,但是出于安全的权衡还是值得的,因为很多语言在使用数组时是不安全的,可以任意访问自身内存块
13、外的数组,编译运行都不会报错,产生难以预料的后果! 四、运算符和表达式 4-1 、不要记操作符的优先级。用括号的可读性更好,也节省你的脑细胞。 4-2 、操作符可能会改变操作数的自身的值,这被称为副作用。涉及赋值的语句肯定具有副作用了,另外两个是前缀和后缀式的“+ ”“- ”。副作用不是贬义的词,看看它的概念就知道了。 4-3 、关于对象的比较。 “= = ”比较的是两个引用是否指向同一个对象,注意是引用的比较,不是对象的比较。equals() 方法是 Object 对象的一个方法,也就是说所有的对象都中继承了 equals() 方法。按照常理,我们通常会覆盖 equals() 方法,在其中加
14、入我们认为两个对象的内容相同的条件,然后 a.equals(b) ,比较的是内容了。但是如果你建立了新类,而且没有覆盖 equals 方法,那么 equals 比较的仍然是引用!因为 equals 的默认行为是比较引用。这点要注意了!Java 类库中一般都覆盖了 equals 方法。 4-4 、“、花括号“和空白符号。 Java 的注释 Java 的注释有三种形式: 单行注释 如:/Comment on one line 多行注释 如:/* Comment on one or more lines */ 文档注释 如:/* Document Comment */ Java 的数据类型和变量 J
15、ava 的基本数据类型 Java 的基本数据类型有 8 种,见下表: 数据类型 类别 宽度(位) 取值范围 boolean 逻辑型 1 true/false char 文字型 16 byte 整数类型 8 -27 27-1 short 整数类型 16 -215 215-1 int 整数类型 32 -231 231-1 long 整数类型 64 -263 263-1 float 浮点型 32 double 浮点型 64 Java 的变量 Java 的变量在使用前必须声明。如 int radios, color;Java 为所有基本数据类型的变量作了预定义( 预设置的值)。如 类型名 boolea
16、n char byte short int long float double 预置值 false u0000 (byte)0 (short)0 0 0L 0.0f 0.0 数据类型的转换 Java 是一种强类型的语言,在赋值和参数传递时,都要求类型的匹配。类型转换有三种情况:自动转换、强制转换和使用类的方法转换。 自动转换:往往低精度类型到高精度类型能自动转换。如: byte b1=10, b2=20;int b3=b1+b2; 强制转换:高精度类型到低精度类型必须强制转换。这时数据可能会丢失部分信息。如:char key=(char)(12+55) / 变量 key 被赋值为 unicod
17、e 值为 67 的字符c 方法转换:如String str = “123“; int a = Integer.parseInt(str); 使用 Integer 类的方法 parseInt 将 String 转换为对应的整数。 Java 编程的习惯约定 为了提高程序的可读性,Sun 公司推荐在 Java 编程时使用以下的习惯约定:类名(classes ):有一个或若干个名词组成,开头大写,名词间的区分也用大写,其他小写。如:class AccountBook class ComplexVariable 接口(Interfaces ):规则同类名。如:Interface Account 方法(m
18、ethods): 由一个或多个动词组成,开头小写,动词间区分用大写,其他小写。如:balanceAccount() 变量:小写字母开头,单词间用大写字母分隔 如:currentCustomer 常量:所有字母大写,单词间用下划线区分 如:MAXIMUM_SIZE Java 的操作符 根据操作对象的个数操作符可分为一元、二元或三元操作符。根据操作符的功能,又可分为算术、逻辑、关系等操作符。 算术操作符 一元: + - + - 二元: + - * / % 值得注意的是 + 和- 操作符,如:int a,x=1,y=5; a = +x;b=y+;此时 a 的值为 2(先加 1,后赋值) ,b 的值为
19、 5(先赋值,后加 1) 。二元操作符两侧的操作对象数据类型不同时,先自动进行类型转换,再进行操作。 赋值操作符与复合赋值操作符 可将 变量 = 变量 op 表达式 写成 变量 op = 表达式 如:x+=20 与 x=x+20 结果一致,但更简洁。注意:= 与 = = 的不同。 位操作符和移位操作符 位操作符 for (x=0,y=0;x10;x+) .; 操作符的优先级和结合规则 优先级: 一元 算术 移位 关系 按位 逻辑 三元 (复合)赋值 逗号结合规则: 除一元、三元和赋值操作符是自右至左结合外,其他均自左至右结合。 语句的分类 Java 语句按是否改变运行的状态可分为执行语句( 如
20、表达式语句)和非执行语句(如声明语句) 。任何语句的末尾都以“;”结束。执行语句按其组成可分三类:空语句 只有一个语句结束符“;” ,无任何内容。 基本语句(单语句) 独立的、完整的不能再分割为更小的可执行单元。 复合语句(块语句) 包含在 内的一条或若干条语句。 Java 的基本语句的结构可分为 4 类:(1)顺序结构语句 (2)分支语句 (3)循环语句 (4)例外处理语句 后三种语句又称为流控制语句,我们将主要介绍分支语句和循环语句,而例外处理语句包括 try、catch 、finally 以及 throw 语句。这些语句是 Java 所特有的。我们将在后面作专门的介绍。分支语句 分支语句
21、包括 if-else, break, switch, return 等语句。分支语句提供了一种控制机制,使得程序可以跳过一些语句,转去执行特定的语句。 条件语句 if-else. if-else 语句根据判定条件的真假来执行两种操作中的一种,其格式为: if (boolean-expression)statement1;elsestatement2;其中,要注意的有:布尔表达式 boolean-expression 是任意一个返回布尔型数据的表达式(这比 C、C+的限制要严格)。 每个单一的语句后都必须有分号。 语句 statement1, statement2 可以是复合语句,这时要用花括号
22、 。外面不加分号。 else 子句是任选的。 若布尔表达式的值为 true,则程序执行 statement1,否则执行 statement2。 if-else 语句的一种特殊形式为: if (expression1)statement1 else if (expression2)statement2else if (expressionN)statementNelse 子句不能单独作为语句使用,它必须和 if 配对使用。else 总是与离它最近的 if 配对。可以通过使用花括号来改变配对关系。 例 3.1: 比较两个数的大小,并按从小到大的次序输出。 public class CompareT
23、wopublic static void main (String args)double d1=23.4;double d2=35.1;if (d2=d1)System.out.println(d2+“=“+d1);elseSystem.out.println(d1+“=“+d2);例 3.2:判断某一年是否为闰年。闰年的条件是符合下面二者之一: 能被 4 整除,但不能被 100 整除; 能被 400 整除。 public class LeapYearpublic static void main (String args)int year=1989; /method1if (year%4=
24、0 elseSystem.out.println(year+“is not a leap year.“);year=2000; /method2boolean leap;if (year%4 != 0)leap=false;else if (year%100 != 0)leap=true;else if (year%400 != 0)leap=false;elseleap=true;if(leap=true)System.out.println(year+“ is a leap year.“);elseSystem.out.println(year+“is not a leap year.“)
25、;该例中,方法 1 用一个逻辑表达式包含了所有的闰年条件,方法 2 使用了 if-else 语句的特殊形式。 多分支语句 switchswitch 语句是一种多分支选择语句,它可根据 switch 中表达式的值,来执行多个操作中的一个,它的一般格式如下:switch (expression)case value1: statement1;break;case value2: statement2;break;case valueN: statemendN;break;default: defaultStatement;表达式 expression 可以返回任一简单类型的值( 如整型、字符型),
26、多分支语句把表达式返回的值与每个 case 子句中的值(一个常量)相比。如果匹配成功,则执行该 case 子句后的语句序列。 default 子句是任选的。当表达式的值与任一 case 子句中的值都不匹配时,程序执行 default后面的语句。如果表达式的值与任一 case 子句中的值都不匹配且没有 default 子句,则程序不做任何操作,直接跳出 switch 语句。 break 语句用来在执行完一个 case 分支后,使程序跳出 switch 语句,即终止 switch 语句的执行。 switch 语句的功能可以用 if-else 来实现,但在某些情况下,使用 switch 语句更简炼,
27、且程序的执行效率提高。 例 3.3 根据考试成绩的等级打印出百分制分数段。 public class GradeLevel public static void main(String args)System.out.println(“nOutPut is:“);char grade=C; /normal useswitch (grade)case A: System.out.println(grade+“is 85100“);break;case B: System.out.println(grade+“is 7084“);break;case C: System.out.println(g
28、rade+“is 6069“);break;case D: System.out.println(grade+“is 60“);break;default: System.out.println(“inputerror“);break 语句在 switch 语中,break 语句用来终止 switch 语句的执行。使程序在 switch 语句后的第一个语句开始执行。 在 Java 中,可以为每个代码块加一个括号。一个代码块通常是用花括号括起来的一段代码。加标号的格式如下: BlockLabel: codeBlock break 语句的第二种使用情况就是跳出它所指定的块,并从紧跟该块的第一条语句
29、处执行。其格式为: break BlockLabel; 例如: a: /标记代码块 ab: /标记代码块 bc: /标记代码块 cbreak a;/will not be executed/will not be executed/will not be executed /execute from here与 C、C+不同, Java 中没有 goto 语句来实现任意的跳转, 因为 goto 语句破坏程序的可读性, 而且影响编译的优化。Java 用 break 来实现 goto 语句所特有的一些功能。 返回语句 returnreturn 语句用于从当前执行的方法中退出, 并返回到调用该方法的
30、语句处继续程序的执行。返回语句有两种格式:return expression 返回一个值给调用该方法的语句, 返回值的数据类型必须与方法声明中的返回值类型一致。可以使用强制类型转换来使类型一致。 return 当方法说明中用 void 声明返回类型为空时 , 可以使用这种格式, 它不返回任何值。不带参数的 return 语句有时可省略。return 语句通常用在一个方法体的最后。 循环语句 循环语句包括 while, do-while, for, continue 等语句。循环语句的作用是反复执行一段代码,直到满足循环终止条件为止,一个循环一般应包括四部分内容: 初始化部分(initializ
31、ation): 用来设置循环的一些初始条件,计数器清零等。循环体部分(body): 这是反复循环的一段代码,可以是单一的一条语句,也可以是复合语句。迭代部分(iteration): 这是在当前循环结束,下一次循环开始前执行的语句,常常用来使计数器加 1 或减 1。终止部分(termination): 通常是一个布尔表达式,每一次循环要对该表达式求值,以验证是否满足循环终止条件。 下面分别介绍 Java 中的 while 语句,do-while 语句和 for 语句。while 语句 while 语句的一般格式为:初始化while (条件表达式 E)语句 S; /循环体当条件表达式 E 的值为
32、true 时,循环执行花括号中的语句 S。S 中包括迭代部分。 while 语句首先计算条件表达式 E 是否成立,当条件成立(true)时,才去执行循环中的语句。所以有可能循环体一次也不执行。 do-while 语句 do-while 语句的一般格式为 : 初始化do 语句 S; /循环体 while (条件表达式 E);do-while 语句首先执行循环体, 然后再计算终止条件, 若结果为 true, 则循环执行语句 S, 直到条件表达式 E 的结果为 false。 与 while 语句不同的是, do-while 语句的循环体至少执行一次。 for 语句 for 语句的一般格式为: for
33、 (初始表达式; 条件表达式; 迭代表达式) 语句 S; /循环体for 语句执行时,首先执行初始化操作,然后判断终止条件是否满足,如果满足,则执行循环体中的语句,最后执行迭代部分。完成一次循环后,重新判断终止条件。 可以在 for 语句的初始化部分声明变量,它的作用域为整个 for 语句。 for 语句通常用来执行循环次数确定的情况( 如对数组元素进行操作)。 在初始化部分和迭代部分可以使用逗号语句来分隔多个操作。例如: for (i=0,j=10; ij; i+,j-) continue 语句 continue 语句用来结束本次循环, 跳过循环体中下面尚未执行的语句 , 接着进行终止条件的
34、判断, 以决定是否继续循环。 也可以用 continue 跳转到括号指明的外层循环中,这时的格式为 continue outerLable; 例 3.4:下例分别用 while、do-while 和 for 语句实现累计求和。public class Sumpublic static void main(String args)System.out.println(“n*while statement*“);int n=10,sum=0; initializationwhile (n0) terminationsum+=n; bodyn-; iterationSystem.out.printl
35、n(“sum is“+sum);System.out.println(“n*do_while statement*“);n=0; initializationsum=0;dosum+=n; bodyn+; iteration while(n=10); terminationSystem.out.println(“sum is“+sum);System.out.println(“n*for statement*“);sum=0;for (int i=1;i=10;i+)sum+=i;System.out.println(“sum is“+sum);可以从中来比较这三种循环语句,从而在不同的场合选
36、择合适的语句。 数组 数组是有序数据的集合, 数组中的每个元素具有相同的类型。数组名和下标可唯一地确定数组中的元素。数组可分为一维数组和多维数组。一维数组 声明方式:type arrayName; 或 type arrayName; type 可以是 Java 中任意的数据类型, arrayName 为数组名。如: int intArray; 声明了一个名为 intArray 的整型数组, 数组中的每个元素为 int 型数据。 Java 在数组的声明中并不为数组元素分配内存, 因此 中不用指出数组中元素个数, 即数组长度。在访问数组的任何元素之前,我们必须为它分配内存空间, 这可用 new 操
37、作符, 其格式如下:arrayName = new typearraySize; 其中,arraySize 指明数组的长度。如: intArray = new int3; 为该数组分配了 3 个 int 型整数所需的内存空间。通常, 这两部分可以合在一起, 格式如下: type arrayName = new typearraySize; 如: int intArray = new int3; 用 new 操作符为数组分配内存空间后,就可以引用数组中的每一个元素。数组元素的引用方式为: arrayNameindex 其中: index 为数组下标,它可以为整型常数或表达式。如 a3, b(i
38、为整型), c6*I等。下标从 0 开始, 一直到数组的长度减 1。对于上面例子中的 intArray 数组来说,它有 3 个元素,分别为 : intArray0, intArray1, intArray2。 (注意: 没有 intArray3。 )另外,与 C、C+中不同,Java 对数组元素要进行越界检查以保证安全性。同时,对于每个数组都有一个属性 length 指明它的长度。例如: intArray.length 指明数组 intArray 的长度。数组的初始化 对数组元素可以按照上述的例子进行赋值。也可以在定义数组的同时进行初始化。 如: int a=1,2,3,4,5; 用逗号(,)
39、分隔数组的各个元素,系统自动为数组分配一定的内存空间。例 3.5:数组的使用:public class ArrayTestpublic static void main(String args)int i;int a=new int5;for (i=0;i5;i+)a=i;for (i=a.length-1;i=0;i-)System.out.println(“a“+i+“=“+a);多维数组 与 C、C+一样, Java 中多维数组可被看作数组的数组。例如二维数组就可看成是一个特殊的一维数组, 该数组的每个元素又是一个一维数组。下面我们主要以二维数组为例来说明多维数组。 二维数组的声明方式如
40、下: type arrayName; 如: int intArray; 与一维数组一样,这时对数组元素也没有分配内存空间,同要使用运算符 new 来分配内存,然后才可以访问每个元素。对二维数组中每个元素,引用方式为: arrayNameindex1index2 其中 index1、index2 为下标, 可为整型常数或表达式, 如 a23等。数组每一维的下标也都从 0 开始。在声明二维数组的同时也可对它进行初始化。如:int a=2,3,1,5,3,4; 定义了一个 32 的数组,并对每个元素赋值。数组的越界 如果使用数组分量时,其下标超过规定的值,则会发生数组的越界。这时,虽然程序能通过编译
41、,但在运行时会产生一个异常比较三:我们知道,在 JAVA 中,子类可以继承父类,如果子类声明的方法与父类有重名的情况怎么办,大伙儿都知道要是重写,但是实际上这又分为两种情况,就是方法和变量在继承时的覆盖和隐藏问题,这些概念性的东西看似无聊,但是在面试或者是 SCJP 认证题中围绕这些是会经常碰到的,我们知道,在 JAVA 中,子类可以继承父类,如果子类声明的方法与父类有重名的情况怎么办,大伙儿都知道要是重写,但是实际上这又分为两种情况,就是方法和变量在继承时的覆盖和隐藏问题,这些概念性的东西看似无聊,但是在面试或者是 SCJP 认证题中围绕这些是会经常碰到的,所以这里来讨论下 首先我们来看几个
42、概念 隐藏 :child 隐藏了 parent 的变量和方法,那么,child 不能访问 parent 被隐藏的变量或者方法,但是,讲 B 转换成 A 中,可以访问 A 被隐藏的变量或者方法 覆盖 :child 覆盖了 parent 的变量或者方法,那么,child 不能访问 parent 被覆盖的变量或者方法,将 child 转换成 parent 后同样不能访问 parent 被覆盖的变量或者方法 首先看一下 JAVA 中方法和变量在继承时的覆盖和隐藏规则 1.父类的实例变量和静态变量能被子类的同名变量隐藏 2.父类的静态方法被子类的同名静态方法隐藏 3.父类的实例方法被子类的同名实例变量覆
43、盖 还有几点需要注意的是 1.不能用子类的静态方法隐藏 父类中同样标示(也就是返回值 名字 参数都一样)的实例方法 2.不能用子类的实例方法覆盖 父类中同样标示的静态方法 3.这点儿请注意,就是变量只会被隐藏 不会被覆盖 ,无论他是实例变量还是静态变量,而且,子类的静态变量可以隐藏 父类的实例变量,子类的实例变量可以隐藏 父类的静态变量 O(_ )O 哈哈 是不是有点儿绕口,没关系 我们看一个实例 创建两个父子类关系的类 /父类 class Parent public static String kind=“javastudy.extendsstudy.parent“; public stat
44、ic int age=50; public String name=“Parent“; /静态方法,返回包名 public static String getKind() System.out.println(“parent 的 getKind()方法被调用了“); return kind; /静态方法,返回年龄 public static int getAge() System.out.println(“Parent 的 getAge()方法被调用了 “); return age; /实例方法,返回姓名 public String getName() System.out.println(“
45、Parent 的 getName()方法被调用了 “); return this.name; /子类 class Child extends Parent public static String kind=“javastudy.extendsstudy.child“; public int age=25; public String name=“child“; /隐藏父类静态方法 public static String getKind() System.out.println(“child 的 getkind()方法被调用了“); return kind; /获取父类包名 public s
46、tatic String getParentKind() return Parent.kind; /覆盖父类实例方法 public String getName() System.out.println(“child 的 getName()被调用了“); return this.name; /获取父类名称 public String getParentName() return super.name; /* *错误,实例方法不能覆盖父类的静态方法 public int getAge() return this.age; */ 然后测试下 class Test public static voi
47、d main(String args) Child child=new Child(); System.out.printf(“子类名称:%s,年龄:%d,包名:%s%n“,child.name,child.age,child.kind); /输出:子类名称:child,年龄:25,包:javastudy.extendsstudy.child /把 child 转换成 parent 对象 Parent parent=child; System.out.printf(“转换后的名称:%s,年龄:%d, 包名:%s%n“,parent.name,parent.age,parent.kind); /输出:转换后的名称:Parent,年龄:50,包:javastudy.extendsstudy.parent System.out.printf(“子类访问父类被隐藏的实例变量name:%s%n“,child.getParentName(); /输出:子类访问父类被隐藏的实例变量 name:Parent System.out.printf(“子类访问父类被隐藏的静态变量 kind:%s“,child.getParentKind(); /输出:子类访问父类被隐藏的静态变量 kind:javastudy.extend