手持终端
Eclipse平台下Android开发环境的搭建
PhoneGap配置到Eclipse开发环境
使用PhoneGap开发Android应用程序
PhoneGap3.0以上版本配置到Eclipse开发环境
使用PhoneGap3.0版本开发Android应用程序
PhoneGap3.0的第三方Android插件
Cordova配置到Android Studio开发环境
Android系统基本架构
Android的字符串颜色图片样式
Android的常用控件及菜单
Android的消息提示及传递
Android系统的组件通信
Android系统的Service
Android的广播消息接收
Android的数据存储与访问
Android系统的网络应用
Android图形图像处理
Android的Fragment框架
Android系统的并发编程
Java源文件结构与保留字
Java语言的数据类型与变量
Java的运算符与流程控制
Java语言的数组及操作
Java面向对象编程
Java的常用类
Android开发常用工具及命令
Android应用程序权限管理
Android系统提供的R类内置资源
Android系统的控件类及其方法
Android系统的菜单类及其方法
Android系统的对话框
Android应用程序模型及组件
Android的绘图类及方法
Android系统的动画效果
Android的数据库操作
Android的多媒体功能
Android系统照相机的使用
Android的文本朗读TTS
获取Android系统信息
Android系统的电话操作
Android系统的定位
Android系统的传感器
Java是一种面向对象的编程语言,核心是类class。
1.类:
1)类的声明:
[<modidiers>] class <class_name> {
[<attribute_declarations>]
[<constructor_declarations>]
[<method_declarations>]
}
各组成部分的含义:
·<modidiers>:修饰符,包括public、private、protected、abstract、final等关键字
·class:关键字,表明是一个类的定义
·<class_name>:类的名称,一般首字母使用大写
·[<attribute_declarations>]:属性attribute声明部分
·<constructor_declarations>:构造方法constructor声明部分
·<method_declarations>:方法method声明部分
示例:
public class Student {
//定义属性
String name;
String sex;
int grade;
int age;
//
public void getName() {
name=_name;
}
public String getName() {
return name;
}
......
}
2)属性的声明:
类定义中所包含的数据称为属性。属性声明的语法为:
[<modidiers>] <data_type> <attr_name>
其中:
·<data_type>:是该属性的数据类型
·<attr_name>:属性名称,一般首字母使用小写
3)方法的声明:
方法表示类的操作,可以认为是类的函数。语法规则为:
[<modidiers>] <return_type> <method_name>([<argu_list>]) {
[<method body>]
}
其中:
·<return_type>:该方法的返回值类型
·<method_name>:方法名,通常首字母为小写
·[<argu_list>]:方法的参数列表,多个参数中间用逗号分隔
·[<method body>]:方法体,0到多行语句
4)构造方法:
构造方法是创建一个类的实例时需要调用的方法。构造方法的修饰符可以使用public、protected、private这类访问的修饰或没有修饰符,而不能使用abstract、final、native、static、synchronized这类非访问性质的修饰。构造器可以有任何类型的返回值,也可以没有返回值,没有返回值不需要使用void。构造方法的名字使用类名,因为类名首字母常用大写,所以构造方法首字母也常为大写。
Java中,每个类都必须至少有一个构造方法。如果没有定义构造方法,编译器会自动加上一个。
2.继承:
在已有类的基础上定义新类,称为继承。已有的类称为基类或父类,在此基础上的新类称为派生类或子类、超类。运用继承,父类的特性不必再重新定义,就可以被其他类继承。继承较好地解决了代码重用问题。
通过关键字extends可以使一个类继承另一个类。Java中,类继承的语法:
<modifier> class <name> [extends <superclass>] {
<declaration>*
}
Java中,一个类只能从一个父类继承,称为单继承。在java.lang包中有一个Object类,这个类是所有类的顶级父类。所有的Java类,包括标准库中的类和自己定义的类,都直接或间接地继承了这个类。这个类没有任何属性,只是定义了一些方法,因此只要定义了一个Java类,就要一些默认的方法供调用。
在Java中,可以在类、类的属性及类的方法前面加上一个修饰符modifier,来对类进行一些访问上的控制。
·private:限制属性或方法只能在同一个类中被访问,在类文件之外则被隐藏,最常用于修饰类中的全局变量。private不能用于修饰类。
·Default:这只是对类、类的属性及类的方法的访问权限的一种称呼。如果在类、类的属性、类的方法前面没有添加任何修饰符,则访问权限是default。这种情况下,只有类本身或者同一个包中的其他类可以访问这些属性或方法,而对于其他包中的类而言是不可访问的。
·protected:protected修饰的属性和方法可以被同一个类、同一个包中的类及子类访问,也不能用于修饰类。
·public:可以修饰类、类的属性和方法,是最宽松的一种限制,修饰的属性及方法可以被任何其他的类访问,无论这个类是否在同一个包中,以及是否是子类。
修饰符 |
同一个类中 |
同一个包中 |
子类中 |
全局 |
private |
Yes |
|
|
|
default |
Yes |
Yes |
|
|
protected |
Yes |
Yes |
Yes |
|
public |
Yes |
Yes |
Yes |
Yes |
一般来说,应该将和其他类无关的属性或者方法设置为private,只有需要将给其他的类访问的属性或方法设为public或protected,或者不加任何修饰符,让其为default。
3.super关键字:
super的作用是用于引用父类的成员,如属性、方法或者构造方法。
1)调用父类的构造方法:
super([arg_list]);
直接用super()加上父类构造方法所需要的参数,就可以调用父类的构造方法。
2)调用父类属性和方法:
super.属性
super.方法()
父类的属性或方法,必须是protected或者public等可以让子类访问的属性或者方法。super用于调用父类中的方法主要用于在子类中定义了和父类中同名的属性,或进行了方法的覆盖,而又要在子类中访问父类中的同名属性或覆盖前的方法时。
4.this关键字:
this代表其所在方法的当前对象。this只能用在构造方法或者方法中,表示对调用此方法的那个对象的引用。如果在方法内部调用同一个类的另一个方法,可以不必显示地使用this,直接调用即可。
1)调用当前对象的属性:
public class Person {
private String name;
private int age;
private String sex;
public String showName() {
return this.name;
}
}
2)引用对象本身:
public class MobileAccount {
private int accountId=0;
public MobileAccount createAccount() {
accountId++;
return this;
}
public int getAccountid() {
return accountId;
}
}
3)构造方法中调用构造方法:
一个类中,由于初始化条件不同,可能定义了多个构造方法,称为构造方法的重载。在这些构造方法中,可能一个构造方法中的一段代码和另一个构造方法完全一样,就可以在这个构造方法中直接调用另一个构造方法,以避免编写相同的代码,可以使用this()。
4)static的含义:
static没有this的静态方法,不可以使用this来调用静态方法。static方法,可以在没有创建任何对象的情况下就通过类本身来调用。
5.方法的覆盖和重载:
1)覆盖:
当一个子类继承了一个父类,也同时继承了父类的属性和方法。如果父类的方法不能满足子类的需求,则可以在子类中对父类的方法进行改造,Java中称为覆盖override。示例:
public class friendCard extends Card {
......
public String showName() {
return "My Friend "+this.name;
}
}
子类中覆盖了父类的方法,在覆盖过程中,需要提供和父类中的被覆盖方法相同的方法名称、输入参数及返回类型。在子类对父类的方法进行覆盖的过程中,不能使用比父类中的被覆盖方法更严格的访问权限。
2)重载:
在Java程序中,如果同一个类中有两个相同的方法(方法名相同、返回值相同、参数列表相同)是不行的。但一个类中,如果有多个方法具有相同的名称,而有不同的参数,是可以的,这种行为称为重载overload。在进行方法重载时,方法的参数列表必须不同,参数个数或者参数数据类型不同,而返回值可以相同,也可以不同。
构造方法也可以重载。
3)通常需要覆盖的几种方法:
①toString方法:
在Object类中,定义了一个toString()方法,用来返回一个表示这个对象的字符串:
public String toString() {
return getClass().getName()+"@"+Integer.toHexString(hashCode());
}
这个方法中,将返回一个由类名、紧随其后的@符号和hash码的无符号的十六进制字符串,用来表示这个对象。所有类都是继承Object,所以所有对象都有这个方法。
通常情况下,需要覆盖父类中的toString()方法,用来提供某对象的自定义信息。Java的API文档中也指出“建议所有子类都重写此方法”。一般来说,大多数类的toString()方法覆盖后返回的用于表示对象的字符串都遵循格式:
类名 [属性1=值1,属性2=值2,...]
示例:
public String toString() {
return getClass()+"["+"name="+name+",sex="=sex+",tele="+tele+"]";
}
在进行String与其他类型数据的连接操作时,会自动调用toString()方法,分两种情况:如果String类型数据和引用数据类型连接,则引用类型数据直接调用其toString()方法返回该对象的字符串;如果String类型数据和简单类型数据连接,则简单类型数据先转换为对应的封装类型,再调用该封装类对象的toString()方法转换为String类型。
②equals():
Java程序设计中,经常需要比较两个变量值是否相等。当比较的是引用对象时,即判断这两个变量是否指向同一个对象引用。
Java中提供了一个equals()方法,用于比较对象的值。在所有类的父类Object中,已经定义了一个equals()方法,这个方法实际上也只是测试两个对象引用是否指向同一个对象,所以经常需要将自己定义的类中的equals()进行覆盖。Integer封装类就覆盖了Object中的equals()方法。
如果测试两个简单类型的数值是否相等,一定要使用==来比较;如果需要比较两个引用变量对象的值是否相等,则用对象的equals()方法来进行比较;如果需要比较两个引用变量是否指向同一个对象,使用==来进行比较。对于自定义的类,应该视情况覆盖Object或其父类的equals()方法。
6.对象的初始化:
当调用类的构造方法来创建对象时,将给新建的对象分配内存,并对对象进行初始化操作。初始化步骤:
1)设置实例变量的值为默认的初始值。2)调用类的构造方法,绑定构造方法的参数。
3)如果构造方法中有this()调用,则根据this()调用的参数调用相应的重载构造方法,然后转到步骤5),否则转到步骤4)。
4)除java.lang.Object类外,调用父类中的初始化块初始化父类的属性,然后调用父类的构造方法。如果在构造方法中有super()调用,则根据super()中的参数调用父类中相应的构造方法。
5)使用初始化程序和初始化块初始化成员。
6)执行构造方法体中的其他语句。
所谓初始化块,就是“游离块”,不管使用哪个构造方法创建对象,都会被首先运行,然后才是构造方法的主体部分被执行。初始化块不是必须的,完全可以将属性的初始化和属性声明结合在一起。
7.封装类:
虽然Java是面向对象的编程语言,但其中的8种基本数据类型并不支持面向对象的编程机制,没有属性、没有方法可调用,是为了能简单有效地进行常规数据处理,也迎合程序员的固有编程习惯。
1)封装类概念:
这种借助非面向对象技术的做法有时会带来不便,比如引用类型数据均继承了Object类的特性,要转换为String时只需要简单调用Object类中定义的toString()方法即可,而基本数据类型转换为String类型就要麻烦很多。为此,Java语言引入了封装类Wrapper Classes的概念。
所有的封装类对象都可以向各自的构造方法传入一个简单类型数据来构造:
boolean b=true;
Boolean B=new boolean(b);
byte by='42';
byte By=new Byte(by);
int i=123;
Integer I=new Integer(i);
......
除了Character外,还可以通过向构造方法传入一个字符串数据来构造,如果传入的字符串不能用于表示对应的值,除了Boolean类型外,将会抛出一个NumberFormatException异常:
Boolean B=new Boolean("true");
Boolean B1=new Boolean("a"); //不抛出异常
try {
Byte By=new Byte("42");
Short S=new Short("121212");
Integer I=new Integer("123456789");
}catch(NumberFormatException e) {
e.printStackTrace();
}
封装在封装类中的值,可以通过各自的xxxValue()方法来转换成简单类型:
·Boolean:public boolean booleanValue()
·Byte:public byte byteValue()
·Character:public char charValue()
·Double:public double doubleValue()
·Float:public float floatValue()
·Integer:public int intValue()
·Long:public long longValue()
·Short:public short shortValue()
2)自动装箱与拆箱:
在JDK5.0中,引入了自动装箱/拆箱(Autoboxing/Unboxing)功能,可以方便地在简单类型和对应的封装类型数据之间转换。示例:
Integer iObject=100;
在之前的版本中是非法的,因为不能将一个简单类型的数据赋值给引用类型的变量。JDK5.0中,通过自动装箱功能,可以将简单类型数据装到对应的封装类型中。
相反地,通过自动拆箱功能,可以将封装类型的数据赋值给对应简单类型变量:
int i=new Integer(100);
在Java中,为了节省创建对象的时间和空间,对于一些常用的对象,会将它在内存中缓存起来。对于如下范围内的简单数据类型:boolean类型的值、所有byte类型的值、在-128~127之间的short类型的值、在-128~127之间的int类型的值、在\u0000~\u007f之间的char类型的值,在使用自动装箱转换成相关封装类型对象的时候,也会如此处理。首先检查内存中是否已经有使用自动装箱产生的具有相同值的对象,如果已经有,那么并不会产生新的对象,而是直接使用已经存在的那个对象。
3)实现小数的精确计算:
编写Java程序时经常需要用到小数。因为计算机中的数字表示方法的原因,小数往往并不能被精确表示和计算,而是变成一个最接近的值。对于需要精确计算结果的地方,需要使用int或者long类型数据,得到最终结果后,再除以适当的10的倍数,来获得精确的小数。
也可以使用BigDecimal来进行精确的小数计算。BigDecimal位于java.math包中,有4个构造方法,其中有两个接收BigInteger参数,还有两个使用String或double类型参数。不要使用double类型参数的构造方法,而要使用String类型参数的构造方法。在这个类上定义了很多加减乘除运算的方法,包括add()、subtract()、multiply()、divide(),另外还有进行小数点移位运算的movePointleft()和movepointRight()等。示例:
import java.math.BigDecimal;
public class TestFloat {
public static void main(String args[]) {
BigDecimal nd1=new BigDecimal("0.05");
BigDecimal nd1=new BigDecimal("0.01");
System.out.println(bd1.add(bd2));
}
}
8.特殊的类及属性和方法:
1)Static关键字:
静态属性和方法,希望某个方法不与包含它的类的任何对象关联在一起,即使没有创建对象,也可以调用这个方法。
public class Statictest {
static int i=27;
public static void main(String args[]) {
StaticTest st1=new StaticTest();
StaticTest st2=new StaticTest();
System.out.println(st1.i+st2.i);
}
static void staticMethod() {
StaticTest.i++;
}
}
Java中,static最常用在Java应用程序的入口方法main()前面,用于修饰main()方法,表示main()得到是一个类方法。在执行一个应用程序时,解析器将会寻找这个main()方法。在调用这个main()方法之前,还没有任何对象存在,如果不将其这样设置,则没有办法得到任何的对象,也就无法调用这个main()方法。
可以直接通过类名来引用static变量,可以通过类名来引用静态方法。静态方法中只能调用类中的静态成员。
2)final关键字:
final关键字表示修饰的类、方法或变量不可被改变。
Java不能使用const定义常量,在需要使用常量的场合,可以使用final关键字来修饰:
final int CONST_VAR=30;
进行定义时必须赋值,一旦初始化后就不能被改变。如果final变量是引用类型变量,那么就不能改变这个变量的引用,但可以改变这个变量所引用的对象的属性。
同时用static和final来修饰的变量,只占据一段不能改变的存储空间:
static final int MAX_TAX_RATE=20;
这时这个常量的名字建议都大写,并且指出完整含义,如果需要用几个单词,单词之间用下划线来分隔。这是对编译时就能得到值的情况。如果运行时才能得到值,就不需要使用上面的命名方法。
final关键字可以将方法锁定,防止任何继承类修改它的含义,避免被覆盖。
如果final修饰类名,这样的类不能被继承,比如java.lang.Math。如果不想类被继承,可以将类定义为final类。final类的所有方法都隐式指定为final。
3)抽象类:
只是定义某些类的框架作为导出类的通用接口,但不具体实现,而将具体实现放在子类中去完成。将这种类定义为抽象类,用abstract来修饰,而将没有实现的方法声明为abstract。抽象类只能继承,而不能实例化。示例:
public abstract class IconShape {
public abstract double iconArea();
}
如果一个类中定义了一个或多个抽象方法,那么这个类必须被限定为抽象类,但抽象类里面未必一定要有抽象方法,有时就是为了避免被实例化。
子类继承抽象类时与继承普通父类相同:
public class Circle extends IconShape {
public double radius;
public static final double PI=3.14;
public double iconArea() {
return PI*radius*radius;
}
}
子类必须覆盖所有抽象方法才能被实例化,否则子类还是一个抽象类。
9.接口:
1)接口的定义:
interface关键字产生了一个完全的抽象类--接口。接口是方法声明和常量值定义的集合,没有为方法提供任何具体的实现。接口的定义不使用class:
<modifier> interface <name>[extends <superinterface>] {
[<attribute_declarations>]
[<abstract_method_declarations>]
}
接口中可以定义常量,但不能有变量。接口的成员属性都会被自动加上public、static和final,而接口中的方法也会自动设置为public。接口中的方法只需要声明,不需要方法体。示例:
public interface ScreenBrightness {
public int DEFAULT_BRIGHTNESS=10;
void brightUp();
void brightDown();
}
这个接口定义了一个表示屏幕亮度调节的接口ScreenBrightness。
对于接口,子类中使用implements来实现它。一个类可以继承一个父类,并且同时实现一个或多个接口,多个接口之间用逗号分隔:
<modifier> class <name> [extends <superclass>]
[implements <interface> [,<interface>]* ] {
<declarations> *
}
2)接口的多实现:
在Java中,一个类只能继承一个父类,不支持多继承;但一个类可以实现多个接口。通过接口,可以模拟实现多继承。示例:
public interface Volume{
public int DEFAULT_VOLUME=5;
void volumeUp();
void volumeDown();
}
这个接口定义了一个表示手机音量的接口Volume。然后定义一个类:
public class MobileSet implements ScreenBrightness,Volume {
public int brightness;
public int volume;
public MobileSet() {
this.brghtness=DEFAULT_BRIGHTNESS;
this.volume=DEFAULT_VOLUME;
}
public void brightUp() {
this.brightness++;
}
public void brightDown() {
this.brightness--;
}
public void volumeUp() {
this.volume++;
}
public void volumeDown() {
this.volume--;
}
public static void main(String[] args) {
MobileSet ms=new mobileSet();
ms.brightUp();
ms.volumeDown();
}
}
这个类中,同时实现了ScreenBrightness和Volume两个接口,然后将两个接口中的方法实现,使该类拥有调节手机屏幕亮度和手机音量的双重功能。
3)接口的扩展:
接口和类类似,可以从一个父接口中派生。接口的继承也使用extends关键字。语法为:
<modifier> interface <name>
[extends <super_interface>,<super_interface>] {
[<attribute_declarations>]
[<abstract_method_declarations>]
}
接口可以继承多个接口,只需要将继承的各个接口用逗号隔开。通过继承,可以在接口中添加新的方法声明,还可以通过继承在新接口中组合数个接口。示例:
public interface MobileSet extends ScreenBrightness,Volume {
void showData();
}
在这个接口中,除了继承的方法外,还新增了一个方法,这样通过接口的组合,扩展出了一个新的接口。
10.多态:
1)概念:
在Java中,对象变量是多态的,一个类型为Aclass的变量,既可以指向类型为Aclass的对象,也可以指向Aclass的任何子类的对象。多态的作用是消除类型之间的耦合关系。示例:
Aclass a=new Bclass();
将子类Bclass的对象赋给父类变量,体现了替换原则substitution principle,这种能力也称动态绑定。以多态的形式传递参数,增强了参数类型的灵活性。
2)instanceof操作符:
Java的多态性,导致引用变量的声明类型和其实际引用对象的类型可能不一致。为了更准确地鉴别一个对象的真正类型,引入了instanceof操作符:
<引用类型变量> instanceof <引用类型>
这是一个boolean类型的表达式,指出对象是否是特定的一个实例。当instanceof左侧的引用类型变量所引用对象的实际类型是其右侧给出的类型或其子类类型时,整个表达式的结果为true,否则为false。
3)引用类型转换:
对于引用类型,也有相互转换机制,也分为自动转换和强制转换两种情况。将子类的实例转换为父类的实例总是可行的,因为子类的实例也是父类的实例;而把父类对象转换为子类对象时,必须使用强制类型转换。
对象的强制转换可以使用运算符“()”来完成:
Superclass sup=new SubClass();
SubClass sub=(SubClass)sup;
无论是自动造型还是强制造型,都只能在有继承关系的对象之间。并不是任意的父类类型数据都可以被造型为子类类型,只有多态情况下,原本就是子类类型的对象被声明为父类的类型,才可以通过转换恢复其“本来面目”,否则会在程序运行时出错。所以进行转换时确保该对象是另一个类的实例,可以利用instanceof运算符来完成。示例:
Card c=FriendCard();
if(c instanceof ColleagueCard) {
ColleagueCard cc=(ColleagueCard)c;
}
父类对象与和子类对象的转化的原则:
·子类对象可以被视为是其父类的一个对象;
·父类对象不能当成是其某个子类的对象;
·如果一个方法的形式参数定义的是父类对象,那么调用这个方法时,可以使用子类对象作为形式参数;
·如果父类对象引用指向的实际是一个子类对象,那么这个父类对象的引用可以用强制类型转化成子类对象的引用。在转换之前要使用instanceof运算符进行判断。
11.内部类:
内部类也称为嵌套类,是定义在一个类内部的类,它可以是其他类的成员,也可以在一个语句块的内部定义。引入内部类,在一个内部类的对象能够访问创建它的对象的实现,包括私有数据;对于同一个包中的其他类来说,内部类能够隐藏起来;匿名内部类可以方便地用在回调方法(Callback Method)中,典型应用是图形编程中的事件处理。
1)定义:
内部类是定义在一个外围类的内部,指的是在类定义的两个大括号之间:
public class OuterClass {
//可以在这个类的内部的任何地方定义内部类
}
内部类可以定义在类中的任何位置,甚至方法体中也可以定义内部类。示例:
public class Outer {
private int a=5;
public class Inner {
private int i=1;
public void innerMethod() {
System.out.println("a="+a+", i="+i);
}
}
public void testTheInner() {
Inner i=new Inner();
i.innerMethod();
]
}
编译这个文件,将会产生两个class文件,Outer.class和Outer$Inner.class,前面一个是类文件是Outer类文件,后面一个是内部类类文件,用$来分隔开内部类和外部类。
2)内部类的使用:
在Outer类内部使用到内部类,与使用普通类没什么区别;但在Outer类范围以外的其他应用中,实例化内部类必须首先有一个外部类实例存在,然后通过外部类实例来实例化内部类:
Outer.Inner in=new Outer().new Inner();
如果需要在另一个应用程序中使用刚才定义的类Outer的内部类Inner:
public class TestInner {
public static void main(String[] args) {
Outer.Inner oi=new Outer().new Inner();
oi.innerMethod();
}
}
可以将一个内部类定义成一个静态内部类,只需要在内部类定义前面加上static关键字。如果内部类是静态static的,也可以使用:
Outer.Inner in=new Outer.Inner();
内部类可以使用protected和private来修饰,以限制在它的外部类以外的地方对它的访问。如果修饰为private,就不能在Outer的范围外使用Inner类了。
3)局部内部类:
Inner类可以定义在方法内部,或者类的一个自由块中,这时就是一个局部内部类,只能在方法体或者自由块中使用。局部内部类不能有访问说明符,可以访问当前代码块内的常量,以及此外部类的所有成员。在类外不可直接访问局部内部类,以保证局部内部类对外是不可见的。如果要在方法体中定义的局部内部类中使用方法的局部变量,需要将这个局部变量定义为final的。示例:
public class Outer {
public void test(int 1) {
class LocalClass {
public void localTest() {
System.out.println("局部内部类的方法被调用");
]
}
LocalClass lc=new LocalClass();
lc.localTest();
}
public static void main(String[] args) {
Outer o=new Outer();
o.test(1);
}
}
在方法test()中可直接初始化局部内部类LocalClass。外部类Outer不能直接访问局部内部类LocalClass,Outer类对象调用test()方法间接访问内部类。
4)匿名内部类:
内部类可以不用指定类名,这就是匿名内部类。匿名内部类可以看做是一种特殊的局部内部类,是通过匿名类实现接口。如果恰好只要创建一个局部内部类的对象,可以使用匿名内部类,存在于一个表达式中,经常用在图形界面的事件处理中。示例:
public class AnInnerTest {
interface AnInfc {
public void printInfo();
}
public static void main(String[] args) {
AnInnerTest a=new AnInnerTest();
AnInfc af=a.testAn();
af.printInfo();
}
public AnInfc testAn() {
return new AnInfc() {
public void printInfo() {
System.out.println("anonymous class");
}
}
}
}
满足下面的条件,使用匿名内部类比较合适:
·只用到类的一个实例;
·类的定义后马上用到;
·类非常小,推荐是4行以下代码;
·给类命名并不会使代码更容易被理解。
使用匿名内部类的原则:
·匿名内部类不能有构造方法;
·匿名内部类不能定义任何静态成员、方法和类;
·匿名内部类不能是public、protected、private、static;
·只能创建匿名内部类的一个实例;
·一个匿名内部类一定是在new后面,用其隐含实现一个接口或实现一个类;
·因匿名内部类为局部内部类,对局部内部类的所有限制都对其有效。
示例:用继承抽象类的形式使用匿名内部类
public class AnInnerTest {
interface AnInfc {
public void printInfo();
}
public static void main(String[] args) {
Person p=new Person("Alex");
public void printInfo() {
System.out.println("name "+this.getName());
}
}
p.printInfo();
}
}
abstract class Person {
private String name;
public Person(String n) {name=n;}
protected String getName() {return name;}
protected void setName(String name) {this.name=name;}
public abstract void printInfo();
}
5)内部类的特性:
Inner class可以声明为抽象类,因此可以被其他的内部类继承,也可以声明为final类。
Inner class可以声明为private或protected。
Inner class可以声明为static类型,但此时就不能再使用外层封装类的非static的成员变量。
非static的内部类中的成员不能声明为static类型,只有在顶层类或static的内部类中才可声明static成员。
6)修饰符的适用范围:
关键字 |
class |
属性 |
方法 |
构造方法 |
自由块 |
内部类 |
public |
Y |
Y |
Y |
Y |
|
Y |
protected |
|
Y |
Y |
Y |
|
Y |
Default |
Y |
Y |
Y |
Y |
Y |
Y |
private |
|
Y |
Y |
Y |
|
Y |
final |
Y |
Y |
Y |
|
|
Y |
abstract |
Y |
|
Y |
|
|
Y |
static |
|
Y |
Y |
|
Y |
Y |