内部类(匿名内部类、静态内部类、局部内部类、非静态内部类、)

内部类都可以继承父类和实现多个接口(不过一般不提倡实现多层的内部类)

1.匿名内部类:

     
    匿名:没有名字,即这里说的是类没有名字
 
  内部类:
       在另一个类中声明的类,称为内部类。
    
  匿名对象:对象没名字
 
  1、匿名内部类的语法格式
      我们声明一个类的目的,是为了创建对象,然后通过对象调用方法什么的。
   那么这里这个类都没有名字,那么怎么创建对象。
   
   (1)因为是匿名内部类,那么必须在声明类的同时创建对象。现在不创建,后面没法创建了。
   (2)因为是匿名内部类,那么只能借助它父类或父接口的名字。
   语法格式:
   A:调用父类的无参构造器
    new 父类(){
          写类的成员
    }
    
   B:调用父类的有参构造
    new 父类(实参列表){
          写类的成员
    }
    
   C:用Object的无参构造,因为接口没有构造器
    new 父接口(){
        写类的成员
    }

 

class Father{
	public void method(){
		System.out.println("父类的方法");
	}
}


public static void main(String[] args) {
//是Father的子类对象,这个类没有名字
	//	同时它还创建了一个该子类的对象。
	Father f = new Father(){
			public void method(){
				System.out.println("子类的方法");
			}
		};
}

还可以作为实参传递,形成多态

 

2.静态内部类:

2、特点
   (1)静态内部类它也是一个类
                它的字节码文件名:外部类名$静态内部类名.class

   (2)静态内部类也可以有自己的成员:没有限制
               所有类的成员在静态内部类中都可以声明。
   
   (3)静态内部类是否可以使用外部类的成员,包括私有的(可以)、静态的(有限制)?
                有限制。静态内部类不能使用外部类的非静态成员。
 
  (4)在外部类中使用静态内部类是否有限制?没有限制
    说明:如果你要使用静态内部类的静态方法等,那么直接使用"静态内部类名."即可
              如果你要使用静态内部类的非静态方法等,那么直接使用"静态内部类对象."即可
        
  (5)在外部类的外面  使用静态内部类是否有限制?没有限制
    说明:如果你要使用静态内部类的静态方法等,那么直接使用"静态内部类名."即可
              如果你要使用静态内部类的非静态方法等,那么直接使用"静态内部类对象."即可
    只不过在外面使用时,要注意静态内部类的全名称是“包名.外部类名.静态内部类名",可以使用import语句简化使用

   (6)在外部类可以使用静态内部类的私有属性

public class TestStaticInner {
	public static void main(String[] args) {
		//调用Inner类中的test()方法
		Inner in = new Inner();
		in.test();
		
		//调用Inner类中的method()方法
		Inner.method();
		
/*		//调用Inner类中的test()方法
		Outer.Inner in = new Outer.Inner();
		in.test();
		
		//调用Inner类中的method()方法
		Outer.Inner.method();*/
	}
}

class Outer{
	private static int a = 1;
	private int b = 2;
	
	public static class Inner{
		public void test(){
			System.out.println(a);
//			System.out.println(b);//错误的
		}
		public static void method(){
			System.out.println(a);
//			System.out.println(b);//错误的
		}
	}
	
	public void outTest(){
		//调用Inner类中的test()方法
		Inner in = new Inner();
		in.test();
		
		//调用Inner类中的method()方法
		Inner.method();
	}
	
	public static void outMethod(){
		//调用Inner类中的test()方法
		Inner in = new Inner();
		in.test();
		
		//调用Inner类中的method()方法
		Inner.method();
	}
}

 3.非静态内部类

2、特点
  (1) 非静态内部类也是类,也有自己的字节码文件
    外部类名$非静态内部类名.class
    
  (2) 非静态内部类中声明成员,是否有限制
                    有限制:不能有静态的成员
 
 (3)非静态内部类中使用外部类的成员是否有限制
                         没有限制
 
  (4)在外部类中使用非静态内部类是否有限制
                有限制
                 静态方法等成员中不能使用非静态内部类
 
  (5)在外部类的外面使用非静态内部类
             可以使用,只不过需要外部类的对象,才能使用非静态内部类

   (6)在外部类中可以使用内非静态内部类的私有属性
 

public class TestNonStaticInner {
	public static void main(String[] args) {
		//使用Outer的outMethod()
		Outer out = new Outer();
		out.outMethod();
		
		//使用Inner的method
		//即要使用非静态内部类需要外部类的对象
		//Outer.Inner in = out.new Inner();
	//	Outer.Inner in = out.getInner();//换一种方法
		
		Inner in = out.getInner();
		in.method();
	}
}
class Outer{
	private static int a;
	private int b;
	
	class Inner{
		public void method(){
			System.out.println(a);
			System.out.println(b);
		}
	}
	
	public void outMethod(){
		//使用Inner的method
		Inner in = new Inner();
		in.method();
	}
	
	public static void outTest(){
		//使用Inner的method
//		Inner in = new Inner();//错误的,因为outTest方法是静态的,不能使用非静态的Inner
//		in.method();
	}
	
	//返回非静态内部类的对象
	public Inner getInner(){
		return new Inner();
	}
}

4.局部内部类

 2、特点
  (1)局部内部类也是类,也是有字节码文件
       外部类名$编号局部内部类名.class
   
  (2)局部内部类中声明类的成员,是否有限制
     不能有静态成员
 
  总结:除了静态内部类中可以有静态成员,其他的内部类中统统都不能声明静态成员。
 
  (3)在局部内部类中使用外部类的成员,是否有限制
      有限制,但是限制和局部内部类无关,看所在的方法,所在的方法是静态的,就不能使用非静态的
 
  (4)在外部类中,使用局部内部类是否有限制?
      局部内部类有作用域
 
  (5)在外部类的外面使用局部内部类?不能
  (6)在外部类的外面是否可以获取局部内部类的对象?可以,但是只能用父类或父接口的变量接收这个对象
 
  (7)在局部内部类中可以使用外部类的作用域范围内的局部变量,但是这个局部变量必须是final的。
      JDK1.8之前,必须手动加final,JDK1.8之后默认自动加final
 
 为什么?
        如果没有final,那么就是普通的局部变量,是在栈中存储,那么方法调用结束后,就内存自动释放了,
        而我们方法中的局部内部类的对象可能被返回到外面使用,如果通过这个对象调用方法,又要使用这个局部变量,
        就无法访问了。所以要用final修饰,使得它称为常量,值存储到方法区的常量池中。
    
    强调:匿名内部类也是局部内部类的一种,只是没有名字。

public class TestLocalInner {
	public static void main(String[] args) {
		Outer out = new Outer();
		Object obj = out.test4();
		System.out.println(obj.getClass());//获取对象的运行时类型
		
//		obj.method();//obj编译时类型是Object类型,无法向下转型为Inner了
		
		MyInter my = out.test5();
		my.method();
	}
}
class Outer{
	private static int a;
	private int b;
	
	public void test1(){
//		Inner in = new Inner();//错误的
		
		class Inner{
			public void method(){
				System.out.println(a);
				System.out.println(b);
			}
		}
		
		Inner in = new Inner();
		in.method();
	}
	
	public static void test2(){
		class Inner{
			public void method(){
				System.out.println(a);
//				System.out.println(b);//错误的,test2是静态的,不能使用b
			}
		}
	}
	
	public void test3(){
		//调用Inner的method方法
//		Inner in = new Inner();//错误,无法使用,因为上面的Inner都是局部的,都有作用域
//		in.method();
	}

	public Object test4(){
		class Inner{
			public void method(){
				System.out.println(".....");
			}
		}
		
		Inner in = new Inner();
		return in;
	}
	
	public MyInter test5(){
		
		final int num = 10;//外部类Outer的test5方法的局部变量
		
		class Inner implements MyInter{

			@Override
			public void method() {
				System.out.println("num = " + num);
			}
			
		}
		return new Inner();
	}
}
interface MyInter{
	void method();
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值