java 内部类

java 内部类,第1张

内部类

内部类:

  • 概念:在一个类的内部再定义一个完整类的类。

  • 特点:1、编译之后可生成独立的字节码文件。

    ​ 2、内部类可以直接访问外部类的私有成员,而不破坏封装。
    ​ 3、可以为外部提供封装的属性

class Outer{
  private String name;
  class Header{
    public void show(){
    System.out.println(name);
    }
  }
}

成员内部类
  1. 在类的内部定义,与实例变量、实例方法同级别的类。
  2. 外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象。 //必须创建外部的类,才能再创建内部的类
public class Outer{
  private String name="张三";
  private int age = 20;
  class Inner{
    private String address="北京";
    private String phone="110";
    
    public void show(){
      //打印外部类的属性
      System.out.println(name);
      System.out.println(age);
      //打印内部类中的属性
      System.out.println(address);
      System.out.println(phone);
    }
  }
}


public class TestOuter{
  public static void main(String[] agrs){
		//1创建外部类对象
    Outer outer=new Outer();
    //2创建内部类对象
    Inner inner = Outer.new Inner();
    
    inner.show();
    
    
    //可以合一步
    inner inner=new Outer().new Inner();
    inner.show();
  }
}
  1. 当外部类、内部类存在重名属性时,会有限访问内部类属性。

    //如果想访问外部的实例变量
    Outer.this.name;
    

    自编案例:

    class Outer {
        private String name = "你好";
    
        class Inner {
            int num = 10;
    
            public void show() {
                int num = 20;
                System.out.println(num);//输出20。注:定义了局部变量,则为局部变量值;如果没有定义,则等同于this.num;********这个务必搞清楚!!!!!容易出错,很多大佬都直接省略this调用实例变量
                System.out.println(this.num);//输出10
                System.out.println(Inner.this.num);//输出10
                System.out.println(Outer.this.name);//输出你好
            }
        }
    
        public static void main(String[] args) {
            new Outer().new inner().show();
        }
    }
    
    
  2. 成员内部类,是无法定义静态变量的,但是可以定义静态常量


静态内部类
  1. 不依赖外部类对象,可以直接创建或通过类名访问,可声明静态成员。

    package operator;
    
    public class Outer {
        private String name = "xxx";
        private int age = 18;
    
        //静态内部类,其级别和外部类相同
        static class Inner {
            private String address = "上海";
            private String phone = "110";
            //静态成员
            private static int count=1000;
            public void show(){
                //调用外部类的属性呢
                //1先效用外部类对象
                Outer outer=new Outer();
                //2调用外部类对象的属性
                System.out.println(outer.name);
                System.out.println(outer.age);
                //调用静态内部类的属性和方法
                System.out.println(address);
                System.out.println(phone);
                //调用静态内部的静态属性
                System.out.println(Inner.count);
            }
    
    
        }
    
        public static void main(String[] args) {
            Outer.Inner inner = new Outer.Inner();
            inner.show();
    
        }
    }
    
自我反思–关于成员内部类与静态内部类

1、两个都是非静态的成员内部类,可以观察细节,直接new 内部的的class,它本质是先创建了外部的类的一个实例,再接着创建内部类的的实例,因此内部的类,可以直接调用外部类的所有的属性,包括不限于static 变量,变量,方法等。这种做法是,我认为是为了解决java单继承的这个缺点。这样子搞了之后,以后需要外部的方法,直接Outer.方法就行了。对应python中就相当于闭包这个知识点。

2、静态内部类,你调用内部的静态变量,你可以发现,是没有初始化外部的类,因此,外部的非静态变量,无法直接调用,只能调用static的方法,所以必须new创建里实例,才可以调用。

对比下非静态成员内部类的new方法。

//非静态内部类
inner inner=new Outer().new Inner();
//静态内部类
Outer.Inner inner = new Outer.Inner();

对比发现了吗?
非静态类new的是Outer带括号,而静态的不带括号。这就意味着非静态内部类new的时候,创建了Outer的的实例,而静态内部类没有创建。主要的区别是在这里。

附上另外一个案例:便一目了然

package operator;


public class TestOut {
    int a = 1;
    static int b = 2;
    private int c = 3;
    private static int d = 4;

    //非静态内部类
    class Inner1 {
        int a =5;
        void test() {
            System.out.println(a);   //外部类属性,得出5
            System.out.println(TestOut.this.a);//得出1
            System.out.println(b);   //外部类静态属性,得出2
            System.out.println(c);   //外部私有类属性,得出3
            System.out.println(d);   //外部静态私有类属性,得出4
        }
    }

    //静态内部类
    static class Inner2 {
        void test() {
            TestOut testOut = new TestOut();
            System.out.println(testOut.a); //创建外部的实例,即可调用;得出1
//            System.out.println(a);//外部类属性  有错误
            System.out.println(b);  //外部类静态属性,得出2
//            System.out.println(c);  //外部私有类属性  有错误
            System.out.println(d);  //外部静态私有类属性,得出4
        }
    }

    public static void main(String[] args) {
        new TestOut().new Inner1().test();
        System.out.println("---------------");
        new TestOut.Inner2().test();

    }
}



局部内部类
  1. 定义在外部类方法中,作用范围和创建对象范围仅限于当前方法。
  2. 局部内部类访问外部类当中方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final。
package operator;


public class Outer {
    private String name = "liudehua";
    private int age = 35;

    public void show() {
        //定于局部变量
        String address = "深圳";

        //局部内部类:注意不能加任何访问修饰符
        class Inner {
            private String phone = "144";
            private String email = "xxx@mai.com";

            public void show2() {
                //访问外部类的属性
                System.out.println(Outer.this.name);
                System.out.println(Outer.this.age);
                //访问内部类的属性
                System.out.println(this.phone);
                System.out.println(this.email);

            }
        }
        //创建局部内部类对象
        Inner inner = new Inner();
        inner.show2();
    }

    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.show();
    }
}



匿名内部类
  1. 没有类名的局部内部类(一切特征都与局部内部类相同)。
  2. 必须继承一个父类或者实现一个接口。
  3. 定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
  4. 优点:减少代码量
  5. 缺点:可读性交叉
//Usb.java 接口

public interface Usb {
	//服务
  void service();
}
-------------------------------
//Mouse.java 实现接口
public class Mouse implements Usb{
  @override
  public void service{
    System.out.println("连接电脑成功。鼠标开始工作");
  }
  
}
-------------------------------
//TestUsb.java
public class TestUsb {
  public static void main(String[] args){
    //创建接口类型的变量
    Usb usb=new Mouse();
    usb.service();
  }
  class Fan implements Usb{
    @Overide
    public void service(){
      System.out.println("连接电脑成功,风扇开始工作了。。")
    }
  }
  //使用局部内部类创建对象
  Usb usb=new Fan();
  usb.service();
  
  
  //使用匿名内部类来优化(相当于创建了一个局部内部类)
  Usb usb=new Usb(){
    @Override
    public void service(){
      System.out.println("连接电脑成功,风扇开始工作了");
    }
  };
  Usb.service;  
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/741777.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-28
下一篇 2022-04-28

发表评论

登录后才能评论

评论列表(0条)

保存