Java的內部類之成員內部類

內容取自http://www.cnblogs.com/yasepix/p/5776425.html

Java內部類的作用

推薦一、定義

放在一個類的內部的類我們就叫內部類。
二、作用
1.內部類可以很好的實現隱藏
一般的非內部類,是不允許有private與protected權限的,但內部類可以
2.內部類擁有外圍類的所有元素的訪問權限
3.可是實現多重繼承
4.可以避免修改接口而實現同一個類中兩種同名方法的調用。

三、例子

1.實現隱藏

平時我們對類的訪問權限,都是通過類前面的訪問修飾符來限制的,一般的非內部類,是不允許有private與protected權限的,但內部類可以,所以我們能通過內部類來隱藏我們的信息??梢钥聪旅娴睦?/p>

接口

package insidecategory;
public interface Incrementable
{
voidincrement();
}


具體類

package insidecategory;
public class Example {
            privateclass InsideClass implements InterfaceTest
             {
                          publicvoid test()
                           {
                                  System.out.println("這是一個測試");
                           }
             }
              publicInterfaceTest getIn()
             {
                     returnnew InsideClass();
             }
}

上面加粗的部分是內部類,訪問修飾符是private

客戶端程序

package insidecategory;

public class TestExample {
               public staticvoid main(String args[])
               {
                     Examplea=new Example();
                     InterfaceTest a1=a.getIn();
                     a1.test();
               }
}

加粗的那部分就是客戶端調用的代碼,從這段代碼里面我只知道Example的
getIn()方法能返回一個InterfaceTest實例但我并不知道這個實例是這么實現的。而且由于InsideClass是private的,所以我們如果不看代碼的話根本看不到這個具體類的名字,所以說它可以很好的實現隱藏。

2.可以無條件地訪問外圍類的所有元素

package insidecategory;
  public class TagBean {
      private Stringname="liutao";
          private classInTest
           {
                   publicInTest()
                   {
                       System.out.println(name);
                   }
           }
           public voidtest()
           {
                      newInTest();
           }
           public staticvoid main(String args[])
           {
                  TagBeanbb=new TagBean();
                  bb.test();
           }
}

看上面加粗部分,name這個變量是在TagBean里面定義的私有變量。這個變量在內部類中可以無條件地訪問System.out.println(name);

3.可以實現多重繼承

這個特點非常重要,個人認為它是內部類存在的最大理由之一。正是由于他的存在使得Java的繼承機制更加完善。大家都知道Java只能繼承一個類,它的多重繼承在我們沒有學習內部類之前是用接口來實現的。但使用接口有時候有很多不方便的地方。比如我們實現一個接口就必須實現它里面的所有方法。而有了內部類就不一樣了。它可以使我們的類繼承多個具體類或抽象類。大家看下面的例子。

類一

packageinsidecategory;
public class Example1 {
           public Stringname()
           {
                  return"liutao";
           }
}

類二

package insidecategory;
public class Example2 {
          public intage()
          {
             return25;
          }
}


類三


packageinsidecategory;
public class MainExample
{
            private classtest1 extends Example1
            {
                   publicString name()
                   {
                       returnsuper.name();
                   }
            }
            privateclass test2 extends Example2
             {
                   publicint age()
                   {
                        returnsuper.age();
                   }
             }
            public Stringname()
             {
                  return newtest1().name();
             }
             public intage()
             {
                   returnnew test2().age();
             }
             public staticvoid main(String args[])
             {
                   MainExample mi=new MainExample();
                   System.out.println("姓名:"+mi.name());
                   System.out.println("年齡:"+mi.age());
            }
}

大家注意看類三,里面分別實現了兩個內部類test1,和test2,test1類又繼承了Example1,test2繼承了Example2,這樣我們的類三MainExample就擁有了Example1和Example2的方法和屬性,也就間接地實現了多繼承。

四、避免修改接口而實現同一個類中兩種同名方法的調用。

大家假想一下如果,你的類要繼承一個類,還要實現一個接口,可是你發覺你繼承的類和接口里面有兩個同名的方法怎么辦?你怎么區分它們??這就需要我們的內部類了??聪旅娴拇a

接口

packageinsidecategory;
public interface Incrementable
{
             voidincrement();
}
類MyIncrement

packageinsidecategory;
 public class MyIncrement {
        public voidincrement()
        {
             System.out.println("Other increment()");
        }
       static voidf(MyIncrement f)
        {
              f.increment();
        }
}

大家看上面加黑的部分,兩個方法都是一樣的。在看下面這個類要繼承這兩個類
如果不用內部類

package insidecategory;

public class Callee2 extends MyIncrement implementsIncrementable
{
             public void increment()
{
//代碼
}
}

想問一下大家increment()這個方法是屬于覆蓋MyIncrement這里的方法呢?還是Incrementable這里的方法。我怎么能調到MyIncrement這里的方法?顯然這是不好區分的。而我們如果用內部類就很好解決這一問題了。看下面代碼

package insidecategory;
public class Callee2 extends MyIncrement
{
    private inti=0;
    private voidincrement()
     {
                 i++;
                 System.out.println(i);
     }
    private classClosure implements Incrementable
    {
                 publicvoid increment()
                 {
                      System.out.println(“接口中的increment()方法”);
                 }
    }
    IncrementablegetCallbackReference()
     {
                 return newClosure();
     }
}

我們可以用內部類來實現接口,這樣就不會與外圍類的方法沖突了
接下來再介紹一下成員內部類實例化方式

//定義一個MemberInner類
package com.qf.demo9;
public class MemeberInner {

    private String name ="太和殿";
    private int age = 300;
    
    public void sleep(){
        System.out.println("一片寂靜");
    }
    // 成員內部類
    // 可以用四種訪問權限修飾符修飾
       class Inner{
        // 成員內部類中 不允許直接用靜態的屬性和方法
         // 但是屬性可以 用 final static 修飾變成常量
        public final static String sex = "不詳";
        private double money;
        
        public  void eat(){
            // 內部類中可以使用外部類中的屬性和方法  包括私有的
            System.out.println(age);
            sleep();
            System.out.println(name);
            System.out.println("吃");
        }   
    }   
}

Main方法

package com.qf.demo9;

import com.qf.demo9.MemeberInner2.Inner;

//import com.qf.demo9.MemeberInner.Inner;

/**
 * 內部類:  一個類里面再定義一個類 , 里面的類叫做  內部類
 *       外面的類  外部類,宿主類
 * 
 * 內部類 : 通常是為了幫助管理外部類事物的
 * 
 * 內部類的分類:
 *      成員內部類: 相當于外部類的一個成員屬性 或者成員方法
 *      靜態內部類
 *      局部內部類
 *      匿名內部類
 *  
 */
public class Test {

    public static void main(String[] args) {
        //實例化外部類對象
        MemeberInner memeberInner = new MemeberInner();
        // 先要創建外部類對象  通過外部類對象  創建內部類對象
        //  外部類對象.new  內部類();
        MemeberInner.Inner inner = memeberInner.new Inner();
        inner.eat();        
        MemeberInner2 memeberInner2 = new MemeberInner2();
        Inner inner2 = memeberInner2.new  Inner();
        inner2.sleep();
        
    }
}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,740評論 18 399
  • 本文出自 Eddy Wiki ,轉載請注明出處:http://eddy.wiki/interview-java.h...
    eddy_wiki閱讀 1,224評論 0 5
  • Java 內部類 分四種:成員內部類、局部內部類、靜態內部類和匿名內部類。 1、成員內部類: 即作為外部類的一個成...
    ikaroskun閱讀 1,246評論 0 13
  • 面向對象主要針對面向過程。 面向過程的基本單元是函數。 什么是對象:EVERYTHING IS OBJECT(萬物...
    sinpi閱讀 1,082評論 0 4
  • 鳥語花香 斑駁的老墻 還有布谷鳥的歌唱 母親的溫柔 爺爺的背影 簇新的葡萄架 閃閃發亮
    雪小凝閱讀 338評論 4 4