JAVA和Nginx 教程大全

网站首页 > 精选教程 正文

内部类(内部类有几种)

wys521 2025-01-23 21:56:54 精选教程 29 ℃ 0 评论

内部类在Java中主要有四种类型分别为静态内部类(Static Inner Class)、成员内部类(Member Inner Class)、局部内部类(Local Inner Class)和匿名内部类(Anonymous Inner Class)。这四种内部类各有其特点和应用场景,可以根据具体需求选择合适的类型。内部类主要用于隐藏内部实现细节,提高代码安全性,方便组织相关类,实现回调功能和多重继承等。

静态内部类(Static Inner Class)

静态内部类是使用static关键字修饰的内部类。它只能访问外部类的静态成员(包括静态变量和静态方法),而不能访问外部类的实例成员。由于静态内部类不依赖于外部类的实例,因此可以直接通过类名来访问。

public class InnerClass {
    private static String englishName = "static variable name";
    private String name = "变量名";

    static class InnerA {
        private static String englishName_ = "inner class static variable name";
        private String name_ = "inner class variable name";

        void methodA() {
            System.out.println("I am static inner class!");
            //静态内部类只能访问外部类的静态成员,外部类的非静态成员不能访问,本内部类的静态和非静态成员都可以访问
            System.out.println(englishName);
            System.out.println(name_);
        }
    }
    /**
     * 外部类方法访问静态内部类
     * 可以访问静态内部类的静态和非静态成员变量
     * 可以访问外部类静态和非静态成员变量
     */
    void getInnerA() {
        InnerA a = new InnerA();
        System.out.println(a.name_);
        System.out.println(a.englishName_);
        System.out.println(englishName);

    }
    public static void main(String[] args) {
        InnerClass inner = new InnerClass();
        inner.getInnerA();
    }
}

成员内部类(Member Inner Class)

成员内部类是最常见的内部类形式,它没有使用static关键字修饰。成员内部类可以访问外部类的所有成员,包括私有成员。成员内部类依赖于外部类的实例,因此需要通过外部类实例来创建。类中定义的私有内部类和内部类中不能直接定义静态变量,可以定义final类型的静态变量。

public class InnerClass {
    private static String englishName = "I am Inner class static variable name";
    private String name = "变量名";

    //private inner class
    private class InnerB {
        //private inner class default Properties
        int a = 20;
        //private inner class private Properties
        private int b = 20;
        //private inner class public Properties
        public int c = 20;

        public void methodB() {
            System.out.println(englishName + "methodB!");
        }

        private void methodC() {
            System.out.println(englishName + "methodC!");
        }
    }

    //inner class
    class InnerC {
        //inner class call External class method
        InnerB innerB = getInnerB();

        /**
         * 可以访问私有内部类的public方法
         * 可以访问私有内部类的private方法
         * 可以访问私有内部类的public属性的变量
         * 可以访问私有内部类的private属性的变量
         * 可以访问私有内部类的默认属性的变量
         */
        public void innerC() {
            System.out.println(englishName + "methodC!");
            //System.out.println(a);//不能直接访问私有内部类的成员和方法,可以通过创建私有内部类的实例来访问
            System.out.println(innerB.a);

        }
    }

    //External class methods call inner class
    InnerB getInnerB() {
        return new InnerB();
    }

    /**
     * 外部类可以访问私有内部类public方法
     * 外部类可以访问私有内部类private方法
     * 不能直接访问内部类变量
     * 外部类可以通过创建内部类实例的方式访问私有内部类的公开的或者私有的方法和属性
     */
    void externalMethod() {
        InnerB innerB = new InnerB();
        innerB.methodB();
        innerB.methodC();
        //System.out.println(a);
        System.out.println(innerB.a);
        InnerC innerC = new InnerC();
        innerC.innerC();
    }

    public static void main(String[] args) {
        InnerClass inner = new InnerClass();
        inner.getInnerB();
        inner.externalMethod();
    }
}

局部内部类(Local Inner Class)

方法中定义内部类,局部内部类可以访问外部类的所有成员以及该方法或代码块的所有局部变量(包括final和非final的)。可见性更小,只在方法内部可见,在外部类及外部类的其它方法中都不可见。方法内部定义成员,只允许final修饰或不加修饰符,public private static等都不可用。

public class InnerClass2 {
    String externalVariableName = "I am inner class externalVariableName!";

    //方法内定义内部类A
    public void methodA() {
        class MethodInnerClassA {
            String innerVariableName = "I am Method Inner class innerVariableName";

            void innerClassMothodA() {
                System.out.println(externalVariableName);
            }
        }
        MethodInnerClassA inner = new MethodInnerClassA();
        inner.innerClassMothodA();
    }

    /**
     * Define internal classes within methodsB(方法内定义内部类B)
     * Can directly access external class variables
     * Can directly access variables within this method
     * Can directly access the final variable of this method(可直接访问本方法的final变量)
     */
    public void methodB(String str) {
        //public String str1 = "Russia";  //不可定义为public
        //static String str2 = "Ukraine";  //不可定义为static
        String str3 = "Russia";
        final String str4 = "Ukraine";
        class MethodInnerClassB {
            final static String str5 = "I am final variable";

            //Static variables cannot be declared
            //static String str6 = "I am static variable";
            public void innerClassMothodB() {
                System.out.println(externalVariableName); //可以直接访问外部类变量
                System.out.println(str3); //可直接访问本方法内部的变量
                System.out.println(str4); //可直接访问本方法的final变量
            }
        }
        MethodInnerClassB innerTwo = new MethodInnerClassB();
        innerTwo.innerClassMothodB();
    }

    public static void main(String[] args) {
        InnerClass2 innerClass2 = new InnerClass2();
        innerClass2.methodA();
        innerClass2.methodB("variable");
    }
}

匿名内部类(Anonymous Inner Class)

匿名内部类是没有名字的内部类,通常用于简化代码,实现一次性的功能。匿名内部类可以直接使用外部类的所有成员,并且可以重写外部类的方法或实现接口。匿名内部类通常用于实现接口或继承某个类,并且只创建一个实例。

一个接口里有一个未被实现的方法,如果想直接调用该方法,传统思路需要一个类B来实现接口A,再创建类B的对象来调用A。

interface A{
    public void eat();
}

class B implements A{
    @Override
    public void eat() {
        System.out.println("calling eat method");
    }
}

public class test {
    public static void main(String[] args) {
        B b = new B();
        b.eat();
    }
}

匿名内部类的实现

interface A{
    public void eat();
}

public class test{

    public static void main(String[] args) {
        new A(){
            @Override
            public void eat() {
                System.out.println("calling eat method");
            }
        }.eat();
    }
}

此时匿名内部类相当于一个对象,可以直接调用eat方法。当A里面有多个方法要调用时,可以这样调用:

interface A{
    public void eat();
    public void drink();
}

public class test{

    public static void main(String[] args) {
        A a = new A(){
            @Override
            public void eat() {
                System.out.println("calling eat method");
            }
            public void drink(){
                System.out.println("calling drink method");
            }
        };
        a.eat();
        a.drink();
    }
}

没有实例化这个接口的类,便实现了里面的方法,所以称之为匿名内部类。其实这个类是被临时创建了,在内存中存在系统设定的名字,通过以下方式获取匿名内部类的名字:

interface A{
    public void eat();
    public void drink();
}

public class test{

    public static void main(String[] args) {
        A a = new A(){
            @Override
            public void eat() {
                System.out.println("calling eat method");
            }
            public void drink(){
                System.out.println("calling drink method");
            }
        };
        a.eat();
        a.drink();
        System.out.println(a.getClass()); //获取类名
    }
}

常用的场景是通过实参的形式来使用

interface A{
    public void eat();
}

public class test{
    public static void main(String[] args) {
        f(new A() {
            @Override
            public void eat() {
                System.out.println("没有创建对象便成功的调用了f方法,不需要实现接口");
            }
        });
    }
    public static void f(A a){
        a.eat();
    }
}
//不需要创建对象便可成功调用f方法,不需要实现接口

匿名内部类具有以下特点:

1、使用匿名内部类时,必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。

2、匿名内部类中不能定义构造函数的。

3、匿名内部类中不能存在任何的静态成员变量和静态方法。

4、匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。

5、匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表