内部类与外嵌类
内部类:
定义:在一个类中定义另一个类,这样的类就称为内部类;
// 外嵌类的声明
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("静态内部类是外嵌类的一种静态数据类型");
}
}
}
内部类能够访问外部内的一切成员变量和方法,包括私有的,而实现接口或继承类做不到。
外嵌类:
定义:包含内部类的类;
特点:
- 外嵌类的成员变量在内部类中仍然有效;
- 外嵌类中的方法可以被内部类中的方法进行调用;
- 外嵌类的类体中可以用内部类声明对象,以作为外嵌类的成员。
匿名类:
定义:
创建类对象时,除了使用父类的构造方法外还有类体,此类体就认为是一个子类除去类声明后的类体,称作匿名类。
特点:
- 可以继承父类的方法也可以重写父类的方法;
- 匿名类是在类中直接创建对象,所以一定是内部类;
- 可以访问外嵌类中的成员变量和方法;
- 不可以声明static成员变量和static方法;
- 创建对象时需要直接使用父类的构造方法;
和子类有关的匿名类:
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();
}
}
注意:类体必须要重写父类或接口中的全部方法;