java快三源码下载内部类深入详解 内部类的分类 特点 定义方式 使用
2018-07-06 11:16
274 查看
内部类定义快三源码下载【大神源码论坛】dsluntan.com 【布丁源码论坛】budingbbs.com 企娥3393756370
将一个类定义放到另一个类的内部,这就是内部类
内部类与组合是完全不同的概念
内部类指的是类的定义在内部
看起来像一种代码隐藏机制
但是,远不止于此,因为他了解外部类 并且能够通信
内部类的代码,可以操作创建它的外部类的对象
所以可以认为内部类提供了某种进入其外部类的窗口
内部类特点
内部类访问外部类不需要任何特殊条件,拥有外部类所有的访问权
也就是对于内部类访问外部类的元素这件事情上
他就相当于是外部类本身一样随便访问
内部类的创建依赖外部类对象
可以直接访问外部类的变量
也可以直接指明
外部类类名.this.变量名
this通常是多余的,可以省略
内部类不仅能够访问包含他的外部类,还可以访问局部变量
但是局部变量必须被声明为final
因为局部内部类会将调用的变量进行拷贝,为了保证一致性,所以变量必须为final
内部类就是隐匿在外部类内部的一个独立的个体,不存在is a like a
内部类的对象必定秘密的捕获了一个指向外部类对象的引用
然后以此访问外部类的成员,编译器处理了所有的细节,对我们来说都是透明的
外部类的作用域之外,可以使用 outerClass.innerClass 方式引用内部类
可以对同一个包中其他类隐藏
内部类可以声明为私有的
每个类都会产生一个.class文件,包含了类的元信息
如果内部类是匿名的
编译器快三源码下载【大神源码论坛】dsluntan.com 【布丁源码论坛】budingbbs.com 企娥3393756370会简单的产生一个数字作为标识符形如 Outer$1.class
否则就是形如 外部类$内部类.class ,虚拟机看来与其他类无差,这也是编译器做的工作
普通的类(外部类)只能用public修饰符修饰,或者不写修饰符 使用默认的
但是内部类可以使用private 与protected
内部类可以达到类似"多重继承"的效果,
每个内部类都能独立的继承自一个(接口的)实现
无论外部类是否已经继承了某个(接口的)实现
也就是说 单个外部类,可以让多个内部类以不同的方式实现同一个接口或者继承同一个类
一个外部类可以创建多个内部类,这是不是就达到了类似"多重继承"的效果呢
回到顶部
内部类分类
1.成员内部类
2.局部内部类
3.匿名内部类
4.静态内部类
成员内部类
成员内部类也叫实例内部类。每一个外部类对象都需要一个内部类的实例,内部类离不开外部类存在
既然是成员内部类,和成员属性成员方法地位上自然没有什么不同
每个外部类对象都有一个内部类对象,自然持有外部类的引用
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();//注意是对象.new
局部内部类
局部内部类不能用public或者private或者protected访问说明符,作用域被限定在了声明这个局部内部类中了
很好理解,局部的就跟方法变量一样,限定在了{}之中,自然就不需要设置访问说明符了,而且你可以想下,也只有类以及类的成员有访问修饰符,局部变量有访问修饰符么
局部类可以对外面完全的隐藏起来,即使是外部类的其他的代码也不能访问他
局部内部类虽然被限定在局部代码块{} 里面,但是他也是可以访问外部类的属性的,不要被分类迷惑了
匿名内部类
匿名内部类就是局部内部类的进一步隐藏,局部内部类定义了之后在局部区域内仍旧可以创建多个对象
匿名内部类声明一个类之后就只能创建一个对象了,因为他并没有类名字
形式为:
new xxxClass (){ //或者new xxxInterface()
//.......
}
表示创建一个类的对象,这个类是xxxClass 子类或者实现了xxxInterface 接口的类
也可以说匿名内部类就是创建了一个匿名类的子类对象
构造方法名字和类名是相同的,匿名内部类显然是没有构造方法的,因为连名字都没有
既然没有构造方法想要构造参数,就只能把参数传递给外部的构造器,通过外部类的构造器绕一圈,本身内部类可以访问外部类所有的属性,去把值操作起来
当然外部类自然可以搞点属性根据业务逻辑单独给内部类用
如果是实现接口,不能带任何的参数的,因为接口都没有构造方法的呀
回到顶部
小技巧,匿名内部类的参数传递
fun(new ArrayList<String>(){{add("a");add("b");add("c");}}); 也就是:
fun(new ArrayList<String>(){
{
add("a");
add("b");
add("c");
}
}
);
1.构造了一个匿名内部类,内部类没有更新重写增加任何的方法
2.设置了一个初始化块 {} ,初始化块会在每个对象构造的时候执行
3.代码块中调用add方法增加对象
静态内部类
如果使用内部类只是为了将一个类隐藏到一个类的内部
并不需要内部类引用外部类的对象
可以将内部类声明为static,以便取消产生的引用
也只有内部类可以声明为static
静态内部类的对象除了快三源码下载【大神源码论坛】dsluntan.com 【布丁源码论坛】budingbbs.com 企娥3393756370没有对生成他的外部类的对象的引用特权外,其他的内部类一样
通过 外部类 . 内部类 来访问
刚才已经说了显然,静态内部类不会持有外部类的引用
静态的创建形式:
Outer.Inner inner = new Outer.Inner();
回到顶部
内部类的继承
内部类的构造器必须连接到指向外部类对象的引用
但是在继承的时候
那个指向外部类对象的"隐匿的"引用必须被初始化
而在派生类中不再存在可连接的默认对象
所以你要解决这个问题,否则的话就会出错
说的就是要包含指向外部类的引用
必须是带参数的,而且参数类型是外部类 在这里面调用super
public 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中也有一个内部类C
public 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 constructor
A ....C constructor
B constructor
创建B的对象,需要调用父类的构造方法
所以会打印A constructor 然后构造方法中创建C对象,然后是A ....C constructor 显然,这并不是B类中的C
所以说:
两个类之间的继承,不存在内部类被覆盖的情况
虽然B继承了A A有C B也有C
但是两个内部类是完全独立的两个实体
各自在各自的命名空间中
上面的例子中创建一个对象,快三源码下载【大神源码论坛】dsluntan.com 【布丁源码论坛】budingbbs.com 企娥3393756370有父类,调用父类的构造方法,父类的构造方法调用父类的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 constructor
A ....C constructor
B constructor
#############
A constructor
A ....C constructor
B 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: NestedClass
NestedClass1Name: NestedClass1
NestedClass1Name: NestedClass2
从代码中可以看的出来,多层内部类和一层内部类创建格式是一样的
外部类名.内部类名 对象名 = 外部类对象.new 内部类名();
这个外部类指的就是他的外部,如果他的外部仍旧是别人的内部类,那就依次往外找就好了
从打印信息可以看得出来,不管有几层,内部类,可以访问到他外面的所有的类的属性信息
回到顶部
接口中的内部类
一般情况下
接口中不允许放置任何代码,但是嵌套类可以作为接口的一部分
你放到接口中的任何类都自动的是public 和 是 static 的
因为类是static,只是将嵌套类置于接口的命名空间内,并不违反接口的规则
你甚至可以接口中的内部类实现外部接口
如果你想要创建某些公共快三源码下载【大神源码论坛】dsluntan.com 【布丁源码论坛】budingbbs.com 企娥3393756370代码,使得他们可以被某个接口的所有不同实现所共用
那么使用接口内部的嵌套类会显得很方便
示例:
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("大鸟都这么飞~");
}
}
打印信息:
一般的鸟都这么飞~
大鸟都这么飞~
可以看得出来,直接通过内部类,接口的静态内部类,可以提供一个默认的实现
这就是提供了编程接口的同时,又提供了一个默认的实现,多给力 阅读更多
相关文章推荐
- java内部类深入详解 内部类的分类 特点 定义方式 使用
- PHP实现生成vcf vcard文件功能类定义与使用方法详解【附demo源码下载】[原创]_php技巧_脚本之家
- Java集合的特点、定义及Map集合的遍历方式
- 【java】源码详解三种map遍历方式
- dynamic web twain java免费下载及使用方法教程功能详解
- java中访问修饰符的使用,方法重写定义,final修饰符,布局的特点等等:
- VC使用ADO连接Oracle数据库详解(含源码下载)
- 深入理解为什么Java中方法内定义的内部类可以访问方法中的局部变量
- 深入理解为什么Java中方法内定义的内部类可以访问方法中的局部变量
- .NET源码保护控件VMProtect免费下载及使用教程脱壳等功能详解
- 深入java面向对象四:Java 内部类种类及使用解析(转)
- 深入java面向对象四:Java 内部类种类及使用解析(转)
- struts 2 深入详解 孙鑫 源码 struts2 深入详解 书上源码 下载列表
- 【java项目实践】详解Ajax工作原理以及实现异步验证用户名是否存在+源码下载(java版)
- Java解析HTML之HTMLParser使用与详解 分类: C_OHTERS 2014-05-19 21:46 2309人阅读 评论(0) 收藏
- java中final在不同情况下使用的特点作用详解
- 深入java线程池的使用详解
- 分区、内存-深入理解Oracle表(5):三大表连接方式详解之Hash Join的定义,原-by小雨
- java 泛型深入之Set实用工具 各种集合泛型深入使用示例,匿名内部类、内部类应用于泛型探讨
- 高级java工程师---------SSH源码包下载及使用