Java基础-内部类

Java基础-内部类

成员内部类

  • 当一个类定义在另一个类里面,我们就称这个类为成员内部类

    public class Outer {
        private String id;
        public void out (){
            System.out.println("这是外部类的方法");
        }
         class Inner{ //成员内部类
            public void in(){
                System.out.println("这是内部类的方法");
            }
        }
    }
    

    这样看起来 Inner就像是Outer的一个成员,Outer称为外部类,Inner称为内部类。成员内部类可以访问外部类的所有成员(包括私有成员和静态成员)

  • 成员内部类的创建是是依附外部类的,也就是说想要创建内部类对象则必须创建一个外部对象

 public class Outer {
   //成员内部类
   class Inner {
       public void in() {
           System.out.println("这是内部类");
       }

       //内部类的构造方法
       Inner() {
           System.out.println("Inner的构造方法");
       }
   }

   //外部类的构造方法
   public Outer() {
       System.out.println("Outer的构造方法");
   }

   //外部类的普通方法
   public void out() {
       System.out.println("这是外部类");
   }
}
class Application {
   public static void main(String[] args) {
       Outer.Inner inner = new Outer().new Inner();
   }
}

在这里插入图片描述

当创建成员内部类时,程序会先执行外部类的构造方法再执行内部类的构造方法

  • 内部类可以使用外部类中所有私有属性和方法
public class Outer {
    private String id="123";
    //成员内部类
    class Inner {
        public void in() {
            out();
            System.out.println(id);
            System.out.println("这是内部类的方法");
        }
    }
    //外部类的普通方法
    public void out() {
        System.out.println("这是外部类的方法");
    }
}

class Application {
    public static void main(String[] args) {
        Outer.Inner inner = new Outer().new Inner();
        inner.in();
    }
}

  • 如果内部类成员和外部类的成员有相同名字,则程序默认调用的是内部类的成员,如果想调用外部的成员则需要”外部类名.this.成员变量“;
public class Outer {
    private String id="123";
    //成员内部类
    class Inner {
        public void in() {
            Outer.this.out();
        }
        public void out() {
            System.out.println("这是内部部类的方法");
        }
    }
    //外部类的普通方法
    public void out() {
        System.out.println("这是外部类的方法");
    }
}

class Application {
    public static void main(String[] args) {
        Outer.Inner inner = new Outer().new Inner();
        inner.in();
    }
}
  • 如果内部类的外部类要问内部类的话,并不能直接访问,外部类必须要创建内部类的对象,即可访问内部类的所有成员(包括私有成员);
public class Outer {
    //成员内部类
    class Inner {
        //内部类的普通方法
        public void in() {
            System.out.println("这是内部部类的方法");
        }
    }
    //外部类的普通方法
    public void out() {
        Inner inner = new Inner();
        inner.in();
    }
}

class Application {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.out();
    }
}
  • 记录问题:
public interface InterfaceTest {
    void test01();
    void test02();
    class Test{//接口的成员内部类
        public void printf(InterfaceTest interfaceTest){
            interfaceTest.test01();
            interfaceTest.test02();
        }
    }

    public static void main(String[] args) {//接口的静态方法
        demo03.Test.Test01 test01 = new demo03.Test().new Test01();//成员内部类需要先初始化外部类再实例化内部类
    }
}
class Test{
    public static void main(String[] args) {
        InterfaceTest.Test test =new InterfaceTest.Test();//接口内部类可以直接实例化 无需使用static修饰成员内部类
    }
    class Test01{//普通类的成员内部类
        public void printf(InterfaceTest interfaceTest){
            interfaceTest.test01();
            interfaceTest.test02();
        }
    }
}

接口没有构造方法,所以接口中的成员内部类可以直接通过外部接口名.内部类名进行对象的创建

局部内部类

  • 当一个类定义在方法体内或者一个作用域内,那么这个类就叫局部内部类

    public class Part {
        static{
            //局部内部类
            class A{
                public void out(){
                    System.out.println("我是静态代码块中的局部内部类");
                }
            }
        }
        public void Test(){
            //局部内部类
            class B{
                public void out(){
                    System.out.println("我是方法里的局部内部类");
                }
            }
        }
    
    }
    

    局部内部类无法使用访问修饰符进行修饰,因为局部内部类的作用域仅在声明该类的块中。所有该类对外部世界可以完全的隐藏,即它的外部类中其他的模块也无法访问它。

    局部内部类可以访问的外部类的成员根据所在方法体不同, 如果在静态方法中,可以访问外部类中所有静态成员,包含私有。如果在实例方法中,可以访问外部类中所有的成员,包含私有。局部内部类可以访问所在方法中定义的局部变量,但是要求局部变量必须使用final修饰。

    public class Part {
        private int s = 1;
        {
            class A {
                final int s = 2;
                public void out() {
                    System.out.println(s);
                    System.out.println("我是代码块里的局部内部类");
                }
            }
        }
        public void Test() {
            final int s = 3;
            //局部内部类
            class B 
                public void out() {
                	Test()System.out.println(s);
                    System.out.println("我是方法里的局部内部类");
                }
            }
        }
         public void Test() {
           System.out.println("外部类的普通方法");
         }
        
    }
    

匿名内部类

  • 使用new关键字初始化类对象时,不将实例保存在变量中则为匿名类

    new String().length();
    

    使用匿名类时,可以直接在该类后面.出自己想要的方法。

  • 使用匿名内部类

  1. new 接口名(){ //匿名内部类的类体部分};

    public interface InterfaceTest {
        void test01();
    
        void test02();
    }
    
    class Test {
        public static void main(String[] args) {
            new InterfaceTest(){//创建匿名内部类
    
                @Override
                public void test01() {//实现接口方法1
                    System.out.println("匿名内部类1");
                }
    
                @Override
                public void test02() {//实现接口方法2
                    System.out.println("匿名内部类2");
                }
            }.test01();//可以后面跟上需要调用的接口方法
        }
    }
    

2.普通方法(new 接口名{//匿名内部类的类体部分});

public interface InterfaceTest {
    void test01();

    void test02();
}

class Test {
    public static void main(String[] args) {
        test(new InterfaceTest() {
            @Override
            public void test01() {
                System.out.println("实现接口方法1");
            }

            @Override
            public void test02() {
                System.out.println("实现接口方法2");
            }
        });
    }
    public static void test(InterfaceTest interfaceTest){
        interfaceTest.test01();

        interfaceTest.test02();
    }
}

3.接口类型 接口名 = new 接口类(){//匿名内部类的类体部分};

public interface InterfaceTest {
    void test01();

    void test02();
}

class Test {
    public static void main(String[] args) {
        InterfaceTest interfaceTest =new InterfaceTest() {
            @Override
            public void test01() {
                System.out.println("实现接口方法1");
            }

            @Override
            public void test02() {
                System.out.println("实现接口方法2");
            }
        };
        interfaceTest.test01();
    }
}

匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。匿名内部类在编译的时候由系统自动起名为Outter$1.class。一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。

静态内部类

  • 静态内部类也是定义在一个类里面,只不过使用static进行修饰,所以不依赖外部类。
  • 它不能使用外部类的非static成员变量或者方法,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象
public class Outer {
    //静态内部类  
    static class Inner {
        private void in() {
            System.out.println("这是静态内部类的方法");
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值