黑马程序员————类的第五个成员内部类

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

  我们在通过java语言描绘事物的时候,会遇到事物里面还有事物,而里面的事物还会用到外面事物的一些属性。就好像看似单一的物体实则里面还有很多看似独立的分支,但却又要用到这个物体的一些属性与方法。就好像大自然里面的万物,每个看似独立却又息息相关。我们当然可以把其中的生物个体单独定义封装,但为了表现程序语言对现实世界的描述力,还是把他放到大自然里面更好,这样如果要用到大自然的一些元素就可以直接条用了。而不是在通过创建对象来调用。

  内部类大致分为三类:成员内部类,局部内部类,匿名内部类。先说说成员内部类,成员内部类可以访问外部类的成员包括私有的;而自身也是通过创建对象被访问,如果是外部其他类要访问,则通过创建追踪对象(方便理解,自创的词)。

class A {
        private int a=3;
        class B{//成员内部类
            void function(){
                System.out.println(a);//调用私有的外部成员变量
            }
        }
}
  
  
class C{
    public static void main(String arg[]){
        A.B aa =new A().new B();//创建所属成员内部类
        aa.function();
    }
}

  

为什么叫创建追踪对象呢,因为想要访问非静态的成员就必须得创建对象,如果一些外部类的内部类重名,系统将不知道是指的哪个外部类里面的内部类,所以在内部类前面必须加上其外部类名。这样才能创建出你想要的那个内部类,格式:外部类名.内部类名  变量名 = new 外部类名().new 内部类名();

值得注意的是当内部类访问外部成员时,如果内部类成员变量与外部类成员变量重名,甚至还与内部局部变量重名,那么其调用原则为就近原则。

class A{
          private  int a =3;//成员变量
          class B{
                    int a=4;//内部类成员变量
                    void  function(){
                    int a =5;//内部类局部变量            
                    System.out,println(a);
              }
 
     }   
 
}

  如果出现这种情况还要调用外部类的成员变量的话,就需要在a前面加上外部类引用。外部类名.this.a,正因为如此,内部类才能访问外部类成员的,因为你不写的时候是隐含了外部类引用的。

因为成员外部类属于类的成员,所以他能被成员修饰符private,static等修饰。被private修饰的内部类为封装内部类,由此我们也可以得出结论:类是能被private修饰的。被static修饰的内部类为静态内部类,同样也具备静态的性质。只能访问外部类静态成员,如果是调用静态内部类非静态成员时还是需要创建对象的,格式为

new 外部类名.内部类名().方法名;

  调用静态内部类中静态成员时,无需创建对象

外部类名.内部类名.方法名();

  

第二种:局部内部类                    

       因为内部类能定义在外部类中任何位置,所以就有了局部内部类。因为是定义在方法中,所以不能被成员修饰符所修饰,但是可以访问到外部类成员,因为隐含了外部类的引用。对一般局部变量也访问不了,如果要访问,必须经final修饰。因为是局部变量,所以即使经final修饰成为常量也依然能起到作为变量的作用,只有当方法调用是,局部变量进栈,但随后会消失,再次调用方法,有重新获得新的内存空间,正因如此也无法对其进行累加或累减运算。

class A{
            viod  aa(){
                         final int a =3;//经final修饰后的局部变量
                         class B{
 
                                    void bb(){
                                                  System.out.println(a);
                   }            
            }
 
      }
}

  有一点需要注意的是。当调用A类aa方法时,B类中bb方法是不能调用的,必要要创建对象。

第三种:匿名内部类

匿名内部类的作用就是简化写法,但前提是必要要有继承或实现。

例如内部类需要继承一个抽象类,再通过调用内部类实现其中方法一般写法是这样

abstract class Abs{
        
         abstract  void show();
}
 
class A{
 
           int  x=3;
           class B extends Abs{//第一步:继承抽象类
 
                 void show(){//第二步:重写父类方法
                               System.out.println(x);
                    
             }
 
     }
          public   void  function(){
                            
                      new A.B().show();//第三步:创建对象
              }
 
}

  上面用了三不才实现的通过匿名内部类一步就可以搞定

new Abs(){//因为没有名字所有直接创建父类
     void show(){//因为父类中有抽象方法,所以重写得到自己想要的方法
               System.out.println(x);
   }
}

  需要注意的是,定义子类的方法最好不要超过三个,一个两个最好。我也是初学者,哪里有问题还望指正。

 

原文地址:https://www.cnblogs.com/huangjiawei/p/4696758.html