嵌套类

00 好处,Why go to User

java 中的内部类和接口加在一起,可以的解决常被 C++ 程序员抱怨 java 中存在的一个问题??没有多继承。实际上,C++ 的多继承设计起来很复杂,而 java 通过内部类加上接口,可以很好的实现多继承的效果。

  • 内部类的第一个好处就体现出来了??隐藏你不想让别人知道的操作,也即封装性。

  • 内部类的第二个好处??一个内部类对象可以访问创建它的外部类对象的内容,甚至包括私有变量!

01 非静态嵌套类(内部类)

注意

不创建对象,直接使用类名.方法时,所用的方法须是static类型的。

A 成员内部类

class OuterClass{
    class InnerClass{
    }
}

外部类与内部类的相互访问方式

  • 成员内部类可以无条件访问外部类的属性和方法。
class OuterClass {
    private String name = "OuterClass";
    public void run(){
        System.out.println("OuterClassRun");
    }
    class Inner{
        public void say(){
            System.out.println(name);
            run();
        }
    }
}
  • 但是外部类想要访问内部类属性或方法时,必须要创建一个内部类对象,然后通过该对象访问内部类的属性或方法
class OuterClass {
    private String name = "OuterClass";
    public void run(){
        System.out.println("OuterClassRun");
    }
    //使用内部类的属性和方法
    public void eat(){
        Inner inner = new Inner();
        System.out.println(inner.value);
        inner.say();
    }
    class Inner{
        private String value = "InnerClass";
        public void say(){
            System.out.println(name);
            run();
        }
    }
}

外部类属性或者方法进行隐藏

如果成员内部类的属性或者方法与外部类的同名,将导致外部类的这些属性与方法在内部类被隐藏,也可按照该格式调用,外部类.this.属性/方法。如下:外部类与内部类方法名以及属性相同,外部类属性被隐藏。

class OuterClass {
    private String name = "OuterClass"; 
    //使用内部类的属性和方法
    public void say(){
        Inner inner = new Inner();
        System.out.println(inner.value);
        inner.say();
    }
    class Inner{
        private String value = "InnerClass";
        //同属性
        private String name = "InnerClass";
        //同方法
        public void say(){
            System.out.println(name);
            run();
            NestedClass.this.say();
            String n = NestedClass.this.name;
        }
    }
}

创建内部类对象

显然成员内部类是寄生于外部类,创建内部类对象就必须先创造外部类对象。之后创建内部类有两种方式。

public class NestedClass {

    public static void main(String[] args) {
        //创建成员内部类对象
        OuterClass OC = new OuterClass();
        OuterClass.Inner inner = OC.new Inner();
        //法二,需要创建一个返回Inner对象的方法。
        OuterClass.Inner inner1 = OC.getClassInner();
        inner1.say();
    }
}
    class OuterClass{
        private String name = "OuterClass";
		//返回Inner对象的方法
        public Inner getClassInner(){
            return new Inner();
        }
        class Inner{
            private String value = "InnerClass";
            private String name = "InnerClass";
            public void say(){
                System.out.println(name);
                String n = OuterClass.this.name;
            }
        }
    }


成员内部类的访问修饰符

  • private :仅外部类可访问,主方法中为另外的类,不可访问。修饰外部类也一样,主方法中不可进行访问!!!
  • protected:同包下或继承类可访问
  • default:同包下可访问
  • public:所有类可访问

B 局部内部类

其存在于方法中。他和成员内部类的区别在于局部内部类的访问权限仅限于方法或者作用域内。

class Outer{
    public void say(){
        class Inner{
            
        }
    }
}

注:局部内部类就像局部变量一样,前面不能访问修饰符以及static修饰符。这种类不能使用public,private修饰,他的作用于被限定在生命这个类的方法中。局部内部类和其他内部类相比的一个优点,就是局部内部类可以访问方法的参数。被局部内部类使用的方法参数必须是final的。

使用心得:由于局部内部类对外并不可见,因此不如使用匿名内部类替代。只有当需要定义或重写类的构造方法,或者需要多个该类的对象时,才建议使用局部内部类。

C 匿名内部类

名内部类本质上是一个重写或实现了父类或接口的子类对象。匿名类可被视为非静态的内 部类,所以他们具备和方法内部声明的非静态内部类相同的权限和限制。匿名内部类由于没有名字,所以它没有构造函数(但是如果这个匿名内部类继承了一个只含有带参数构造函数的父类,创建它的时候必须带上这些参数,并在实 现的过程中使用 super 关键字调用相应的内容)

public class NestedClass {

    public static void main(String[] args) {
        //创建成员内部类对象
    noNameClass nnc = new noNameClass();
    print pr = nnc.test();
    pr.printing();
    }
}
class noNameClass{
    public print test(){
        return new print() {
            @Override
            public void printing() {
                System.out.println("helloWorld");
            }
        };
        //lambda表达式写法
        //return () -> System.out.println("helloWorld");
    }
}
     interface print{
        void printing();
     }

02 静态嵌套类(static修饰)

静态内部类和成员内部类相比多了一个static修饰符。它与类的静态成员变量一般,是不依赖于外部类的。同时静态内部类也有它的特殊性。因为外部类加载时只会加载静态域,所以静态内部类不能使用外部类的非静态变量与方法。 区别就在于静态内部类没有了指向 外部的引用。

class OuterClass{
    static class StaticNestedClass{
    }
}
posted on 2021-12-13 15:36  胡太白  阅读(66)  评论(0)    收藏  举报