Java 内部类摘抄
关于Java的内部类,要说的东西实在太多,这篇博文中也无法一一具体说到,所以就挑些重点的讲。关于内部类的使用,你可能会疑问,为什么我们要使用内部类?为了回答这个问题,你需要知道一些关于内部类的重点。所以本篇文章首先介绍了一些关于内部类的一些与众不同的地方,后面再解答为什么我们要使用内部类这个问题。各位看官,文章稍微有点长,深吸一口气。来,我们开始吧!
二、内部类定义
内部类定义非常简单,就是把一个类的定义放在另外一个外围类定义的里面。如下面代码所示:
class OutterClass {
class InnerClass {
}
}
你可能会想,内部类和组合有什么区别?就这么简单把内部类的定义放在外部类里面,能惹出多少事儿来?诶,你还别说,还真有不少的事儿。
三、内部类惹出来的那些事儿
1. 内部类能访问外围类的所有成员,包括私有成员。
当生成一个内部类对象时,此对象与制造它的外围类对象之间就有了一种联系,所以它能访问其外围类对象的所有成员,而不需要任何特殊的条件。如下面代码所示:
class OutterClass {
private int i = 1;
class InnerClass {
public void displayPrivate() {
System.out.println(i);
}
}
}
public class MainClass{
public static void main(String[] args) {
OutterClass outter = new OutterClass();
OutterClass.InnerClass inner = outter.new InnerClass();
inner.displayPrivate();
}
}
由上面的代码可以看出,内部类能够访问外部类的私有成员变量。在这段代码中,还需要注意的是
①生成内部类对象,必须要先有外围类对象,具体的做法请见代码;
②内部类能访问外围类的私有成员这一点,C++中的嵌套类是没有这个特性的。
2. 内部类与static
①内部类不能含有static方法;
②内部类不能含有static数据成员,除非是static final;
③内部类可以继承含有static成员的类。
3. 匿名内部类
匿名内部类,看起来非常奇怪。因为它太简洁了,但这也带来一个好处,用匿名内部类写出来的代码通常比较简洁啦!见下面代码(左):
4. 内部类允许继承多个非接口类型
分析左边的代码,可以看出这个语法非常的奇怪。但是仔细想想,也比较容易理解。语法的核心就是return new () {匿名类定义},这个匿名类是AnonymouysBase的子类,然后向上转型为AnonymouysBase类。其实左边代码是右边代码的简化,大家可以对照看一下。所以呢,匿名内部类,可以简化代码。关于匿名内部类还需要注意:
①匿名内部类所使用的参数必须是final;
②匿名内部类因为没有名字,所以不可能有构造函数,只能通过实例初始化来达到一个构造器的效果。
众所周知,java和c++中其中一个不同的地方在于,java是没有多重继承的。可是在某些时候,我们的确还是需要多重继承的,为此java中提出了“接口”的概念。一个类可以实现多个接口,这就解决了多重继承问题吗?我们仔细想想,其实接口只部分解决了多重继承的问题。而每一个内部类都能独立地继承自一个接口或者类,所以无论外围类是否继承了某个接口或者类,对内部类都没有影响。所以内部类和接口双剑合璧,给出了java中多重继承的完美替代方案。见下面代码:
class D {}
abstract class E {}
class Z extends D {
E makeE() { return new E() {}; }
}
public class MultiImplementation {
static void takesD(D d) {}
static void takesE(E e) {}
public static void main(String[] args) {
Z z = new Z();
takesD(z);
takesE(z.makeE());
}
} ///:~
5.内部类继承
因为内部类的构造器必须链接到指向外围类对象的引用。所以,当一个类需要继承内部类时,那个神秘的链接到外部类的引用也必须要得到初始化。见代码:
class WithInner {
class Inner {}
}
public class InheritInner extends WithInner.Inner {
//! InheritInner() {} // Won't compile
InheritInner(WithInner wi) {
wi.super();
}
public static void main(String[] args) {
WithInner wi = new WithInner();
InheritInner ii = new InheritInner(wi);
}
}
如上面代码所示,InheritInner继承内部类,为了能够使得指向外部类的那个神秘的引用能够得到初始化,需要将外部类的引用作为参数传进内部类的构造函数,并且在内部类的构造函数中代用外部类的super()函数。
6. 内部类不能被覆盖
有一个外围类,含有一个内部类。当有另外一个类去继承这个外围类,并且去覆盖这个内部类。真的能覆盖吗?见下面代码:
class Egg {
private Yolk y;
protected class Yolk {
public Yolk() { System.out.println("Egg.Yolk()"); }
}
public Egg() {
System.out.println("New Egg()");
y = new Yolk();
}
}
public class BigEgg extends Egg {
public class Yolk {
public Yolk() { System.out.println("BigEgg.Yolk()"); }
}
public static void main(String[] args) {
new BigEgg();
}
} /* Output:
New Egg()
Egg.Yolk()
*///:~
由程序的输出结果可以看到,Egg和它的派生类BigEgg中的内部类Yolk其实是独立的,它们分布在不同的空间。
7. 内部类VS嵌套类
Java中的嵌套类是指:将内部类声明为static,那么这个内部类就变成了一个嵌套类。因此,相对于内部类来说,嵌套类两个显著的同点在于:
要创建嵌套类的对象,并不需要其外围类的对象,所以内部类中那个指向外围类的神秘的引用在嵌套类中就消失了;
‚不能从嵌套类的对象,访问其外围类的非static成员;
ƒ嵌套类中可以包括static成员或方法。
Java中的嵌套类和c++中的嵌套类,实际上还是有一点不一样的。C++中的嵌套类不能访问外围类的私有成员,但是java中嵌套类可以访问其外围类中static的私有成员。见代码:
class OutterClass {
static class AnotherLevel {
public static void f() {System.out.println("test");}
}
}
public class MainClass {
public static void main(String[] args) {
OutterClass.AnotherLevel.f();
}
} ///:~
8.为什么要使用 内部类?
介绍完java中的内部类,现在我们再回过头来总结一下,为什么要使用内部类?楼主也只能凭着楼主
的理解进行一下总结:
①内部类提供进入其外围类的绿色通道;
‚②一般来说,内部类继承自某个类或实现某个接口,和接口一起实现java中多重继承;
③private内部类给类的设计者提供了一种途径,通过这种方式可以完全阻止任何依赖于类型的编码,并且完全隐藏了实现的细节;
④ƒ匿名内部类可以使得代码更加地灵活。
四、后记
关于java中的内部类,就先介绍这么多了。为了避免文章篇幅过长,也只是挑了点重点进行梳理,一些细节上的东西就没怎么讲了。如有不足之处,欢迎批评指正,谢谢。
Java 内部类摘抄的更多相关文章
- java 内部类(摘抄自网络)
Java内部类 1.内部类分为成员内部类.静态嵌套类.方法内部类.匿名内部类. 几种内部类的共性: A.内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的.class文件,但是前面冠以外部类 ...
- Java内部类final语义实现
本文描述在java内部类中,经常会引用外部类的变量信息.但是这些变量信息是如何传递给内部类的,在表面上并没有相应的线索.本文从字节码层描述在内部类中是如何实现这些语义的. 本地临时变量 基本类型 fi ...
- Java内部类详解
Java内部类详解 说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉.原因是平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下,并且即使用到也很少去总结内部类的用法.今天我们就 ...
- 黑马----JAVA内部类
黑马程序员:Java培训.Android培训.iOS培训..Net培训 黑马程序员--JAVA内部类 一.内部类分为显式内部类和匿名内部类. 二.显式内部类 1.即显式声明的内部类,它有类名. 2.显 ...
- java 内部类 *** 最爱那水货
注: 转载于http://blog.csdn.net/jiangxinyu/article/details/8177326 Java语言允许在类中再定义类,这种在其它类内部定义的类就叫内部类.内部类又 ...
- java内部类和匿名内部类
内部类即是包含在类里面的又一个类. java内部类分为: 成员内部类.静态嵌套类.方法内部类.匿名内部类 . 内部类的共性 (1).内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.clas ...
- Java内部类小程序(成员内部类,静态内部类,匿名内部类)
/** * 测试java内部类(成员内部类,静态内部类,匿名内部类) * 局部内部类不常用,就不写了. * @package :java05 * @author shaobn * @Describe ...
- [转] Java内部类详解
作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本博客中未标明转载的文章归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置 ...
- java内部类的作用分析
提起Java内部类(Inner Class)可能很多人不太熟悉,实际上类似的概念在C++里也有,那就是嵌套类(Nested Class),关于这两者的区别与联系,在下文中会有对比.内部类从表面上看,就 ...
随机推荐
- vagrant初始登录失败的一般性解决方案
如果是下载的box文件,vagrant box add和init之后启动,可能出现长时间无法通过vagrant ssh登陆的问题 ==> localvm2: Importing base box ...
- Des加解密算法
class DesHelper { /// <summary> /// DES加密方法 /// </summary> ...
- JavaScript 数组 length 属性获取数组长度或设置数组元素的数目
JavaScript 数组 length 属性 JavaScript 数组 length 属性可返回或设置或组中元素的数目,语法如下: array_object.length 利用 length 属性 ...
- iOS实现屏幕旋转
iOS实现屏幕旋转有两种方式 1. 应用本身支持 2. 手动旋转UIView (这种方式我没找到旋转 系统控件的方法 如:键盘.导航.UIAlertView) 如果你只是要把竖屏的播放器,做成支持横屏 ...
- 8.16 CSS知识点7
display(元素显示模式) 语法: display : block | none | inline | inline-block display 属性用来设置元素的显示方式. block ...
- linux 学习5 文本编辑器 vim
vim 没有菜单,只有命令 //root用户既可以用vi,也可以用vim, 无实质性区别,vim是vi的升级版//粘贴用shift+insert , 要在insert模式下粘贴,否则粘贴不全// ^ ...
- 最简单的JS图片轮播
var arr=new Array(); arr[1]="";//放图片地址 arr[2]=""; arr[3]=""; var no=0; ...
- python 二叉树实现带括号的四则运算(自学的孩子好可怜,不对的地方请轻责)
#!/usr/bin/python #* encoding=utf-8 s = "20-5*(0+1)*5^(6-2^2)" c = 0 top = [0,s[c],0] op = ...
- 1全志 A20 camera移植
转自 http://www.right.com.cn/forum/thread-146260-1-1.html 在Android4.0升级后,突然发现大量平台对Camera的支持均非常不好.要么C ...
- angularjs(一)基础概念
一.前言 前端技术的发展是如此之快,各种优秀技术.优秀框架的出现简直让人目不暇接,作为一名业界新秀,紧跟时代潮流,学习掌握新知识自然是不敢怠慢.当听到AngularJs这个名字并知道是google在维 ...