外部类的创建

直接在  外部类里面   像定义其他类一样地去定义。

在外部类的非static方法中,要用自己定义的内部类就和用普通类一样,直接拿来就new。

除了外部类的feistatic方法,在其他地方像其他类中的方法或者是外部类的static方法中,要使用内部类则要用完整的   外部类.内部类名   这样的格式来标识一个内部类。

引用外部类的变量

内部类可以自动获得创建他的那个类中的类变量,这是因为内部类会暗中抓住  外部类对象  的引用,当你要用到外部类的  类变量的适合,这个引用会帮你选择正确的类变量。  因此   当你要创建一个   非static的内部类的对象的时候,一定只有在它和外部类的对象相关联的情况下,才能被创建。

.this和.new

上面说了,之所以内部类可以使用外部类的  类变量,是因为  偷偷抓住了  外部类对象的引用。   那么当你想要用到这个引用的时候,只需要OutClass.this就可以。  注意,直接在内部类中用this关键字,返回的引用是这个内部类对象的引用。

怎么直接创建内部类的对象呢??用.new关键字,下面看个例子:

DotNew.Inner dni = dn.new Inner();

这是在一个static方法中,前面要描述内部类,肯定要外部类.内部类名  这样,然后后面  new对象就要用这个语法,我们前面说过一定要通过外部类的   对象     才能建立内部类的对象,所以要用    外部类对象  dn  然后再.new   +   内部类()。  注意这里  不用再  外部类.内部类()。

内部类可以实现某个接口,然后向上转型

一般的类的访问权限只能是public和default的package范围的嘛,但  内部类可以是private,protected的。再结合  接口实现和转型,可以生成更高效的代码。

方法内和作用域内的内部类

方法内的内部类例子:

//: innerclasses/Parcel5.java
// Nesting a class within a method.
public class Parcel5 {public Destination destination(String s) {class PDestination implements Destination {private String label;private PDestination(String whereTo) {label = whereTo;}public String readLabel() { return label; }}return new PDestination(s);}public static void main(String[] args) {Parcel5 p = new Parcel5();Destination d = p.destination("Tasmania");}
} ///:

还有贴一个笔记:

还有在作用域中  使用内部类的例子:

//: innerclasses/Parcel6.java
// Nesting a class within a scope.
public class Parcel6 {private void internalTracking(boolean b) {if(b) {class TrackingSlip {private String id;TrackingSlip(String s) {id = s;}String getSlip() { return id; }}TrackingSlip ts = new TrackingSlip("slip");String s = ts.getSlip();}// Can’t use it here! Out of scope://! TrackingSlip ts = new TrackingSlip("x");
    }public void track() { internalTracking(true); }public static void main(String[] args) {Parcel6 p = new Parcel6();p.track();}
} ///:

注意:  方法内部类和块中的内部类,可以任意访问外部类的类变量,但方法中的变量的话(比如方法内部类),就方法中的参数的话,一定要是final才能访问!!这个和下面讲的  匿名类 是一样的。

匿名内部类

下面的例子是一个实现了Contents接口的匿名类,类的定义和return语句结合在了一起,注意后面还要有个分号:

public Contents contents() {return new Contents() { // Insert a class definitionprivate int i = 11;public int value() { return i; }}; // Semicolon required in this case
}

这是用默认的构造器来生成Contents,那么如果基类的构造器是需要参数的呢?

public Wrapping wrapping(int x) {// Base constructor call:return new Wrapping(x) { // Pass constructor argument.public int value() {return super.value() * 47;}}; // Semicolon required
}//: innerclasses/Wrapping.java
/**
*基类 Wrapping
*/
public class Wrapping {private int i;public Wrapping(int x) { i = x; }public int value() { return i; }} ///:

在 匿名类中  初始化一些类变量或者干点什么:

// Argument must be final to use inside
// anonymous inner class:
public Destination destination(final String dest) {return new Destination() {private String label = dest;public String readLabel() { return label; }};
}

如果你在匿名类里面,要用到一个外面的定义的对象,那么编译器要求这个参数的引用是final的

匿名类是没有构造器的,那么如果你想像  构造器一样,做一些复杂点的  初始化工作呢?可以用   实力初始化——instance initialization来实现:

public Destination destination(final String dest, final float price) {return new Destination() {private int cost;// Instance initialization for each object:
        {cost = Math.round(price);if(cost > 100)System.out.println("Over budget!");}private String label = dest;public String readLabel() { return label; }};
}

匿名类一般就是这样的语法来用的,要么是继承一个基类,像上面的  return new 基类();   要么就实现一个接口   return new 接口();

但只能是一个操作,即匿名类要么继承一个基类,要么实现一个接口。

嵌套类(nested classes)

如果不需要内部类对象和外部类对象有联系的话,可以把内部类声明为static——这通常被称为是嵌套类。  我们知道,普通的内部类会偷偷抓个  外部类对象的引用,而嵌套类nested classes就不是这样了,当一个内部类被声明为static时,意味着:

  1. 要创建内部类的对象,不需要外部类的对象。
  2. 不能从内部类的对象中访问非static的外部类对象。

嵌套类和普通类还有个区别是,普通类的字段和方法只能放在外部层次上,所以普通内部类中不能有static字段和static数据,也不能包含嵌套类。  但是!!!嵌套类可以包含所有这些东西!!

所以内部的static类也就是嵌套类  有点像是一个static的方法。

interface里面的类

interface里面的东西,会自动变成public static,所以把嵌套类放在接口中,其实是不违背规则的!    甚至可以在内部嵌套类中实现外部的接口,看看例子:

public interface ClassInInterface {void howdy();class Test implements ClassInInterface {public void howdy() {System.out.println("Howdy!");}public static void main(String[] args) {new Test().howdy();}}
}

书上说,就很方便喔,如果你有些公共的代码,想所有的实现这个接口的类都共用,那么就可以这样   在j接口中放个嵌套类喔~

多层内部类中访问外部类成员

一个内部类不管在里面多少层,都可以访问它外部类的成员,哪怕是private的东西。

class MNA {private void f() {}class A {private void g() {}public class B {void h() {g();f();}}}
}public class MultiNestingAccess {public static void main(String[] args) {MNA mna = new MNA();MNA.A mnaa = mna.new A();MNA.A.B mnaab = mnaa.new B();mnaab.h();}
} ///:~

 内部类的继承

我们知道,就一个内部类的对象,一定是要偷偷抓住外部类的对象的引用嘛,那么继承了  内部类的子类要怎么操作呢?  有个特别的语法:

就如果一个类继承了一个内部类,那么原本的无参构造器不能用,你需要:
1.构造器传一个 外部类的 对象
2.在构造方法中第一句写 enclosingClassReference.super();

看个例子:

//: innerclasses/InheritInner.java
// Inheriting an inner class.
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);}
} ///:~

内部类可以被重写吗??

想这么一个情况,如果有个内部类,它继承了它的外部类,然后重新定义它自己(内部类),会发生怎样的事情呢?但其实并没卵用。。看个例子

//: innerclasses/BigEgg.java
// An inner class cannot be overriden like a method.
import static net.mindview.util.Print.*;
class Egg {private Yolk y;protected class Yolk {public Yolk() { print("Egg.Yolk()"); }}public Egg() {print("New Egg()");y = new Yolk();}
}public class BigEgg extends Egg {public class Yolk {public Yolk() { print("BigEgg.Yolk()"); }}    public static void main(String[] args) {new BigEgg();}
}
/* Output:
New Egg()
Egg.Yolk()
*///:~

原本的父类Egg里面有个内部类Yolk。

然后BigEgg继承Egg并又定义了一个Yolk类。似乎是重写了内部类。

你可能认为,既然创建了BigEgg这样的对象,那么所使用的应该是覆盖后的Yolk版本,但输出并不是这样。

这个例子说明,当继承了某个外围类的时候,内部类并没有什么神奇的变化。这两个内部类是完全独立的实体,各自在自己的命名空间中 。

当然我们也可以明确地继承某个内部类,看例子:

//: innerclasses/BigEgg2.java
// Proper inheritance of an inner class.
import static net.mindview.util.Print.*;
class Egg2 {protected class Yolk {public Yolk() { print("Egg2.Yolk()"); }public void f() { print("Egg2.Yolk.f()");}}private Yolk y = new Yolk();public Egg2() { print("New Egg2()"); }public void insertYolk(Yolk yy) { y = yy; }public void g() { y.f(); }
}public class BigEgg2 extends Egg2 {public class Yolk extends Egg2.Yolk {    //这里继承了内部类,但 构造方法没有显式地指出  Egg2对象的引用,我想是因为  这个类是BigEgg2的内部类,然后肯定有BigEgg2对象的引用吧,而这个                           //BigEgg2又是Egg2的子类,意味着  BigEgg2对象里面相当于有这个Egg2基类对象,所以就相当于有这个引用了吧……public Yolk() { print("BigEgg2.Yolk()"); }public void f() { print("BigEgg2.Yolk.f()"); }}public BigEgg2() { insertYolk(new Yolk()); }public static void main(String[] args) {Egg2 e2 = new BigEgg2();e2.g();}
}
/* Output:
Egg2.Yolk()
New Egg2()
Egg2.Yolk()
BigEgg2.Yolk()
BigEgg2.Yolk.f()
*///:~

这个输出有点绕,上一个我看了半天的分析笔记图片:

 关于标识符

直接上图吧哈哈哈:

转载于:https://www.cnblogs.com/wangshen31/p/10292695.html

内部类的小总结(语法和用法方面)相关推荐

  1. 【微信小程序】零基础学 | 小程序语法

    在前面的章节中讲过WXML用于描述页面的结构.WXS用于结合WXML构建出页面的结构.WXSS用于描述页面的样式,它们三者都有特定的语法.其中,WXSS与CSS相差不大,所以就不单独列出了.本章主要讲 ...

  2. 装饰器的定义、语法糖用法及示例代码

    1. 装饰器的定义 就是给已有函数增加额外功能的函数,它本质上就是一个闭包函数. 装饰器的功能特点: 不修改已有函数的源代码 不修改已有函数的调用方式 给已有函数增加额外的功能 2. 装饰器的示例代码 ...

  3. C++ I/O语法及其用法

    C++ I/O语法及其用法 构造器 bad clear close eof fail fill flags flush gcount get getline good ignore open peek ...

  4. c语言编程小技巧-if空语句用法

    c语言编程小技巧-if空语句用法 关于if语句其实我们在进行c语言编程的时候用的很多,对于if语句其实有一些小技巧可以帮助我们进行一些更简单的编程 一个小技巧就是我们可以设置条件的对立面来简化我们的编 ...

  5. 微信小程序学习5:小程序语法-事件绑定之给事件传递参数

    微信小程序学习5:小程序语法-事件绑定之给事件传递参数 前面一讲是关于事件绑定的,下面对事件绑定进行补充. 在用户触发事件,比如点击按钮时,我们往往要传递一下参数用来识别是那个按钮,因为一个界面往往不 ...

  6. 微信小程序学习4:小程序语法 - 事件绑定

    微信小程序学习4:小程序语法 - 事件绑定 事件绑定最简单的例子是,你设置一个按钮为可触发的,触发条件可以是点击,按压,长按等等.当然,如果你仅仅是设置了触发事件,而没有创建回调函数,是不会产生什么效 ...

  7. 微信小程序学习3:小程序语法-数据绑定

    微信小程序学习3:小程序语法-数据绑定 文章目录 微信小程序学习3:小程序语法-数据绑定 例子 可以认为是声明变量,只不过小程序的变量要在规定位置声明. 官方文档https://developers. ...

  8. 微信小程序开发学习笔记004--微信小程序语法结构

    今天讲微信小程序的语法结构 技术交流QQ群:170933152 数据绑定:把数据声明后显示在页面上 渲染:条件渲染,循环渲染 模板:某个小需求,模块封装成模板 事件:点击一个按钮触发一个事件,发送一个 ...

  9. Ningx实用小技巧——rewrite重写用法讲解

    一.引言 上一节讲解了location对于不同的URL进行不同的处理,那么这个rewrite也是负责对URL进行解析,然后通过一系列的判断,最后重写到不同的位置. 举一个小小的例子,比如我们查看Ngi ...

最新文章

  1. linux 查找目录或文件详解
  2. 智能车技术与实践_ROS入门
  3. 成功的前提,35岁前必须做好的十件事
  4. Java ObjectOutputStream writeInt()方法及示例
  5. vue computed 中操作DOM和给对象添加属性遇到的问题
  6. 制作日历组件,点击出来一个弹窗
  7. 西门子s7-200smart——2.cpu选型
  8. slf4j、log4j日志级别与配置
  9. 神经网络控制系统的特点,神经网络控制的优点
  10. 用微信网页版阅读文章
  11. 色彩校正中的Gamma(人眼亮度感应的非线性)
  12. springboot整合elasticsearch5.x以及IK分词器做全文检索
  13. ORB-SLAM2学习笔记——BundleAdjustment函数
  14. 给个华为服务器账号和密码忘了怎么办啊,华为帐号密码忘了怎么办?华为帐号找回密码教程...
  15. 一年级课程表(4月18日-4月22日)
  16. Arthas——热替换
  17. Android 11 新特性和API兼容
  18. Ubuntu 设置合上笔记本盖子不休眠的方法
  19. zxing生成带logo的二维码
  20. 【素描黑白】精致的IU手绘素描源码文件一键领取哦~

热门文章

  1. 年薪十万的王者荣耀,LOL游戏模型师的工作是这样的|附50G资料
  2. 车速与档位匹配关系_档位与速度匹配法则 每个档位的速度范围
  3. SOTIF预期功能安全分析方法
  4. Tensorflow高级API的进阶--利用tf.contrib.learn建立输入函数
  5. 图像处理(二十四)Gradient Domain High Dynamic Range Compression学习笔记
  6. 用别的表格中数据进行计算机,tusimpleBI 做的图表,别的电脑可以打开吗?
  7. java 投票算法_摩尔投票算法 - woshixin的个人空间 - OSCHINA - 中文开源技术交流社区...
  8. c# 计算空格宽度像素_分享计算机视觉之图像处理Python之opencv
  9. CVE-2019-0708漏洞补丁KB4499175
  10. 最后一周,如何高效率的备考软考信息安全工程师?