six面向对象xia

6.4 final关键字

  • 修饰类、变量和方法,
  • 有点类似C#里的 sealed关键字,
    • 表示它修饰的类、方法和变量不可改变。

  • final可修饰成员变量(包括类变量和实例变量),修饰局部变量、形参。
  • 有的书上介绍说final修饰的变量不能被赋值,错误!
  • final修饰的变量不可被改变,一旦获得初始值,
    • 该变量就不能被重新赋值。

  • final变量获得初始值之后不能被重新赋值,
    • 因此final修饰成员变量和修饰局部变量时有一定的不同。

6.4.1 final成员变量

  • 类初始化时,系统为该类的类变量分配内存并分配默认值:
    • 创建对象时,系统为该对象的实例变量分配内存,并分配默认值
  • 执行静态初始化块时可以对类变量赋初始值:
    • 当执行普通初始化块、构造器时可对实例变量赋初始值。
  • 成员变量的初始值可在定义该变量时指定默认值,
    • 也可以在初始化块、构造器中指定初始值

好多没写

6.7内部类

  • 把一个类放在另一个类的内部定义,
    • 内部类(也叫嵌套类),
    • 外部类(宿主类)。
    • JDK1.1引入内部类,
  • 内部类有如下作用。

  • 把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。
  • Cowley类只有在Cow类里才有效,
    • 离开Cow类没意义
    • 把Cowley定义成Cow的内部类,不允许其他类访问Cowley

  • 内部类成员可直接访问外部类的私有数据
    • 内部类被当成外部类成员
      • 同一个类的成员之间可互访
  • 外部类不能访问内部类实现细节
    • 如内部类的成员变量

  • 匿名内部类用于创建那些仅需要一次使用的类。
  • 对于前面介绍的命令模式,当需要传入个Command对象时,重新专门定义 Print Command和 Addcommand两个实现类可能没有意义,
  • 因为这两个实现类可能仅需要使用一次。
  • 这种情况下,使用匿名内部类将更方便。

  • 定义内部类与定义外部类的语法相同,内
    • 部类除了需要定义在其他类里面之外,还存在如下区别。
  • 内部类比外部类可多用三个修饰符:
    • private、 protected、 static
    • 外部类不可以使用这三个修饰符
  • 非静态内部类不能有静态成员

6.7.1非静态內部类

  • 只要把一个类放在另一个类内部定义即可。
    • “类内部”包括类中的任何位置,
    • 方法中也可定义内部类(称局部内部类)。

  • 大部分内部类都被作为成员内部类定义,
    • 而不局部内部类。
  • 成员内部类与
    • 成员变量、方法、构造器和初始化块相似的类成员;
    • 局部内部类和匿名内部类不是类成员

  • 成员内部类分:
    • 静态内部类和非静态内部类,
    • static修饰的成员内部类是静态内部类,
    • 没有用 static修饰的成员内部类是非静态内部类。

  • 同一个Java源文件里定义多个类,那不是内部类
    • 是两个互相独立的类。

  • 内部类作为其外部类的成员,
    • 可用任意访问控制符如 private、 protected和 public

在这里插入图片描述

  • Cow类里定义Cowleg非静态内部类,
  • Cowley类的实例方法中访问Cow的private访问权限的实例变量。

在这里插入图片描述

  • 粗体字是一个普通类定义,
    • 这个类定义放在了另一个类的内部,它就成一个内部类,
    • 可用private来修饰这个类
  • Cow里含test方法
    • 创建了CowLeg对象,并调该对象的info方法
    • 在外部类里用非静态内部类时,与平时使用普通类并没区别。

  • 编译
  • Cow.class,Cow$cowLeg.class,后者是内部类 Cowleg的 class文件,
  • 成员内部类(包括静态内部类、非静态内部类)的class文件总是这种形式: Outer Class Sinnerclass class

  • 非静态内部类里可直接访问外部类的private成员,
  • 1号粗体代码行
    • Cowleg类的方法内直接访问其外部类的private实例变量。
    • 非静态内部类对象里,保存一个它所寄生的外部类对象的引用
    • (当调非静态内部类的实例方法时,须有一个非静态内部类实例,
      • 非静态内部类实例必须寄生在外部类实例)
  • 图6.6显示程序运行时的内存示意图。

在这里插入图片描述

  • 非静态内部类的方法访问某变量时,
    • 优先在该方法内查找是否存在该名字的局部变量,
      • 存在就使用该变量;
  • 不存在,则到该方法所在的内部类中査找是否存在该名字的成员变量
  • 如果存在则使用该成员变量;
    • 不存在,则到该内部类所在的外部类中查找是否存在该名字的成员变量,如果存在则使用该成员变量;
  • 依然不存在,编译错误:提示找不到该变量。

  • 如果外部类成员变量、内部类成员变量与内部类里方法的局部变量同名,
  • 可用this
  • 外部类类名.this来区分

在这里插入图片描述

  • 非静态内部类的成员只在非静态内部类范围内是可知的,
    • 不能被外部类直接使用
  • 如果外部类要访问非静态内部类成员
    • 则须显式创建非静态内部类对象来调用访问其实例成员

在这里插入图片描述

  • 粗体字试图在外部类方法里访问非静态内部类的实例变量,这将引起编译错误。
  • 外部类不允许访问非静态内部类的实例成员还有一个原因,
    • main的1号代码创建了一个外部类对象,并调用外部类对象的 accesslnnerpropo
    • 此时非静态内部类对象不存在,如果允许accessinnerprop()访问非静态内部类对象,肯定引起错

在这里插入图片描述

  • 外部类的静态方法、静态代码块不能访问非静态内部类,
    • 不能用非静态内部类定义变量、创建实例

在这里插入图片描述

  • 不许非静态内部类里定义静态成员。

在这里插入图片描述

  • 非静态内部类不能有静态方法、静态成员变量、静态初始化块,
    • 上面三个静态声明都错

在这里插入图片描述

6.7.2 静态内部类

  • 用static修饰一个内部类,则这个内部类就属于外部类本身,不属于外部类的某个对象
  • 因此static修饰的内部类称类内部类,
    • 也称为静态内部类。

在这里插入图片描述

  • 静态内部类可含静态成员,非静态成员。
  • 静态内部类不能访问外部类的实例成员,
    • 只能访问外部类的类成员。
  • 静态内部类的实例方法也不能访问外部类的实例成员,
    • 只能访问外部类的静态成员。

在这里插入图片描述

  • 粗体字代码行定义了一个静态成员变量,
    • 这个静态成员变量处于静态内部类中。
  • Staticlnnerclass类里定义了一个 accessouterprop方法,
    • 这是个实例方法,
    • 但不能访问外部类的prop1,因为这是实例变量;
    • 但可访问prop2,因为它是静态成员变量。

在这里插入图片描述

here!!!

发布了558 篇原创文章 · 获赞 295 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/zhoutianzi12/article/details/105408802