内部类了解么?简单介绍下[中高]

版权声明:No Rain No Rainbow https://blog.csdn.net/xiangyuenacha/article/details/84139442

一定义:
放在一个类的内部类我们就叫内部类。

二作用
1.内部类可以很好的实现隐藏
一般的非内部类,是不允许有 private 与 protected 权限的,但内部类可以
2.内部类拥有外部类的所有元素的访问权限
3. 可以实现多重继承(重点说下这个)
三 分类
1.静态内部类:作为类的静态成员,存在于某个类的内部。 (java.util.Collections,ConcurrentHashMap)
2.成员内部类:作为类的成员,存在于某个类的内部。
3.局部内部类:存在于某个方法的内部。
4.匿名内部类:存在于某个类的内部,但是无类名的类。

参考代码: inner、Outter

/**
 * 静态内部类虽然是外部类的成员,但是在未创建外部类的对象的情况下,可以直接创建静态内部类的对象。
 * 静态内部类可以引用外部类的静态成员变量和静态方法,但不能引用外部类的普通成员。
 */
public class Outter {
	static String staticVar = "staitc var静态变量";
	String instinceVar = "普通成员变量";
	static {
		System.out.println("静态代码块执行:" + staticVar);
		System.out.println("===========================");
	}

	static void test() {
		System.out.println("外部类的静态方法执行");
	}

	static class Inner {
		static {
			// 内部类的静态代码块在外部类初始化的时候,不会被初始化
			System.out.println("静态内部类的静态代码块");
		}
		public void test2() {
			System.out.println("staticVar的值为:" + staticVar);// 直接引用外部类的静态成员变量
			test();// 直接引用外部类的静态方法
			// System.out.println(instinceVar); // 试图引用外部类的非静态成员变量,不能通过编译
			System.out.println("静态内部类的方法执行");
		}
	}

	public static void main(String[] args) {
		new Outter();
		Inner in = new Inner();// 静态内部类的对象可以直接创建,无需先创建外部类的对象
		in.test2();
	}
}
/**
 * 成员内部类可以调用外部类的所有成员,但只有在创建了外部类的对象后,才能调用外部的成员。
 * 它与一个实例绑定在了一起,不可以定义静态的属性和方法
 *
 */
public class Outter1 {
	static int a = 1;
	int b = 0;

	public static void test1() {
		System.out.println("外部类的静态方法");
	}

	public void test2() {
		System.out.println("外部类的非静态方法");
	}

	class Inner {
		// static String aa; // 不可以定义静态的属性和方法
		public void test() {
			System.out.println("在成员内部类的方法中");
			test1();// 调用外部类的静态方法
			test2();// 调用外部类的非静态方法
			System.out.println("访问外部类的静态成员变量和非静态成员变量:" + (a + b));// 访问外部类的静态成员变量和非静态成员变量
		}
	}

	public static void main(String[] args) {
		// Inner in = new Inner(); // 成员内部类的对象不能直接创建,编译会报错
		Outter1 out = new Outter1(); // 先创建外部类的对象
		Inner in = out.new Inner(); // 注意:!成员内部类的对象必须通过外部类的对象创建
		in.test(); // 调用内部类的方法
	}
}
/**
 * 局部内部类只能在方法内部中使用,一旦方法执行完毕,局部内部类就会从内存中删除。
  必须注意:如果局部内部类中要使用他所在方法中的局部变量,那么就需要将这个局部变量定义为final的。
 *
 */
public class Outter2 {
	
	int a = 10;
	
	public void test() {
		final int c = 5;
		System.out.println("执行外部类的方法");
		class Inner {
			int b = 20;
			void test1() {
				System.out.println("执行局部内部类的方法,b:" + b);
				/**
				 * 注意:如果局部内部类中要使用他所在方法中的局部变量,
				 * 那么就需要将这个局部变量定义为final的。
				 */
				System.out.println("调用方法的局部变量final,c:" + c);
			}
		}
		Inner inner = new Inner();
		inner.test1();
	}

	public static void main(String[] args) {
		Outter2 outter = new Outter2();
		outter.test();
	}
}
/**
 *   匿名内部类的定义与对象的创建合并在一起,匿名内部类一般通过如下形式定义,并且在定义的同时进行对象的实例化。
     new 类或者接口的名字(){
        //匿名内部类的主体,大括号中是匿名内部类的主体,这个主体就是类或者接口的实现,
         * 如果是类,那么匿名内部类是该类的子类,
         * 如果是接口,匿名内部类需要完成接口的实现。
     }
 *
 */
public class Outter3 {
	public static void main(String[] args) {
		Person person = new Person();
		person.show(new Message() {
			public void show() {
				System.out.println("在匿名内部类中");
			}
		});

		// 比较经典的创建线程的一种方式
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println("new Thread");// 输出:new Thread 2
			}
		});
		t2.start();

	}
}

class Person {
	public void show(Message message) {
		message.show();
	}
}

class Message {
	public void show() {
		System.out.println("在Message类中");
	}
}

// 测试通过内部类实现多继承等
class Example1 {
	public String name() {
		return "Example1 name()";
	}
}

class Example2 {
	public int age() {
		return 1;
	}
}

class Example3 {
	public int age() {
		return 1;
	}
}

class InnerExtendExample {
	 private String id = "id";
	 private static String name = "name";
	 //一般的非内部类,是不允许有 private 与protected权限的,
	 // 但内部类可以,所以我们能通过内部类来隐藏我们的信息。
	 private class test1 extends Example1 {
		public String name() {
			System.out.println("调用外部类的成员变量,id:" + id);
			System.out.println("调用外部类的静态变量,name:" + name);
			return super.name();
		}
	}

	private class test2 extends Example2 {
		public int age() {
			return super.age();
		}
	}

	public String name() {
		return new test1().name();
	}

	public int age() {
		return new test2().age();
	}

	public static void main(String args[]) {
		InnerExtendExample ie = new InnerExtendExample();
		System.out.println("获得父类Example1的方法,姓名:" + ie.name() );
		System.out.println("获得父类Example2的方法,年龄:" + ie.age());
	}
	
}

猜你喜欢

转载自blog.csdn.net/xiangyuenacha/article/details/84139442
今日推荐