千峰Java教程:068. 内部类详解②

书接上文

静态内部类

在一个类内部定义一个静态内部类:

静态的含义是该内部类可以像其他成员一样,没有外部类对象时,也能够访问它。静态嵌套类仅能访问外部类的静态成员和方法。下面代码我们重点看有关Inner3的代码:

public class Demo1
{
	public static void main(String[] args)
	{
		Outer outer = new Outer();
		
		//在外部创建成员内部类的实例:
		/*Outer.Inner inner =outer.new Inner();
		//调用内部类方法:
		inner.print();
		
		outer.innerPrint();
		outer.show();*/
		
		Outer.Inner3 n = new Outer.Inner3();//Inner3的内部类
		n.print();
	}
}

class Outer
{
	private String name;
	//添加这个方法:
	public void innerPrint()
	{
		Inner inner = new Inner();
		inner.print();
	}
	private class Inner//成员内部类
	{
		public void print()
		{
			System.out.println("成员内部类");
		}
	}
	public void show()//方法内部类
	{
		int x = 10;
		class Inner2//
		{
			public void print()
			{
				//x++;//这里就会出现错误: 从内部类引用的本地变量必须是最终变量或实际上的最终变量,因为上面的x=10这个10就已经是最终变量了,int x = 10;可以理解成final int x = 10;
				System.out.println("方法内部类"+x);
			}
		}
		Inner2 inner2 = new Inner2();//增加这行跟下面这行
		inner2.print();
	}
	static class Inner3
	{
		public void print()
		{
			System.out.println("这是静态内部类");
		}
	}	
}
/*
结果:
这是静态内部类
*/

这样写的目的就是基于封装的概念,内部类跟外部类之间一定是有关系的,否则不会出现内部类概念。比如你家里的亲戚能住在你家,一般大街上一个人能随便让他住在自己家吗?说是有相对关系,只不过,这个相对关系比较独立,这个内部类附属在外部类里面,有一定的关系,但是没有实际上的代码调用关系,这就是封装。刚才说了,在静态内部类里面是不能访问外部类的属性的(在普通内部类和方法内部类可以),因为静态类里面只能访问静态变量。

匿名内部类

匿名内部类就是没有名字的内部类。

匿名内部类三种情况:

(1)继承式的匿名内部类;

(2)接口式的匿名内部类;

(3)参数式的匿名内部类。

 

先看继承式匿名内部类:

public class Demo1
{
	public static void main(String[] args)
	{
		Outer outer = new Outer();
		
		//在外部创建成员内部类的实例:
		/*Outer.Inner inner =outer.new Inner();
		//调用内部类方法:
		inner.print();
		
		outer.innerPrint();
		outer.show();
		
		Outer.Inner3 n = new Outer.Inner3();//Inner3的内部类
		n.print();*/
		
		outer.print1();
	}
}

class Outer
{
	private String name;
	//添加这个方法:
	public void innerPrint()
	{
		Inner inner = new Inner();
		inner.print();
	}
	private class Inner//成员内部类
	{
		public void print()
		{
			System.out.println("成员内部类");
		}
	}
	public void show()//方法内部类
	{
		int x = 10;
		class Inner2//
		{
			public void print()
			{
				//x++;//这里就会出现错误: 从内部类引用的本地变量必须是最终变量或实际上的最终变量,因为上面的x=10这个10就已经是最终变量了,int x = 10;可以理解成final int x = 10;
				System.out.println("方法内部类"+x);
			}
		}
		Inner2 inner2 = new Inner2();//增加这行跟下面这行
		inner2.print();
	}
	static class Inner3
	{
		public void print()
		{
			System.out.println("这是静态内部类");
		}
	}
	public void print1()//继承式匿名内部类
	{
		Cat cat = new Cat()//新建一个对象
		{
			public void eat()
			{//加大括号,表示实现
				System.out.println("cat:匿名继承内部类");
			}
		};//这里一定要加分号,从61行到这一行是一条语句。	
		cat.eat();
	}
}

abstract class Cat//抽象类,下面要有抽象方法,应加abstract
{
	public abstract void eat();
}
/*
结果:
cat:匿名继承内部类
*/
//这个内部类创建以后,也会产生成一个Outer$1.class文件

然后是接口式匿名内部类:

public class Demo1
{
	public static void main(String[] args)
	{
		Outer outer = new Outer();
		
		//在外部创建成员内部类的实例:
		/*Outer.Inner inner =outer.new Inner();
		//调用内部类方法:
		inner.print();
		
		outer.innerPrint();
		outer.show();
		
		Outer.Inner3 n = new Outer.Inner3();//Inner3的内部类
		n.print();*/
		
		outer.print1();
		outer.print2();
	}
}

class Outer
{
	private String name;
	//添加这个方法:
	public void innerPrint()
	{
		Inner inner = new Inner();
		inner.print();
	}
	private class Inner//成员内部类
	{
		public void print()
		{
			System.out.println("成员内部类");
		}
	}
	public void show()//方法内部类
	{
		int x = 10;
		class Inner2//
		{
			public void print()
			{
				//x++;//这里就会出现错误: 从内部类引用的本地变量必须是最终变量或实际上的最终变量,因为上面的x=10这个10就已经是最终变量了,int x = 10;可以理解成final int x = 10;
				System.out.println("方法内部类"+x);
			}
		}
		Inner2 inner2 = new Inner2();//增加这行跟下面这行
		inner2.print();
	}
	static class Inner3
	{
		public void print()
		{
			System.out.println("这是静态内部类");
		}
	}
	public void print1()//继承式匿名内部类
	{
		Cat cat = new Cat()//新建一个对象
		{
			public void eat()
			{//加大括号,表示实现
				System.out.println("cat:匿名继承内部类");
			}
		};//这里一定要加分号,从61行到这一行是一条语句。	
		cat.eat();
	}
	public void print2()//接口式匿名内部类
	{
		Eat eat = new Eat()//接口是不能被新建的,所以我们加了个大括号,来实现这个接口,然后,大括号后面记得要加分号
		{
			public void eat()
			{
				System.out.println("cat:匿名接口式内部类");
			}
		};
		eat.eat();
	}
}

interface Eat
{
	public void eat();
}

abstract class Cat//抽象类,下面要有抽象方法,应加abstract
{
	public abstract void eat();
}
/*
结果:
cat:匿名继承内部类
cat:匿名接口式内部类
*/
//再创建这个匿名内部类时,就又会生成一个Outer$2.class文件

然后是参数是内部类

public class Demo1
{
	public static void main(String[] args)
	{
		Outer outer = new Outer();
		
		//在外部创建成员内部类的实例:
		/*Outer.Inner inner =outer.new Inner();
		//调用内部类方法:
		inner.print();
		
		outer.innerPrint();
		outer.show();
		
		Outer.Inner3 n = new Outer.Inner3();//Inner3的内部类
		n.print();*/
		
		outer.print1();
		outer.print2();
		outer.print3(new Eat()
		{
			public void eat()//方法在这里写
			{
				System.out.println("参数式匿名内部类");//这里不要加eat了,会提示错误: 找不到符号
			}
		});//也可以传多个参数,中间加逗号,那样写就比较复杂了
	}
}

class Outer
{
	private String name;
	//添加这个方法:
	public void innerPrint()
	{
		Inner inner = new Inner();
		inner.print();
	}
	private class Inner//成员内部类
	{
		public void print()
		{
			System.out.println("成员内部类");
		}
	}
	public void show()//方法内部类
	{
		int x = 10;
		class Inner2//
		{
			public void print()
			{
				//x++;//这里就会出现错误: 从内部类引用的本地变量必须是最终变量或实际上的最终变量,因为上面的x=10这个10就已经是最终变量了,int x = 10;可以理解成final int x = 10;
				System.out.println("方法内部类"+x);
			}
		}
		Inner2 inner2 = new Inner2();//增加这行跟下面这行
		inner2.print();
	}
	static class Inner3
	{
		public void print()
		{
			System.out.println("这是静态内部类");
		}
	}
	public void print1()//继承式匿名内部类
	{
		Cat cat = new Cat()//新建一个对象
		{
			public void eat()
			{//加大括号,表示实现
				System.out.println("cat:匿名继承内部类");
			}
		};//这里一定要加分号,从61行到这一行是一条语句。	
		cat.eat();
	}
	public void print2()//接口式匿名内部类
	{
		Eat eat = new Eat()//接口是不能被新建的,所以我们加了个大括号,来实现这个接口,然后,大括号后面记得要加分号
		{
			public void eat()
			{
				System.out.println("cat:匿名接口式内部类");
			}
		};
		eat.eat();
	}
	public void print3(Eat eat)//参数式匿名内部类,要往方法里传一个参数(把接口当参数)
	{
		eat.eat();
	}
}

interface Eat
{
	public void eat();
}

abstract class Cat//抽象类,下面要有抽象方法,应加abstract
{
	public abstract void eat();
}
/*
结果:
cat:匿名继承内部类
cat:匿名接口式内部类
参数式匿名内部类
*/

在使用匿名内部类时,要记住以下几个原则:

(1)不能有构造方法,只能有一个实例

(2)不能定义任何形态成员、静态方法

(3)不能是public、protected、private、static

(4)一定是在new的后面,用其隐含实现一个接口或继承一个类

(5)匿名内部类为局部的,所以局部内部类的所有限制都对其生效

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值