黑马程序员-Java基础,非静态内部类

    定义内部类非常简单,只要把一个类放在另一个类内部定义即可。此处的“类内部”包括类中的任何位置,甚至在方法中也可以定义内部类(方法里定义的内部类被称为局部内部类)。内部类定义语法格式如下:

1 public class OuterClass{
2 
3 //此处可定义内部类
4 
5 }

 

    大部分时候,内部类都被作为成员内部类定义,而不是作为局部内部类。成员内部类是一种与属性、方法、构造器和初始化块相似的类成员;局部内部类和匿名内部类则不是类成员。
    成员内部类分为两种:静态内部类和非静态内部类,使用static修饰的成员内部类是静态内部类,没有使用static修饰的成员内部类是非静态内部类。
    前面经常看到同一个Java源文件里定义了多个类,那种情况不是内部类,它们依然是两个互相独立的类。例如下面程序:
    //下面A、B两个空类互相独立,没有谁是谁的内部类。
class A{}
public class B{}
    上面两个类定义虽然写在了同一个源文件中,但它们相互独立,没有谁是谁的内部类这种关系。内部类一定是放在另一个类的类体部分(也就是类名后的花括号部分)定义。
    因为内部类作为其外部类的成员,因此可以使用任意访问控制符如private、protected和public等修饰。
    下面程序在King类里定义了一个KingBlack的非静态内部类,并在KingBlack类的实例方法中直接访问King的private访问权限的实例属性。
程序清单:simples/src/com/king/king.java
 
 1 package com.king;
 2 
 3  
 4 
 5 public class King {
 6 
 7 private double weight;
 8 
 9 //外部类的两个重载的构造器
10 
11 public King(){}
12 
13 public King(double weight){
14 
15 this.weight=weight;
16 
17 }
18 
19 //定义一个非静态内部类
20 
21 private class KingBlack{
22 
23 private double length;
24 
25 private String color;
26 
27 //非静态内部类的两个重载的构造器
28 
29 public KingBlack(){}
30 
31 public KingBlack(double length,String color){
32 
33 this.color=color;
34 
35 this.length=length;
36 
37 }
38 
39 public void setLength(double length){
40 
41 this.length=length;
42 
43 }
44 
45 public double getLength(){
46 
47 return this.length;
48 
49 }
50 
51 public void setColor(String color){
52 
53 this.color=color;
54 
55 }
56 
57 public String getColor(){
58 
59 return this.color;
60 
61 }
62 
63 //非静态内部类的实例方法
64 
65 public void info(){
66 
67 System.out.println("当前颜色:"+color+",长度:"+length);
68 
69 //直接访问外部类的private属性:weight
70 
71 System.out.println("当前重量为:"+weight);
72 
73 }
74 
75 }
76 
77 //定义实例方法,创建内部类对象,调用内部类方法
78 
79 public void test(){
80 
81 KingBlack kb=new KingBlack(170, "黑色");
82 
83 kb.info();
84 
85 }
86 
87 public static void main(String[] args) {
88 
89 King king=new King(65);
90 
91 king.test();
92 
93 }
94 
95 }

 

 
    上面的程序中斜体部分是一个普通的内部类,但因为把这个类定义放在了另一个类的内部,所以它就成了一个内部类,可以使用private修饰符来修饰这个类。
    外部类King里包含了一个test方法,该发放里创建了一个KingBlack对象,并调用该对象的info方法。读者不难发现,在外部类里使用非静态内部类时,与平时使用不同类没有太大的区别。
    编译上面程序,看到在文件路径生成了两个class文件,一个是King.class,另一个是King$KingBlack.class,前者是外部类King的class文件,后者是内部类KingBlack的class文件。即成员内部类(包括静态内部类、非静态内部类)的class文件的这种形式:OuterClass$InnerClass.class。
    当在非静态内部类的方法内访问某个变量时,系统优先在该方法内查找是否存在该名字的局部变量,如果存在该名字的局部变量,就使用该变量;如果不存在,则到该方法所在的内部类中查找是否存在该名字的属性,如果存在则使用该属性,如果不存在,则到该内部类所在的外部类中查找是否存在该名字的属性,如果存在则使用该属性。如果依然不存在,系统将出现编译错误:提示找不到该变量。
    因此,如果外部类属性、内部类属性与内部类里方法的局部变量同名,则可通过使用this、外部类类名.this作为限定来区分。
 
posted @ 2014-01-03 23:36  code4a  阅读(151)  评论(0编辑  收藏  举报