内部类

本文详细介绍了Java内部类的概念、分类及应用场景,并重点讲述了成员内部类、局部内部类、匿名内部类的特点与使用方法。

内部类

内部类概述:

把类定义在其他类的内部,这个类就被称为内部类。


举例:在类A中定义了一个类B,类B就是内部类。


内部的访问特点:

A:内部类可以直接访问外部类的成员,包括私有。

B:外部类要访问内部类的成员,必须创建对象。

class Outer {
 private int num = 10;
 class Inner {
  public void show() 
{
   System.out.println(num);
  }
 }
 public void method() 
{
  //找不到符号
  //show();
  Inner i = new Inner();
  i.show();
 }
}

class InnerClassDemo {
 public static void main(String[] args) {
     
 }
}

内部类位置

局部位置:在局部位置定义的类,被称为局部内部类。(如成员方法中)


成员位置:在成员位置定义的类,被称为成员内部类。


内部类的class文件的命名是:外部类$内部类.class


内部类可以直接访问外部类的所有成员。

当成员内部类和外部类存在相同名的成员时,默认情况下访问的是成员内部类的成员。


如果内部类出现了和外部类同名的成员时,要访问外部类成员,则要使用以下格式:

  • 外部类名.this.成员变量名;

  • 外部类名.this.成员方法(参数列表);

class Outer {
 private int num = 10;

 //成员位置
 /*
 class Inner {
 }
 */
    
//成员方法
 public void method() {
  //局部位置
  class Inner 
{
  }
 }
}

class InnerClassDemo2 {
 public static void main(String[] args) 
{
 }
}

成员内部类:

如何直接访问内部类的成员。

外部类名.内部类名 对象名 = 外部类对象.内部类对象;

class Outer {
 private int num = 10;
 class Inner {
  public void show() 
{
   System.out.println(num);
  }
 }
}

class InnerClassDemo3 {
 public static void main(String[] args) 
{
  //需求:我要访问Inner类的show()方法
  //Inner i = new Inner();
  //i.show();
  //格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;
  Outer.Inner oi = new Outer().new Inner();
  oi.show();
 }
}

成员内部类的修饰符:

private 为了保证数据的安全性

如果成员内部类使用private修饰,其他类无法再创建该成员内部类的对象,只能在外部类中提供一个方法创建成员内部类对象了。

成员内部类不能定义静态成员,如果要定义,则该内部类也必须使用static修饰,也就是静态内部类了

static 为了方便访问数据 注意:静态内部类访问的外部类数据必须用静态修饰。

 案例:我有一个人(人有身体,身体内有心脏。)
  class Body {
   private class Heart {
    public void operator() 
{
     System.out.println("心脏");
    }
   }
   public void method() {
    if(如果你是外科医生) {
     Heart h = new Heart();
     h.operator();
    }
   }
  }
  //按照我们刚才的讲解,来使用一下
   Body.Heart bh = new Body().new Heart();
   bh.operator();
  //加了private后,就不能被访问了,那么,怎么玩呢?
  Body b =  new Body();

  b.method();
*/
class Outer {
 private int num = 10;
 private static int num2 = 100;
 //内部类用静态修饰是因为内部类可以看出是外部类的成员
    
 public static class Inner 
{
  public void show() 
{
   //System.out.println(num);
   System.out.println(num2);
  }
     
     
class InnerClassDemo4 {
 public static void main(String[] args) {
  //使用内部类
  // 限定的新静态类
  //Outer.Inner oi = new Outer().new Inner();
  //oi.show();
  //oi.show2();
  
  //成员内部类被静态修饰后的访问方式是:
  //格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
  Outer.Inner oi = new Outer.Inner();
  oi.show();
  oi.show2();
  
  //show2()的另一种调用方式
  Outer.Inner.show2();
 }
}


局部内部类

A:可以直接访问外部类的成员

B:在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能

局部内部类访问局部变量的注意事项?

A:局部内部类访问局部变量必须用final修饰

B:为什么呢?

局部变量是随着方法的调用而调用,随着调用完毕而消失。

而堆内存的内容并不会立即消失。所以,我们加final修饰。

加入final修饰后,这个变量就成了常量。既然是常量。你消失了。 我在内存中存储的是数据20,所以,我还是有数据在使用。

class Outer {
 private int num  = 10;
 
 public void method() {
  //int num2 = 20;
  //final int num2 = 20;
  class Inner {
   public void show() {
    System.out.println(num);
    //从内部类中访问本地变量num2; 需要被声明为最终类型
    System.out.println(num2);//20
   }
  }
  
  //System.out.println(num2);
  
  Inner i = new Inner();
  i.show();
 }
}

class InnerClassDemo5 {
 public static void main(String[] args) {
  Outer o = new Outer();
  o.method();
 }
}

匿名内部类

就是内部类的简化写法。

匿名内部类是局部内部类的一种。

前提条件:存在一个类或者接口

这里的类可以是具体类也可以是抽象类。


格式:

new 类名或者接口名(){

   重写方法;
    
  }

本质是什么呢?
是一个继承了该类或者实现了该接口的子类匿名对象。

匿名内部类能定义新的成员方法和成员变量吗?

可以,但不能使用static修饰,但无法显式的通过“实例名.方法名(参数)”的形式调用,

因为使用new创建的是“上转型对象”(即父类声明指向子类对象)。

所以一般不会为匿名内部类添加成员变量和成员方法。

匿名内部类能定义构造方法吗?

不能定义构造方法,匿名内部类没有类名,无法定义构造方法。

interface Inter {
 public abstract void show();
 public abstract void show2();
}

class Outer {
 public void method() {
  //一个方法的时候
  /*
  new Inter() {
   public void show() {
    System.out.println("show");
   }
  }.show();
  */
  
  //二个方法的时候
  /*
  new Inter() {
   public void show() {
    System.out.println("show");
   }
   
   public void show2() {
    System.out.println("show2");
   }
  }.show();
  
  new Inter() {
   public void show() {
    System.out.println("show");
   }
   
   public void show2() {
    System.out.println("show2");
   }
  }.show2();
  */
  
  //如果我是很多个方法,就很麻烦了
  //那么,我们有没有改进的方案呢?
  Inter i = new Inter() { //多态
   public void show() {
    System.out.println("show");
   }
   
   public void show2() {
    System.out.println("show2");
   }
  };
  
  i.show();
  i.show2();
 }
}

class InnerClassDemo6 {
 public static void main(String[] args) {
  Outer o = new Outer();
  o.method();
 }
}

请说出什么是内部类.请说出什么时候使用内部类.请说出内部类的分类.

1.在A类内部中定义另外一个B类,B类则称为内部类,A类则称为外部类。
2.内部类的使用场景
    a.当某个类除了它的外部类,不再被其他的类使用时。
    b.当描述事物A时,发现该A事物内部还具备另一类事物B,而且B事物需要用到A事物的一些成员数据,那么此时事物B就可以使用内部类来描述。
3.内部类分为成员内部类与局部内部类
    a.成员内部类,定义在外部类中的成员位置。与类中的成员变量相似,可通过外部类对象进行访问
    b.局部内部类: 定义在方法中. 与局部变量类似,只能在本方法中使用.

请说出成员内部类定义位置.请说出成员内部类定义格式.请说出如何通过成员内部类创建对象.

    1.定义位置: 成员内部类,定义在外部类中的成员位置。与类中的成员变量相似,可通过外部类对象进行访问
    2.定义格式:
        class 外部类 { 
            修饰符 class 内部类 {
                //其他代码
            }
        }
    3.创建对象(访问方式): 
        外部类名.内部类名 变量名 = new 外部类名().new 内部类名();

请说出匿名内部类的两个含义分别是什么?

  1. ​临时定义某一指定类型的子类(实现类)
  2. 定义后即刻创建刚刚定义的这个子类(实现类)的对象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值