三种java内部类及其应用场景

内部类:
	成员内部类
	局部内部类
	匿名内部类
内部类仍然是一个独立的类,在编译之后会被编译成独立的.class文件,
但是前面冠以外部类的类名和$号
内部类不能用普通的方式访问,内部类是外部类的一个成员
,因此内部类可以自由的访问外部类的成员变量,无论是否是private。

(1)成员内部类

import IO_liu.Outer.Inner;

public class IO_liu {
	public static void main(String[] args) {
//		调用外部类
//		在内部类中,可以直接访问外部类的成员,包括私有成员
//		Outer o = new Outer();
//		o.method();
//		访问内部类
		Outer.Inner cry = new Outer().new Inner();
		cry.function();
	}
	
}
class Outer{
//	成员内部类
	private String num = "我可以访问外部类的私有成员变量";
	public void method() {
//		可以在外部类的方法中创建内部类的对象并调用
		Inner i = new Inner();
		i.function();
		System.out.println("我是外面类的一个主类");
	}
	class Inner{
		public void function() {
			System.out.println("我是外面的一个类中的一个内部类!"+num);
		}
	}
}

成员内部类的private修饰需要注意的地方:

package IO_liu;

import IO_liu.Outer.Inner;
//成员内部类的修饰符:
//		我们可以使用权限修饰符去修饰成员内部类,但是如果使用private来进行修饰,则无法在其他类中进行使用

public class com {

	public static void main(String[] args) {
//		私有的成员只能在当前的类中进行调用,所以此处报错,无法在此对私有化的类进行实例化
		Outer2.Inner2 i = new Outer2().new Inner2();

	}

}
class Outer2{
	public void method() {
		Inner2 i = new Inner2();
	}
//	此处的类如果不写就是默认的public,如果此处设为private,则在主方法中无法进行实例化调用
	private class Inner2{
		public void function() {
			System.out.println("function");
		}
	}
}

使用static修饰成员内部类:

public class com {

	public static void main(String[] args) {
//		静态的类中不一定包含静态方法,但是含有静态方法的类一定是静态类
//而且不需要再创建对象,直接通过类名方法名进行调用
		Outer2.Inner2.function();

	}

}
class Outer2{
	public void method() {
		Inner2 i = new Inner2();
	}
//	此处的类如果不写就是默认的public,如果此处设为private,则在主方法中无法进行实例化调用
	static class Inner2{
		public static void function() {
			System.out.println("function");
		}
	}
}

(2)局部内部类

//局部内部类在方法中,出了方法就无法使用,
//使用的场景较另外的两种内部类相对少一点
public class com {
	public static void main(String[] args) {
		Outer o = new Outer();
		o.method();
	}

}

class Outer {
	public void method() {
		class Inner{
			public void function() {
				System.out.println("function");
			}
		}
		
		Inner inner = new Inner();
		inner.function();
	}
	public void test() {
		
	}
}

(3)匿名内部类的两种格式
第一种格式
只能当做对象一次性使用了

package IO_liu;

/*
 * 匿名内部类就是一个没有名字的局部内部类
 * 定义在方法中方
 * 必须在定义匿名内部类的时候创建他的对象
 * 格式:
 * 		new 类/接口(){
 * 			如果创建了继承这个类的子类对象,我们可以重写父类的方法
 * 			如果是创建了实现这个接口的子类对象,我们必须要实现该接口的所有方法
 * 		};
 * 原理:创建了继承这个类的子类对象或者是创建了实现这个接口的子类对象
*/
public class com {
	public static void main(String[] args) {
		Outer o = new Outer();
		o.method();
	}

}
//创建接口
interface Inner{
	public void function();
}

class Outer{
	public void method() {
//		创建匿名对象
		new Inner() {

			@Override
			public void function() {
				System.out.println("我是匿名对象,不是小三");
			}
			
		}.function();

	}
}


另外一种格式:
可以多次调用

package IO_liu;

/*
 * 匿名内部类就是一个没有名字的局部内部类
 * 定义在方法中方
 * 必须在定义匿名内部类的时候创建他的对象
 * 格式:
 * 		new 类/接口(){
 * 			如果创建了继承这个类的子类对象,我们可以重写父类的方法
 * 			如果是创建了实现这个接口的子类对象,我们必须要实现该接口的所有方法
 * 		};
 * 原理:创建了继承这个类的子类对象或者是创建了实现这个接口的子类对象
*/
public class com {
	public static void main(String[] args) {
		Outer o = new Outer();
		o.method();
	}

}
//创建接口
interface Inner{
	public void function();
}

class Outer{
	public void method() {
//		创建匿名对象
		Inner i = new Inner() {

			@Override
			public void function() {
				System.out.println("我是匿名对象,不是小三");
			}
			
		};
		//这里可以多次调用
		i.function();
		i.function();

	}
}

匿名内部类的作用:

package IO_liu;
/*
 * 
 * 匿名内部类的应用场景:
 * 作为参数进行传递
*/

public class com {
	public static void main(String[] args) {
		method(new Dog());
		method(new cat());
	}
	
	public static void method(Animal a) {
		a.eat();
	}

}



package IO_liu;

public interface Animal {

	public abstract void eat();

}

package IO_liu;

public class Dog implements Animal{

	@Override
	public void eat() {
		System.out.println("狗吃骨头");
		
	}
	
}

package IO_liu;

public class cat implements Animal{

	@Override
	public void eat() {
		System.out.println("猫吃鱼");
	}

}

你可能感兴趣的:(Java)