内部类和匿名内部类
- 内部类
- 匿名内部类
- 内部接口
1. 内部类
- 概述:定义在类中的类称作内部类
- 内部类访问特点
- 内部类可以直接访问外部类的成员,包括私有。
- 外部类要访问内部类的成员,必须创建对象。
- 分类:
- 成员内部类:将内部类定义到外部类的成员位置(类中方法外)
- 局部内部类:将内部类定义到 外部类的局部位置(方法中)
class A{
class B {
//成员内部类
}
public void waiShow(){
class C{
//局部内部类
}
}
}
- 成员内部类访问特点:
- 内部类可以直接访问外部类的成员,包括私有的属性和方法
- 外部类不能直接访问内部类的成员,需要创建内部类的对象(创建类的对象)
- 在测试类中直接访问内部类的成员。
格式: 外部类名.内部类名 对象名 =new 外部类对象.new 内部类对象; - 未用staitc修饰的内部类的创建对象的语法
外部类名.内部类名 对象名 =new 外部类对象.new 内部类对象;
static 修饰内部类,那么创建内部类对象的语法:(静态内部类,只能访问外部类的静态成员)
外部类名.内部类名 对象名 =new 外部类对象.内部类对象;
Ps:内部类可以用private修饰,但是私有的内部类,外界(Test类)不能创建其对象了
使用时只能通过外部类(内部类上一级)new内部类然后调用内部类中的成员和方法
public classTest {
public static void main(String[] args) {
//调用内部类的方法,要创建内部类的对象
Outer.Inner inner=new Outer().new Inner();
inner.innnerShow();
//外部类想要调用内部类的成员,得创建内部类对象
}
}
public class Outer {
int num=10;
private int a=20;
class Inner{ //成员内部类
int aa=1;
public void innnerShow(){
System.out.println("内部类的show方法");
System.out.println(num);
System.out.println(a);
outerShow(); //调用外部类方法
outerTest(); //调用外部类私有方法
}
}
public void outerShow(){
System.out.println("这是外部类的方法");
}
private void outerTest(){
System.out.println("外部类的私有方法");
}
public void test(){
//外部类想要访问内部类的成员,得创建内部类的对象
Inner inner = new Inner();
System.out.println(inner.aa);
}
}
- 局部内部类访问特点:
- 可以直接访问外部类的成员
- 局部内部类,在外界没有直接创建其对象语法
- 可以创建内部类对象(在外部类),通过对象调用内部类方法,来使用局部内部类功能
- 局部内部类访问局部变量必须用final修饰
因为局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失,还要使用那个变量。
为了让数据还能继续被使用,就用fianl修饰,使其变成一个常量
public class MyTest {
public static void main(String[] args) {
Outer outer = new Outer(); //创建外部类对象
outer.waiShow();
}
}
class Outer{
int num=100;
private int a=10;
public void waiShow(){
class Inner{ //局部内部类
int aa=2;
public void neiShow(){
System.out.println("内部类的show方法");
System.out.println(num); //可直接访问外部类成员
System.out.println(a); //可直接访问外部类私有成员
hehe(); //可直接访问外部类方法
}
}
Inner inner = new Inner(); //创建局部内部类对象
inner.neiShow(); //调用局部内部类方法
}
private void hehe(){
}
public void waiTest(){
}
}
2. 匿名内部类
- 概述:
- 匿名内部类: 就是局部内部类的简化写法
- 本质上是一个该类或实现了接口的子类对象
- 前提: 存在一个类或者接口;这里的类可以是具体类也可以是抽象类
- 格式:
new 类名或者接口名(){
重写方法;
} ;
public class MyTest2 {
public static void main(String[] args) {
new Animal(){ //匿名内部类
@Override
public void eat() {
System.out.println("吃鸡");
}
}.eat(); //调用该对象的eat方法
new MyInterface(){ //匿名内部类
@Override
public void show() {
System.out.println("hehhehe");
}
}.show(); //调用该对象的show方法
}
}
abstract class Animal{
public abstract void eat();
}
interface MyInterface{
void show();
}
- this关键字的使用
interface Inter {
public static final int a = 23;
}
public class Test {
public static void main(String[] args) {
new Inter() {
int a=50;
public void show() {
// 这个this表示的是匿名内部类的这个对象
System.out.println(this.a); //匿名内部类(对象)的a值
System.out.println(Inter.a); //Inter 接口的a值
}
}.show();
}
}
3. 内部接口
就是在类中定义一个接口
public class MyTest {
public static void main(String[] args) {
//方式1
new Outer().outerShow(); //直接访问outer类中的outershow方法
//方式2
Outer.MyInterface myInterface = new Outer.MyInterface() { //创建内部接口的对象(匿名内部类)
@Override
public void show() {
System.out.println("重写show方法");
}
};
myInterface.show();
}
}
class Outer{
//定义成员内部接口
interface MyInterface{
void show();
}
public void outerShow(){
new MyInterface(){
@Override
public void show() {
System.out.println("匿名内部类的show方法");
}
}.show();
}
}