java基础之内部类

内部类概述

内部类的概述
在这里插入图片描述
内部类的具体表现
在这里插入图片描述
特点:
1编译后会生成字节码文件, 也就是里面的inner在文件管理的bin目录下会生成后缀名为class的文件
即我们创建了内部类后bin目录下,就会在目录下会生成Outer.class文件和Outer$Inner.class两个文件
2内部类可以直接访问外部类的用private的成员,而不会破坏封装属性
(就是像下面的这个内部类里的方法可以访问外部类的私有属性)

class Outer(){
	private String name;
	class Inner(){
	public void show(){
	system.out.println(name);

3.可为外部类提供必要的功能组件
(就是外部类可以提供一些东西供内部类使用)

成员内部类

概念:在类的内部定义,与实列方法,实列变量同级别
外部类的一个实列部分,创建内部类时,必须依赖外部类

public class Outer(){
  private String name;
  private 

然后想要对内部类进行调用
我们都知道,想要调用类中的方法,就需要先创建一个类对象

ackage day01;

//外部类
public class Outer {
    private String name;
    private int age=20;
    //内部类
    class Inner{
          //这里的内部类看可以用修饰符修饰,即可用public和private来修饰
         private String address="北京";
         private  String photo="111";
         //内部类里定义一个方法
          public void show(){
              //打印外部类属性
              System.out.println(name);
              System.out.println(age);
              //打印内部类的属性
              System.out.println(address);
              System.out.println(photo);;
          }
     }
}

图1是进行对外部类创建对象方法的操作,最后的结果将会调用内部类的方法
下面图2是在新类中进行调用前面内部类的操作

package day01;
public class test {
    public static void main(String[] args) {
        //如果现在想调用内部类中的方法,那么就需要执行下面操作
        //因为我们知道如果想要调用另外一个类中的方法,则需要创建对象来调用
        //方法1,创建外部类对象
      Outer outer=new Outer();
        Outer.Inner inner =outer.new Inner();
  //注意:就是这里的左边只能做成 外部类.内部类这种格式就相当于是内部类了
        System.out.println("------------");*/
      //方法2,调用内部类方法
        Outer.Inner inner=new Outer().new Inner();
            inner.show();
        }
    }

注意::创建内部类对象的时候,要先创建外部类对象,然后用外部类对象名+点+new+内部类名
也就是内部类对象=
外部类.内部类类名 内部类对象名=外部类对象名 .new 内部类类名
——————————————————
注意:这样两行代码比较麻烦,我们可以节省为一行代码
即: 外部类.内部类类名 内部类对象名=new 外部类类名.new 内部类类名()
(直接缩写成一句话,简单多了,可能逻辑上不如上面的两行代码,先new外部类对象,在new内部类对象这样直接省了关于构建外部类对象名的那一步了)

特点4,关于内部类的优先级访问,当外部类和内部类属性重名(也就是图中都定义相同的比如 private String name)的时候,会优先访问内部类属性
但是如果真的想要访问外部类的属性,不要内部类,那么可以用this关键字指向外部类
具体操作:
外部类.this.属性名
相反内部类就不用这样操作了,因为本类内部类的优先级就比外部类要高
在这里插入图片描述
注意:上面图中,如果在内部类和外部类中都定义同一个成员属性 String name 字段,但是值不同,这时候,我们如果调用方法中的name值,则只能调用内部类中的name;如果我们想要不调用内部类的而调用外部类中的name,那么就可以使用this关键字
用法(外部类.this.name)就可以不调用内部类中的李四,而调用外部类中的张三。
特点5,成员内部类中是不能定义静态成员的,也就是说内部类中如果这样定义式会报错的
在这里插入图片描述
特点6,成员内部类中可以定义静态常量,就是内部类中可以用final来修饰字段,但是如果把final删了,那么就会报错
在这里插入图片描述

静态内部类(static)

概念:不依赖外部类对象,可直接
内部类添加static静态关键字修饰,那么内部类的级别就等同于外部类了
也就是外部类怎么操作,静态内部类也享受同样的待遇
那么既然级别都相同了那为什么还要定义个静态内部类呢?
(答:是因为静态内部类中需要定义些功能来供外部类使用)

//外部类
public class Outer {
    private String name;
    private int age=20;
    //静态内部类
    //注意:此时Inner的等级和Outer是相同的
    
    static class Inner{
     private String address="北京";
     private  String photo="111";
     //注意:现在是静态内部类了,那么就可以添加静态成员
     private static int num=10;
     //1,下面是在内部类中创建一个show方法,然后通过show方法来访问外部类属性
     public void show()
     //因为内部类和外部类都已经处于同级的了,所以访问的话,直接是通过创建个对象,然后通过对象来访问
     Outer outer=new Outer();
     system.out.println(outer.name);
     system.out println(outer.age);
     //2.下面是访问静态内部类中的private属性
     //可以直接通过调用属性来访问
     system.out.println(address);
     system.out.println(photo);
     //3.下面是访问静态内部类中的静态属性
     //因为我们在前面就学习到了,访问静态属性,直接是(类名.属性)调用
     system.out println(Inner.num);
    }
    }

然后我们通过新建一个测试类来测试一下方法的结果

package day01;
public class test {
    public static void main(String[] args) {
    //注意下面的语句,创建对象是  类名()
    //然后下面的Outer.Inner()是包含关系,实际表示的是Inner类的创建对象
    Outer.Inner inner=new Outer.Inner();
    //调用方法
    inner.show();
    }
    }

局部内部类

概念:定义在外部类的方法当中,作用范围和创建对象范围仅仅局限在当前方法

public class Outer(){
  private String name="刘德华";
  private int age=60;
  public void show(){
  //在外部类的方法中,是可以直接访问定义的私有属性的,列如下面
  
  private address="深圳";//这是局部属性,因为addresss只有在show这个方法中才能使用
  	//开始定义一个局部类,也就是在类中的方法中在定义一个新类,简称局部类,如下面的
  	class Inner(){
  	  private phone="123544658";
  	  private sex="男";
  	//然后在局部内中添加一个方法
  	public void show2(){
  	//访问外部类属性
  	system.out.println(Outer.this.name);
  	system.out.println(Outer.this.age);
  	//访问局部类属性
  	system.out.println(phone);
  	system.out.println(sex);
  	}
  	}
  	}
  	}

然后重新定义个test类来进行测设

package day01;
public class test {
    public static void main(String[] args) {
 //因为这里定义的是局部类,所以我们要进行调用测试的话
 //需要先创建外部类对象,因为局部类在外部类中,所以先创建外部类对象
    Outer outer=new Outer();
    outer.show();
    }
    }
    

注意如果按照上面图片的测试类中的方式来进行调用,会出现错误,因为上面的调用,是创建外部类对象,然后调用show方法的时候,它定义了一个局部变量,然会下面定义了个类,但是这个类却并未使用,也就是并未参与关于的show方法的运算,则最后输出的效果就是啥都没有
所以我们想要使用局部类的东西,就要创建局部类对象,然后局部类调用方法

public class Outer(){
  private String name="刘德华";
  private int age=60;
  public void show(){
  //在外部类的方法中,是可以直接访问定义的私有属性的,列如下面
  
  private address="深圳";//这是局部属性,因为addresss只有在show这个方法中才能使用
  	//开始定义一个局部内部类,也就是在类中的方法中在定义一个新类,简称局部内部类,如下面的
  	class Inner(){
  	  private phone="123544658";
  	  private sex="男";
  	//然后在局部内中添加一个方法
  	public void show2(){
  	//访问外部类属性
  	system.out.println(Outer.this.name);
  	system.out.println(Outer.this.age);
  	//访问内部类属性
  	system.out.println(phone);
  	system.out.println(sex);
  	//访问局部变量
  	system.out.println(address);
  	//值得注意的就是,在java的jdk版本1.8之后
  	//如果要访问局部变量,那么就相当于默认添加了个final修饰符
  	//意思就是我们不能在对访问的局部变量进行修改初始值
  	//在局部内部类不调用局部变量下 就是普通的变量 可以修改初始值
  	}
  	}
  	//即在这里创建局部类的对象,并调用方法
  	Inner inner=new Inner();
  	inner.show2();
  	}
  	}

最后,测试的结果就是会输出局部类里面的东西
注意:为什么我们只需要创建一个局部类的对象,然后局部类的对象只是调用show2方法,看起来Outer外部类和那个外部类中的方法,点参与感没有

是因为局部类的规则,局部类是定义在外部类的里面的子类 (类似于儿子的儿子的形状的东西)

匿名内部类

概念:和局部内部类相同,不过没有类名
常见用处:继承父类和实现接口

一个接口/类的方法的某个实现方式在程序中只会执行一次,但为了使用它,我们需要创建它的实现类/子类去实现/重写。此时可以使用匿名内部类的方式,可以无需创建新的类,减少代码冗余。

下面详细说明一下

假设当前有一个接口,接口中只有一个方法

public interface Interface01 {
    void show();
}

为了使用该接口的show方法,我们需要去创建一个实现类,同时书写show方法的具体实现方式

public class Interface01Impl implements Interface01{
    @Override
    public void show() {
        System.out.println("I'm a impl class...");
    }
}

如果实现类Interface01Impl全程只使用一次,那么为了这一次的使用去创建一个类,未免太过麻烦。我们需要一个方式来帮助我们摆脱这个困境。匿名内部类则可以很好的解决这个问题。

public static void main(String[] args) {
    Interface01 interface01 = new Interface01() {
        @Override
        public void show() {
            System.out.println("这里使用了匿名内部类");
        }
    };
    //调用接口方法
    interface01.show();
}

最后控制台结果显示,这里使用了匿名内部类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值