内 部 类

目录

内部类的分类

1、成员内部类(在外部类中定义内部类)

2、局部内部类对象(在成员方法中定义局部内部类)

3、静态内部类(嵌套内部类)

4、内部类中的this以及.this的使用

5、匿名内部类

操作符::

绑定静态方法

绑定成员方法

绑定构造方法


内部类的分类

  • 内部类定义在成员位置上:成员内部类
  • 内部类定义在局部位置上:局部内部类
  • 没有名字的内部类: 匿名内部类
  • 被static修饰的内部类:静态内部类

1、成员内部类(在外部类中定义内部类)

普通内部类,是外围的一个成员,可以无限制的访问外部类的所有成员属性和方法,即便是private

但外部类想要访问内部类的成员变量和方法则需要通过内部类实例来访问

成员内部类中不能存在任何的static的变量和方法

成员内部类是依附于外部类的,只有先创建外部类才能创建内部类

public class OuterClass {
    private String name;
    private int age;

    //定义内部类
    public class InnerClass {
        //无参构造
        public InnerClass() {
            name = "jack";//name是外部类的成员变量,内部类可以直接使用
            age = 20;//age是外部类的成员变量,内部类可以直接使用
        }

        public void display() {
            System.out.println("name=" + name + ",age=" + age);
        }
    }

    public static void main(String[] args) {
        //1、创建外部类对象
        OuterClass outer = new OuterClass();
        //2、定义内部类类型的变量
//OuterClass.InnerClass inner = null;//外部类名称.内部类名称,内部类的类型就有了
        OuterClass.InnerClass inner;
        //3、内部类类型变量初始化,创建内部对象
        inner=outer.new InnerClass();
        //每一个对象才有内部类   外部类对象.new  内部类构造方法()的方式构建对象
        //4、调用display方法
        inner.display();
    }
}

2、局部内部类对象(在成员方法中定义局部内部类)

嵌套在方法和作用域内

//外部类
public class OuterClass1 {
    private String name;
    private int age;
    //成员方法
    public void display(int age1){
        //定义局部内部类
        class InnerClass{
            public InnerClass(){
              name="jack";//使用了外部不类的成员变量name
              age=age1;//使用了外部不类的成员变量age,并把方法的参数变量age1赋值给age
            }
            public void display(){
               System.out.println("name="+name+",age="+age);
            }
            //public static void display(){
            //不能用静态的
            //}
        }
       ** //创建局部内部类对象**
        InnerClass inner=new InnerClass();
        //调用局部类display()方法
        inner.display();
    }

    public static void main(String[] args) {
        OuterClass1 outer=new OuterClass1();//外部类对象
        //外部类对象display方法
        outer.display(70);
    }
}

3、静态内部类(嵌套内部类)

静态内部类与非静态内部类存在一个最大的区别:非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外部类,但是静态内部类却没有。

  • 它的创建是不需要依赖于外部类
  • 不能使用任何外部类的非static成员变量和方法
  • 和成员内部类不同,static内部类能够声明static的成员
public class OuterClass2 {
    //外部类静态成员变量,所有的new对象共享静态变量,外部类名/(对象).静态成员变量
    private static String name="jim";
    private int age;
    //静态内部类
    static class InnerClass{
        static String innerStaticName="jack";//静态内部类的静态成员变量
        int innerAge;
        static void innerStaticDisplay(){
//静态方法能调用静态的成员变量
//System.out.println("静态内部类的静态方法innerStaticDisplay被触发,innerStaticName="+innerStaticName+innerAge);
            System.out.println("静态内部类的静态方法innerStaticDisplay被触发,innerStaticName="+innerStaticName);
        }
        void innerDisplay(){
            **//非静态方法可以调用静态和非静态方法**
            System.out.println("静态内部类的非静态方法innerDisplay被触发,innerStaticName="+innerStaticName+",innerAge="+innerAge);
        }
    }
    //外部类的成员方法
    void outerDisplay(){
        //外部类的方法可以调用内部类的静态成员变量
        System.out.println(InnerClass.innerStaticName);
        //外部类的方法可以调用内部类的静态成员方法
        InnerClass.innerStaticDisplay();
    }

    public static void main(String[] args) {
        OuterClass2 outer=new OuterClass2();
        outer.outerDisplay();
        //创建静态内部类对象,直接new静态内部类的构造方法,不依赖outer对象
        //OuterClass2.InnerClass inner=new OuterClass2.InnerClass();
        InnerClass inner=new OuterClass2.InnerClass();
        inner.innerDisplay();
        //调用静态内部类的方法
        //OuterClass2.InnerClass.innerStaticDisplay();
        InnerClass.innerStaticDisplay();
    }
}

Run:
jack
静态内部类的静态方法innerStaticDisplay被触发,innerStaticName=jack
静态内部类的非静态方法innerDisplay被触发,innerStaticName=jack,innerAge=0
静态内部类的静态方法innerStaticDisplay被触发,innerStaticName=jack

4、内部类中的this以及.this的使用

内部类本质上是一个独立的类,在内部类中直接使用this,其指代的是内部类自身的引用,如果要想引用外部内的对象,则应该使用外部类类名.this的方式

public class OuterClass3 {
    private int i=10;//外部类的成员变量
    //成员内部类
    public class InnerClass{
        private int i=100;//内部类的成员变量
        void display(){
            System.out.println(**this.i**);
            //内部类的成员变量i,this内部类的对象引用  i=100
            System.out.println(**OuterClass3.this.i**);
            //外部类的成员变量i,外部类名.this  外部对象的引用  i=10
        }
    }
    public static void main(String[] args) {
        //1、创建外部类对象
        OuterClass3 outer=new OuterClass3();
        //2、创建内部类对象
        OuterClass3.InnerClass inner=outer.new InnerClass();
        //3、调用内部类对象display方法
        inner.display();
    }
}

5、匿名内部类

  • 如果一类内部类仅需要构建一个单一的对象,那么这个类其实并不需要额外取一个特有的名字,对于不存在名字的内部类,我们称为匿名内部类
  • 匿名内部类必须继承一个父类或实现一个接口
  • 匿名内部类没有构造方法(匿名内部类没有显式类名)
  • 匿名内部类要想完成一些初始化工作可以交由类初始化或实例初始化代码块来完成
  • 匿名内部类对类成员、方法临时变量的访问规则和具备名字的内部类保持一致

接口

public interface Foo {
    void display();
}

public class OuterClass4 {
    private String name;
    private int age;
    //创建  实现Foo接口的匿名类对象,赋值给foo变量
    Foo foo = new Foo() {
        @Override
        public void display() {
            System.out.println("打印Foo接口的匿名内部类对象,display方法被调用");
        }
    };
    //继承OuterClass2匿名类的对象,赋值给outerClass2成员变量
    OuterClass2 outerClass2 = new OuterClass2(){
        void outerDisplay(){
            System.out.println("重写OuterClass2.outerDisplay方法");
        }
    };

    public static void main(String[] args) {
        OuterClass4 outer = new OuterClass4();
        outer.foo.display();
        outer.outerClass2.outerDisplay();
    }
}

操作符::

用作静态方法、成员方法或构造方法的绑定

  • 绑定静态方法

public interface IntegerFactory {
    Integer cInteger(String str) ;
}

public class Test {
    public static void main(String[] args) {
        IntegerFactory factory = Integer::valueOf;
        //把Integer的静态方法ValueOf绑定给IntegerFactory的cInteger方法
        //调用factory.cInteger()相当于调用Integer.ValueOf方法
        Integer integer=factory.cInteger("234");
        System.out.println(integer);
    }
}

  • 绑定成员方法

public interface Foo {
    void ifoo();
}

public class Test1 {
    //定义成员方法
    public void foo() {
        System.out.println("Test2的foo方法");
    }
    public static void main(String[] args) {
        Test1 test1 = new Test1();
        //把Test1的对象foo方法绑定Foo接口的ifoo方法上,要求返回值和参数列表一样
        Foo foo = test1::foo;
        //调用foo.ifoo();
        foo.ifoo();
    }
}

  • 绑定构造方法

@FunctionalInterface
public interface PersonFactory {
    Person create(String firstName,String lastName);
}

public class Person {
    String firstName;
    String lastName;

    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return "Person{" +
                "firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                '}';
    }

    public static void main(String[] args) {
        PersonFactory pf=Person::new;
        //把Person的构造方法绑定能给PersonFactory,接口匿名类create方法
        Person p=pf.create("王","肖");
        System.out.println(p);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值