(static修饰的成员属于整个类,而不属于单个对象)
定义:将一个类放到另一个类的内部定义,这个在内部定义的类就叫做内部类(也有的成嵌套类),包含内部类的类被称为外部类(也有的称宿主类)。
1。非静态内部类
没有使用static修饰的内部类就是非静态内部类。
注意:a。java不允许在非静态内部类中定义静态成员
b。当调用非静态内部类中的实例方法时,必须有一个非静态成员内部类实例,非静态内部类实例必须寄生在外部实例内
c。如果外部类成员变量与内部类成员变量与内部类里的方法的局部变量同名,可通过this,外部类类名.this 作为限定来加以区分。
public class Test {
? ? private String prop = "外部类的实例变量";
? ?
? ? public class InClass{
? ? ? ? private String prop = "内部类中的实例变量";
? ? ? ? public void info(){
? ? ? ? ? ? String prop = "局部变量";
? ? ? ? ? ? System.out.println("外部类的实例变量值:"+Test.this.prop);
? ? ? ? ? ? System.out.println("内部类的实例变量值:" + this.prop);
? ? ? ? ? ? System.out.println("局部变量:" + prop);
? ? ? ? }
? ? }
? ? public void test(){
? ? ? ? InClass ic = new InClass();
? ? ? ? ic.info();
? ? }
? ? public static void main(String[] args){
? ? ? ? /*
? ? ? ? * Test ts = new Test();
? ? ? ? * ts.test();
? ? ? ? * 上下的代码作用一样
? ? ? ? */
? ? ? ? new Test().test();
? ? }
}
?
使用非静态内部类:
在外部类以外的地方定义内部类的语法格式: OuterClass.InnerClass? VarName
在外部类以外的地方创建非静态内部类实例的语法: OuterInstace .new? InnerConstructor()
?
class Out{
? ? class In
? ? {
? ? ? ? public In(String msg){
? ? ? ? ? ? System.out.println(msg);
? ? ? ? }
? ? }
}
public class CreateInnerInstance {
? ? public static void main(String[] args){
? ? ? ? //OuterClass.InnerClass varName = new OutInstance.new InnearConstructor();
? ? ? ? Out.In in = new Out().new In("测试信息");
? ? ? ? /*Out.In in;
? ? ? ? *Out out = new Out();
? ? ? ? *in2 = out.new In("测试信息");
?
*/
? ? }
}
?
?
2.静态内部类
静态内部类是用static修饰的内部类,也称类内部类。
a。静态内部类不能访问外部类的实例成员,只能访问外部类的类成员(同为static 修饰)。
c。外部类依然不能访问静态内部类中的成员,但可以使用静态内部类的类名作为调用者来访问静态内部类中的类成员,也可以使用静态内部类对象作为调用者来访问静态内部类中的实例变量。
?
public class StaticInnerClassTest {
? ? private int prop = 5 ;
? ? private static int prop1 = 6 ;
? ? static class InClass{
? ? ? ? public void accessOuterProp(){
? ? ? ? ? ?
private static int prop = 5;
private int prop1 = 6;
//System.out.println(prop); //这句代码会出错,静态内部类无法访问外部类的非静态成员 ? ? ? ? ? ?
? ? ? ? ? ?
System.out.println(prop1);
? ? ? ? }
? ? }
? ? public void accessInnerPro(){
//通过静态内部类的类名访问静态内部类中的类成员
? ?
?
System.out.println(InClass.prop);
//通过静态内部类对象作为调用者来访问静态内部类中的实例变量
SYstem.out.println(new InClass().prop1);
? ? }
}
?
在外部类以外使用使用静态内部类:(和使用非静态比较,相类似)
语法:? new OuterClass.InnerConstructor()
?
class Out{
? ? static class In
? ? {
? ? ? ? public In(){
? ? ? ? ? ? System.out.println("静态内部类的构造器");
? ? ? ? }
? ? }
}
public class CreateStaticInnerInstance {
? ? public static void main(String[] args){
? ? ? ? Out.In in = new Out.In();
? ? }
}
?
3.匿名内部类
如果把一个内部类放到方法中定义,则这个内部类就是一个局部内部类,局部内部类仅在该方法里有效。
定义匿名内部类的格式:
new 实现接口 | 父类构造器(实参列表)
{
? 类体部分
}
可以看出,匿名内部类必须继承一个父类或者实现一个接口。
?
interface Product{
? ? public Double getPrice();
? ? public String getName();
}
public class AnonymTest {
? ?
? ? public void ce(Product p){
? ? ? ? System.out.println("购买了一个" + p.getName() + ",花掉了" + p.getPrice());
? ? }
? ? public static void main(String[] args){
? ? ? ? AnonymTest? at = new AnonymTest();
? ? ? ? at.ce(new Product() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public Double getPrice() {
? ? ? ? ? ? ? ? return 0.5;
? ? ? ? ? ? }
? ? ? ? ? ? @Override
? ? ? ? ? ? public String getName() {
? ? ? ? ? ? ? ? return "辣条";
? ? ? ? ? ? }
? ? ? ? });
? ? }
}