内部类与外嵌类

内部类:

        定义:在一个类中定义另一个类,这样的类就称为内部类;

//  外嵌类的声明
public class internalExa {

	class internal {
		//	内部类internal的声明
		void speak() {
			System.out.println("\t内部类不能构建静态内部变量");
			System.out.println("\t非static内部类可以操作外嵌类中的static变量和实例变量");
		}
	}
}

        特点

        1. 内部类的类体中,不可声明类变量和类方法;

        2. 非内部类不可以是static类;

        3. 非static内部类可以操作外嵌类中的static变量和实例变量;

        4. static内部类不能操作外嵌类的实例成员变量;

        5. 内部类仅供它的外嵌类使用,其他类不可以用某个类的内部类声明对象;

public class Example7_test {
	public static void main(String[] args) {
		Abc.ABC abc = new Abc.ABC(){
			void speak2() {
				System.out.println("利用此方式构建的成员对象,要求对应内部类需为封闭类,如果不是静态内部类,这此代码非法!");
			}

			@Override
			void speak() {
				speak2();
			}
		};
		abc.speak();
	}
}

class Abc{
	static class ABC{
		void speak(){
			System.out.println("静态内部类是外嵌类的一种静态数据类型");
		}
	}
}

内部类能够访问外部内的一切成员变量和方法,包括私有的,而实现接口或继承类做不到。

外嵌类:

        定义:包含内部类的类;

        特点

  1. 外嵌类的成员变量在内部类中仍然有效;
  2. 外嵌类中的方法可以被内部类中的方法进行调用;
  3. 外嵌类的类体中可以用内部类声明对象,以作为外嵌类的成员。

匿名类:

        定义:

        创建类对象时,除了使用父类的构造方法外还有类体,此类体就认为是一个子类除去类声明后的类体,称作匿名类。

        特点:

  1. 可以继承父类的方法也可以重写父类的方法;
  2. 匿名类是在类中直接创建对象,所以一定是内部类;
  3. 可以访问外嵌类中的成员变量和方法;
  4. 不可以声明static成员变量和static方法;
  5. 创建对象时需要直接使用父类的构造方法;

        和子类有关的匿名类:

public class Exa7_2 {
	public static void main(String[] args) {
		//  创建类对象
		showLan lan = new showLan();    
		//  传递子类对象
		lan.showMess(new enLanguage());
		//  传递匿名抽象父类对象,同时进行方法构造和重写并调用父类成员变量
		lan.showMess(new language() {
			@Override
			public void outLan() {
				outCh();
			}
			void outCh(){
				for (char a3 = 'α'; a3 <= 'π'; a3++) {
					System.out.printf("%3c",a3);
				}
				System.out.println("\n匿名类调用父类的变量:" + a1);
			}
		});
	}
}

abstract class language {
	public abstract void outLan();
	public int a1 = 12;
	char[] a2 = {'a','b','1','Ω'};
}

class enLanguage extends language{
	@Override
	public void outLan() {
		for (char a : a2) {
			System.out.printf("%3c",a);
		}
	}
}

class showLan{
	void showMess(language lan){
		lan.outLan();
	}
}

        和接口有关的匿名类:

public class Example7_3 {
	public static void main(String[] args) {
		helloMachine hellom = new helloMachine();
		hellom.turnOn(new speak() {
			@Override
			public void speakHello() {
				System.out.println("传递接口匿名类————————你好!");
			}
		});

		hellom.turnOn(() -> System.out.println("接口单个抽象类方法时,对匿名类的调用时,可以用lambda写法:() -> " +
				"System.out.println(\"匿名 new speak() 可以用 Lambda 替换\")"));
		
        hellom.turnOn(new speak() {
			@Override
			public void speakHello() {
				System.out.println("匿名 new speak() 可以用 Lambda 替换");
			}
		});
	}
}

interface speak {
	void speakHello();
}

class helloMachine {
	public void turnOn(speak speak) {
		speak.speakHello();
	}
}

注意:类体必须要重写父类或接口中的全部方法;