梵美传媒网站是谁做的,不用花生壳做网站服务器,crm管理系统 一般包含,大公司的网站都找谁设计java内部类 内部类的分类 特点 定义方式 使用 外部类调用内部类 多层嵌套内部类 内部类访问外部类属性 接口中的内部类 内部类的继承 内部类的覆盖 局部内部类 成员内部类 静态内部类 匿名内部类内部类定义将一个类定义放到另一个类的内部,这就是内部类内部类与组合是完…java内部类 内部类的分类 特点 定义方式 使用 外部类调用内部类 多层嵌套内部类 内部类访问外部类属性 接口中的内部类 内部类的继承 内部类的覆盖 局部内部类 成员内部类 静态内部类 匿名内部类内部类定义将一个类定义放到另一个类的内部,这就是内部类内部类与组合是完全不同的概念内部类指的是类的定义在内部看起来像一种代码隐藏机制但是,远不止于此,因为他了解外部类 并且能够通信内部类的代码,可以操作创建它的外部类的对象所以可以认为内部类提供了某种进入其外部类的窗口内部类特点内部类访问外部类不需要任何特殊条件,拥有外部类所有的访问权也就是对于内部类访问外部类的元素这件事情上他就相当于是外部类本身一样随便访问内部类的创建依赖外部类对象可以直接访问外部类的变量也可以直接指明外部类类名.this.变量名this通常是多余的,可以省略内部类不仅能够访问包含他的外部类,还可以访问局部变量但是局部变量必须被声明为final因为局部内部类会将调用的变量进行拷贝,为了保证一致性,所以变量必须为final内部类就是隐匿在外部类内部的一个独立的个体,不存在is a like a内部类的对象必定秘密的捕获了一个指向外部类对象的引用然后以此访问外部类的成员,编译器处理了所有的细节,对我们来说都是透明的public class O { class I{O get() { return O.this;}}public static void main(String[] args) {O outer new O();O.I inner outer.new I();System.out.println(outer inner.get());}}打印结果为:true内部类持有的外部类对象就是外部类对象本身,内存地址是相同的外部类的作用域之外,可以使用 outerClass.innerClass 方式引用内部类可以对同一个包中其他类隐藏内部类可以声明为私有的每个类都会产生一个.class文件,包含了类的元信息如果内部类是匿名的,编译器会简单的产生一个数字作为标识符形如 Outer$1.class否则就是形如 外部类$内部类.class ,虚拟机看来与其他类无差,这也是编译器做的工作普通的类(外部类)只能用public修饰符修饰,或者不写修饰符 使用默认的,但是内部类可以使用private 与protected内部类可以达到类似多重继承的效果,每个内部类都能独立的继承自一个(接口的)实现无论外部类是否已经继承了某个(接口的)实现也就是说 单个外部类,可以让多个内部类以不同的方式实现同一个接口或者继承同一个类一个外部类可以创建多个内部类,这是不是就达到了类似多重继承的效果呢内部类分类成员内部类局部内部类匿名内部类静态内部类成员内部类成员内部类也叫实例内部类。每一个外部类对象都需要一个内部类的实例内部类离不开外部类存在既然是成员内部类,和成员属性成员方法地位上自然没有什么不同每个外部类对象都有一个内部类对象,自然持有外部类的引用Outer outer new Outer();Outer.Inner inner outer.new Inner();//注意是对象.new局部内部类局部内部类不能用public或者private或者protected访问说明符,作用域被限定在了声明这个局部内部类中了很好理解,局部的就跟方法变量一样,限定在了{}之中,自然就不需要设置访问说明符了,而且你可以想下,也只有类以及类的成员有访问修饰符,局部变量有访问修饰符么局部类可以对外面完全的隐藏起来,即使是外部类的其他的代码也不能访问他局部内部类虽然被限定在局部代码块{} 里面,但是他也是可以访问外部类的属性的,不要被分类迷惑了匿名内部类匿名内部类就是局部内部类的进一步隐藏,局部内部类定义了之后在局部区域内仍旧可以创建多个对象匿名内部类声明一个类之后就只能创建一个对象了,因为他并没有类名字形式为:new xxxClass (){ //或者new xxxInterface()//.......}表示创建一个类的对象,这个类是xxxClass 子类或者实现了xxxInterface 接口的类也可以说匿名内部类就是创建了一个匿名类的子类对象构造方法名字和类名是相同的,匿名内部类显然是没有构造方法的,因为连名字都没有既然没有构造方法想要构造参数,就只能把参数传递给外部的构造器,通过外部类的构造器绕一圈,本身内部类可以访问外部类所有的属性,去把值操作起来当然外部类自然可以搞点属性根据业务逻辑单独给内部类用如果是实现接口,不能带任何的参数的,因为接口都没有构造方法的呀不过还可以通过初始化代码块达到类似的初始化效果,想必大家还记得初始化代码块是什么吧不过也仅仅是达到类似的效果,而且,相当于只有一个构造方法,因为即使你写了多个初始化代码块,还不是构造对象的时候一起执行嘛小技巧,匿名内部类的参数传递fun(new ArrayList(){{add(a);add(b);add(c);}});也就是:fun(new ArrayList(){ {add(a);add(b);add(c);}});构造了一个匿名内部类,内部类没有更新重写增加任何的方法设置了一个初始化块 {} ,初始化块会在每个对象构造的时候执行代码块中调用add方法增加对象静态内部类如果使用内部类只是为了将一个类隐藏到一个类的内部并不需要内部类引用外部类的对象可以将内部类声明为static,以便取消产生的引用也只有内部类可以声明为static静态内部类的对象除了没有对生成他的外部类的对象的引用特权外,其他的内部类一样通过 外部类 . 内部类 来访问刚才已经说了显然,静态内部类不会持有外部类的引用静态的创建形式:Outer.Inner inner new Outer.Inner();内部类的继承内部类的构造器必须连接到指向外部类对象的引用但是在继承的时候那个指向外部类对象的隐匿的引用必须被初始化而在派生类中不再存在可连接的默认对象所以你要解决这个问题,否则的话就会出错说的就是要包含指向外部类的引用必须是带参数的,而且参数类型是外部类 在这里面调用superpublic class InnerInherit extends OutClass.Inner {InnerInherit(OutClass out){out.super();} public static void main(String[] args){OutClass out new OutClass();InnerInherit ii new InnerInherit(out);}}class OutClass { class Inner{}}可以看得到,虽然只是继承内部类但是想要生成一个构造器,不仅仅是需要传递一个外部类的引用必须在构造器中使用:enclosingClassReference.super();说白了就是,内部类的对象依赖外部类的对象内部类的子类的对象,也仍旧是依赖外部类的对象的内部类的加载时机package test.b;public class Outer {Outer(){System.out.println(Outer构造方法);}{System.out.println(Outer初始化代码块);} static{System.out.println(Outer静态代码块);}class Inner{Inner(){System.out.println(Inner构造方法);}{System.out.println(Inner初始化代码块);}}public static void main(String[] args) {Outer outer new Outer();System.out.println(----------); //Outer.Inner inner outer.new Inner();}}打印结果:Outer静态代码块Outer初始化代码块Outer构造方法----------显然,内部类没有被初始化,放开注释打印结果:Outer静态代码块Outer初始化代码块Outer构造方法----------Inner初始化代码块Inner构造方法所以可以说内部类是懒加载的 用到了才加载初始化而且,可以创建多个内部类的实例Outer.Inner inner1 outer.new Inner();Outer.Inner inner2 outer.new Inner();Outer.Inner inner3 outer.new Inner();Outer.Inner inner4 outer.new Inner();这是可以的,完全没问题,每个实例有自己的状态信息,与外部类对象信息独立内部类的覆盖情况两个类之间的继承和他们各自的内部类没有关系,不存在覆盖的情况两个类之间的继承关系 比如 B extends A ,每个类中都有C这个内部类他们两者中的C是没有什么关系的示例:类A 拥有内部类C 并且有一个C的对象,构造方法中初始化类B继承A,并且B中也有一个内部类Cpublic class A { private C c;A(){System.out.println(A constructor);c new C();}protected class C{C(){System.out.println(A ....C constructor);}}public static void main(String[] args) {}}public class B extends A{B(){System.out.println(B constructor);} class C{C(){System.out.println(B ....C constructor);}}public static void main(String[] args) { new B();}}创建类B new B();打印信息:A constructorA ....C constructorB constructor创建B的对象,需要调用父类的构造方法所以会打印A constructor 然后构造方法中创建C对象,然后是A ....C constructor 显然,这并不是B类中的C所以说:两个类之间的继承,不存在内部类被覆盖的情况虽然B继承了A A有C B也有C但是两个内部类是完全独立的两个实体各自在各自的命名空间中上面的例子中创建一个对象,有父类,调用父类的构造方法,父类的构造方法调用父类的C的构造方法,也找不到任何方法会要调用子类的C主函数修改下:public static void main(String[] args) { //new B();A a new B();System.out.println(#############);B b new B();System.out.println(#############);a.new C();System.out.println(#############);b.new C();System.out.println(#############);}打印结果为:A constructorA ....C constructorB constructor#############A constructorA ....C constructorB constructor#############A ....C constructor#############B ....C constructor#############上面两段很正常,都是创建B对象,自然步骤一样当创建a.new C(); 的时候使用的是A的C当创建b.new C(); 的时候使用的是B的C显然,创建内部类对象时,到底是父类中的还是子类中的是由: .new 前面的类型决定的,也就是定义的类型,而不是实际指向的类型多层嵌套的内部类多层嵌套的内部类,他能透明的访问所有他所嵌入的外围类的所有成员public class NestedClass { private String NestedClassName NestedClass; public class NestedClass1{ private String NestedClass1Name NestedClass1; public class NestedClass2{ private String NestedClass2Name NestedClass2; public class NestedClass3{ public void print() {System.out.println(NestedClassName: NestedClassName);System.out.println(NestedClass1Name: NestedClass1Name);System.out.println(NestedClass1Name: NestedClass2Name);}}}} public static void main(String[] args) {NestedClass nestedClass new NestedClass();NestedClass.NestedClass1 nestedClass1 nestedClass.new NestedClass1();NestedClass.NestedClass1.NestedClass2 nestedClass2 nestedClass1.new NestedClass2();NestedClass.NestedClass1.NestedClass2.NestedClass3 nestedClass3 nestedClass2.new NestedClass3();nestedClass3.print();}}打印信息NestedClassName: NestedClassNestedClass1Name: NestedClass1NestedClass1Name: NestedClass2从代码中可以看的出来,多层内部类和一层内部类创建格式是一样的外部类名.内部类名 对象名 外部类对象.new 内部类名();这个外部类指的就是他的外部,如果他的外部仍旧是别人的内部类,那就依次往外找就好了从打印信息可以看得出来,不管有几层,内部类,可以访问到他外面的所有的类的属性信息接口中的内部类一般情况下接口中不允许放置任何代码,但是嵌套类可以作为接口的一部分你放到接口中的任何类都自动的是public 和 是 static 的因为类是static,只是将嵌套类置于接口的命名空间内,并不违反接口的规则你甚至可以接口中的内部类实现外部接口如果你想要创建某些公共代码,使得他们可以被某个接口的所有不同实现所共用那么使用接口内部的嵌套类会显得很方便示例:public class Test { public static void main(String[] args) { // 接口中的内部类都是默认 public static 的Fly bird new Fly.DemoFly();bird.fly();Fly bigBird new BigBird();bigBird.fly();}}interface Fly { public void fly(); class DemoFly implements Fly {Override public void fly() {System.out.println(一般的鸟都这么飞~);}}}class BigBird implements Fly {Override public void fly() {System.out.println(大鸟都这么飞~);}}打印信息:一般的鸟都这么飞~大鸟都这么飞~可以看得出来,直接通过内部类,接口的静态内部类,可以提供一个默认的实现这就是提供了编程接口的同时,又提供了一个默认的实现,多给力内部类中不能有静态属性以及静态方法以及静态代码块class A{class B{ private static int a 0;//IDE会提示报错的 }}非静态的内部类型,不能声明静态的filed 除非标记为常量,也就是用final声明