JAVASE基础模块十二(成员内部类 局部内部类 匿名内部类)
内部类
-
内部类 将类A定义到类B中 那么这个类称之为内部类 类B称之为外部类
- 根据内部类定义的位置分为 成员内部类和局部内部类
- 成员内部类:就是把内部类 定义到外部类的成员位置 类中方法外
- 局部内部类:就是把内部类 定义到外部类的局部位置 方法内
- 根据内部类定义的位置分为 成员内部类和局部内部类
-
特点
-
内部类可以直接访问外部类的成员 包括私有成员
-
外部类不能直接访问内部类的成员 要访问必须创建内部类的对象 通过内部类对象来访问
public class Zz { public static void main(String[] args) { Doctor.HuShi hushi = new Doctor().new HuShi(); hushi.neiShow(); } } class Doctor { int num = 33; private int zw = 77; public void waiShow() { System.out.println("外部外部"); } public void heHa() { HuShi huShi = new HuShi(); System.out.println(huShi.nei); } class HuShi { int nei = 3322; public void neiShow() { System.out.println("内部内部内部"); System.out.println(num); System.out.println(nei); System.out.println(zw); } } } 运行结果: 内部内部内部 33 3322 77 进程已结束,退出代码0
-
内部类可以用private来修饰 私有的内部类 外界无法创建其对象
public class Testx { public static void main(String[] args) { Wai wai = new Wai(); wai.heHa(); } } class Wai { public void heHa() { Nei nei = new Nei(); nei.neiShow(); } private class Nei { public void neiShow() { System.out.println("内部内部内部"); } } } 运行结果: 内部内部内部 进程已结束,退出代码0
-
内部类可以用static修饰 静态内部类只能访问外部类的静态成员
public class Z5 { public static void main(String[] args) { Waix.Neix vv=new Waix.Neix(); vv.neiShow(); } } class Waix { static class Neix { public void neiShow() { System.out.println("内部内部内部"); } } } 运行结果: 内部内部内部 进程已结束,退出代码0
-
-
普通格式: 外部类名.内部类名 对象名 = 外部类对象.内部类对象;
-
成员内部类的修饰符:
- private 为了保证数据的安全性
- static 为了方便访问数据
- 注意事项:
- 静态内部类访问的外部类数据必须用静态修饰
- 成员方法可以是静态的也可以是非静态的
-
成员内部类被静态修饰后的访问方式是:
- 格式: 外部类名.内部类名 对象名 = new 外部类名.内部类名();
-
内部类的class文件名为 wai$nei.class
-
局部内部类
- 局部内部类访问外部类的局部变量 外部类的这个局部变量必须为一个常量
- 特点
- 可以直接访问外部类的成员
- 可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
- 局部内部类访问局部变量必须用final修饰
- 因为局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失,还要使用那个变量。为了让数据还能继续被使用,就用fianl修饰,这样,在堆内存里面存储的其实是一个常量 JDK1.8之后,final会默认加上
匿名内部类
-
匿名内部类:它是局部内部类的一中简写形式
-
语法格式:new 接口名/类名(){重写方法}
-
匿名内部类的本质:
-
匿名内部类本质上是一个对象
-
是实现了该接口或者是继承了该抽象类的子类对象
-
-
同一个匿名内部类 调用两个方法
interface Bao { void show(); void show1(); } public class Han { public static void main(String[] args) { Bao c = new Bao() { @Override public void show() { System.out.println("重写九田家"); } public void show1() { System.out.println("重写汉堡王"); } }; c.show(); c.show1(); } } 运行结果: 重写九田家 重写汉堡王 进程已结束,退出代码0
-
匿名类举例
public class NiM {
public static void main(String[] args) {
new ChouXiang(){
@Override
public void show() {
System.out.println("重写汉堡王");
}
}.show();
}
}
abstract class ChouXiang{
public abstract void show();
}
重写汉堡王
进程已结束,退出代码0
public class Han {
public static void main(String[] args) {
new Bao(){
@Override
public void show() {
System.out.println("重写九田家");
}
}.show();
}
}
interface Bao{
void show();
}
重写九田家
进程已结束,退出代码0
5. 对于一个普通的类 我们也可以使用匿名内部类 创建该类的子类对象
- 匿名对象的参数传递与作为返回值的返回
interface Bao {
void aa();
}
abstract class Animal {
public abstract void eat();
}
abstract class Dog {
public abstract void eatd();
}
public class Han {
public static void main(String[] args) {
set(new Bao() {
@Override
public void aa() {
System.out.println("重写一堆好吃的"); }});
set(new Animal() {
@Override
public void eat() { System.out.println("爱吃鱼");}});
}
public static void set(Bao b) {
b.aa();
}
public static void set(Animal bb) {
bb.eat();
}
}
public static Dog set(Dog bb) {
return new Dog() {
@Override
public void eatd() {
System.out.println("爱吃骨头");
}
};
}
运行结果:
重写一堆好吃的
爱吃鱼
进程已结束,退出代码0