内部类详解

内部类访问特点

* a:内部类可以直接访问外部类的成员,包括私有。

* b:外部类要访问内部类的成员,必须创建对象。

外部类名.内部类名 对象名 外部类对象.内部类对象;

总结只是把内部类看成一个对应位置 对应访问权限的变量就好了

demo1

class Demo1_InnerClass {
	public static void main(String[] args) {
		//Inner i = new Inner();
		//i.method();
//外部类名.内部类名 对象名=外部类对象.内部类对象
 Outer.Inner oi = new Outer().new Inner();	
		oi.method();

	}
}

class Outer {
	private int num = 10;
	class Inner {
		public void method() {
			System.out.println(num);
		}
	}
}
demo2:私有内部类

class Demo2_InnerClass {
	public static void main(String[] args) {
		//Outer.Inner oi = new Outer().new Inner();
		//oi.method();

		Outer o = new Outer();
		o.print();
	}
}

class Outer {
	private int num = 10;
	private class Inner {
		public void method() {
			System.out.println(num);
		}
	}

	public void print() {//使用一个方法区调用
		Inner i = new Inner();
		i.method();
	}
}
静态内部类

格式:外部类名.内部类名 对象名 = 外部类名.内部类对象 习惯把new写在前面  如:

class Demo1_InnerClass {
	public static void main(String[] args) {
		Outer.Inner oi = new Outer.Inner();
		oi.method();

		Outer.Inner2.print();
	}
}

class Outer {
	static class Inner {
		public void method() {
			System.out.println("method");
		}
	}

	static class Inner2 {
		public static void print() {
			System.out.println("print");
		}
	}
}
局部内部类访问局部变量的问题

局部内部类是在方法中定义的类
* 局部内部类访问局部变量必须用final修饰
    * 局部内部类在访问他所在方法中的局部变量必须用final修饰,为什么?
        因为当调用这个方法时,局部变量如果没有用final修饰,他的生命周期和方法的生命周期是一样的,
        当方法弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有马上消失想用这个局部变量,
        就没有了,如果用final修饰会在类加载的时候进入常量池,
        即使方法弹栈,常量池的常量还在,也可以继续使用

eg:

class Demo1_InnerClass {
	public static void main(String[] args) {
		Outer o = new Outer();
		o.method();
	}
}

class Outer {
	public void method() {
		final int num = 10;
		class Inner {
			public void print() {
				System.out.println(num);
			}
		}
		//方法内部含有类,所用域为方法内部
		Inner i = new Inner();
		i.print();
	}
}
匿名内部类:

本质是一个继承了该类或者实现了该接口的子类匿名对象。

1、存在一个类或者接口
    * 这里的类可以是具体类也可以是抽象类。

2、匿名内部类必须要和某各类某个接口产生关系。

3、一般是应用是在某些 方法中充当参数。

4、匿名内部类适用于实现一个方法。

5、格式:

new 类名或者接口名(){
            重写方法;
        }

如:

new 类名(){
            重写方法;
        }

等价于一个子类继承了某个抽象类或者具体类并且声称了对象

new 接口名(){
            重写方法;
        }

等价于实现了一个接口的类的对象。

demo :

class Demo1_NoNameInnerClass {
	public static void main(String[] args) {
		Outer o = new Outer();
		o.method();
	}
}

interface Inter {
	public void print();
}

class Outer {
	public void method(){
		/**
		*如果inter为一个抽象类或者父类 那个下面
                *new Inter() {				
		*	public void print() {			
		*		System.out.println("print");
		*	}
		*}这一块代表了继承inter的一个子类对象。如果是一个接口表示的是实现了该接口的一个对象
		**/
		new Inter() {				
			public void print() {			
				System.out.println("print");
			}
		}.print();//.print()表示实现了inter接口产生了一个对象,并且调用了该对象的print方法
	}
}
在正常的开发中匿名内部一般作为方法的参数传入进去

class Test1_NoNameInnerClass {
	public static void main(String[] args) {
		PersonDemo pd = new PersonDemo ();
		//pd.method(new Student());
		pd.method(new Person() {//匿名内部类当做参数传递(本质把匿名内部类看做一个对象,这个对象实现或继承了Person)
			public void show() {
				System.out.println("show");
			}
		});
	}
}
//接口和抽象类都可以
abstract class Person {
	public abstract void show();
}

class PersonDemo {
	public void method(Person p) {
		p.show();
	}
}

class Student extends Person {
	public void show() {
		System.out.println("show");
	}
}



你可能感兴趣的:(内部类详解)