黑馬程序員-面向對象 多態,內部類

------- android培訓java培訓、期待與您交流! ----------

18,多態

     多態:可以理解爲事物存在的多種體現形態。

      1,多態的體現。

             父類的引用指向了自己子類對象。

            父類的引用也可以接收自己的子類的對象。

      2,多態的前提。

            必須是類與類之間有關係,要麼繼承,要麼實現。

            存在覆蓋

      3,多態的好處。

              多態的出現大大提高了程序的擴展性。

       4,弊端

               提高了擴展性,但是隻能使用父類的引用訪問父類中的成員。

      5,多態的應用。

    轉型:

             Cat類中有一個特有的方法CatchMouse();

             Animal a=new Cat();//類型提升。向上轉型

              a.eat();

              //如果想要調用子類特有的方法時,如何操作?

             //強制將父類的引用。轉成子類類型.向下轉型。

             //我們能轉換的是父類引用指向了自己的子類對象時,該應用可以被提升,也可以被強制轉換。

              //多態自始自終都是子類對象在做着變化。

              Car c=(Car)a;

              c.catchMouse();

                    判斷某一類型 引用指向的對象到底符合什麼類型的時候

                  if(a instanceof Cat){

                             Cat c=(Cat)a;

                             c.catchMouse();

                      }

6,成員特點。

        在編譯時期:參閱引用型變量所屬的類中是否有調用德爾方法。如果有,編譯通過,沒有編譯失敗。

         在運行時期:參閱對象所屬的類中是否有調用的方法。

         簡單總結就是:成員函數在多態調用時,編譯看左邊,運行看右邊。

       在多態中,成員變量的特點:(非靜態的)

           無論編譯和運行,都參考左邊。(引用型變量所屬的類)

             父類有一個變量num,子類有一個變量num

                 Fu f=new Zi();

                   f.num是父類中的num;

              Zi zi=new ZI();

                 zi.num是子類中的num;

       在多態中靜態成員函數的特點:

           無論編譯和運行,都參考左邊。

                  類加載到內存,靜態就存在了,不需要對象。

19,Object :是所有對象的直接或者間接父類,傳說的上帝。

          該類中定義的肯定是所有對象都具備的功能。

         Object 類中已經提供了對對象是否相同的比較方法。

         如果自定義類中也有比較相同的功能,沒有必要重新定義。

         如果沿襲父類中的功能,建立自己特有比較內容即可。這就是覆蓋。

        equals(); toString();

20,內部類

將一個類定義在另一個類的裏面,對裏面那個類就稱爲內部類(內置類,嵌套類)。

 內部類與外部類的訪問規則

         
/*
 * 內部類的訪問規則
 * 1,內部類可以直接訪問外部類中的成員,包括私有
 *     之所以可以直接訪問外部類的成員,是因爲內部類中持有了外部類的引用。外部類.this
 * 2,外部類要訪問內部類,必須建立內部類對象。
 */
public class InnerClassDemo {

	public static void main(String[] args) {
		// Outer o=new Outer();
		// o.method();
		// 直接訪問內部類的成員。
		Outer.Iner in = new Outer().new Iner();
		in.function();
	}
}

class Outer {
	private int x = 3;

	// 內部類可以私有化
	class Iner {
		int x = 4;

		public void function() {
			int x = 6;
			System.out.println("inner" + x);// 這裏打印6,內部有的不往外找了
			System.out.println("inner" + this.x);// 這裏打印4;
			System.out.println("inner" + Outer.this.x);// 這裏打印6
		}
	}

	public void method() {
		Iner i = new Iner();
		i.function();
	}
}


訪問格式:

1,當內部類定義在外部類的成員位置上,而且非私有的,可以再外部其他類中,可以直接建立內部類對象。

  格式:

         外部類.內部類名 變量名=外部類對象.內部類對象;

2,當內部類在成員位置上,就可以被成員修飾符所修飾。

       比如,private :將內部類在外部類中進行封裝。

            static :內部類就具備static 的特性。

            當內部類被static 修飾後,只能直接訪問外部類中的static成員了。出現了訪問權限、

           在外部其他類中,如何直接訪問static內部類的非靜態成員呢?

           new Outer.Inner().function();;

          在外部其他類中,如何直接訪問static內部類的靜態成員呢?

            Outer.Inner.function();

          注意:當內部類中定義了靜態成員,該內部類就必須是static的。

內部類定義規則。

      當描述事物時,事物的內部還有事物,該事物用內部類來描述。

          因爲內部事物在使用外部事物的內容。

      內部類只有定義在成員變量上的時候,才能被私有或者靜態所修飾,一般內部類是不會被公有修飾的。

21,匿名內部類

     在方法當中定義內部類

  
public class InnerClassDemo {
	public static void main(String[] args) {
         Outer o=new Outer();
         o.method(7);
         o.method(6);
	}
}
/*
 * 內部類定義在局部時
 * 1,不可以被成員修飾符修飾
 * 2,可以直接訪問外部類中的成員,因爲還持有外部類的引用。
 *       但是不可以訪問他所在的局部中的變量。只能訪問被final修飾的局部變量
 *
 */
class Outer {
	int x = 3;
  
	void method(final int a) {
	  final	int y=4;
		/**
		 * 此時不能被靜態私有修飾,因爲修飾符只能修飾成員,現在Inner在局部了,所以不能
		 * @author Administrator
		 */
		class Inner {
			/**
			 * 這裏也不能用static修飾
			 */
			void function() {
				System.out.println(Outer.this.x);
				System.out.println(y);//加final
				System.out.println(a);//加final
			}
		}
		new Inner().function();
	}
}

匿名內部類:

        1,匿名內部類其實就是內部類的簡寫格式。

        2,定義匿名內部類的前提;

                內部類必須是繼承一個類或者接口。
        3,   匿名內部類的格式,new 父類或者接口(){定義子類的內容}

        4 ,     其實匿名內部類就是一個匿名子類對象。而且這個對象有點胖,也可以理解爲帶內容的對象。

         5,匿名內部類中定義的方法最好不要超過三個。

public class InnerClassDemo {
	public static void main(String[] args) {
		new Outer().function();
	}
}

class Outer {
	int x = 3;

	/*
	 * class Inner extends AbsDemo{ void show(){ System.out.println("show:"+x);
	 * } }
	 */
	// 對上面的代碼簡化
	public void function() {
		// new Inner().show();
		/*
		 * 整體是一個對象,是AbsDemo的一個子類對象,只有之類才能複寫方法。
		 */
		new AbsDemo() {// 匿名內部類

			@Override
			void show() {// 複寫方法
				// TODO Auto-generated method stub
				System.out.println("x:" + x);
			}

		}.show();
	}
}

abstract class AbsDemo {
	abstract void show();
}

基本小練習

 

public class InnerClassDemo {
	public static void main(String[] args) {
		// 類名. 肯定有靜態成員Test.function(),有一個靜態的方法。
		// .method;function 這個方法運算後的結果是一個對象,而是一個Inter對象
		// 只有Inter才能調用mthod方法。
		Test.function().method();

	}
}

interface Inter {
	void method();
}

class Test {
	// 補足代碼。通過匿名內部類
	/*
	 * static class Inner implements Inter{
	 * 
	 * @Override public void method() { // TODO Auto-generated method stub
	 * System.out.println("method run"); }
	 * 
	 * }
	 */
	static Inter function() {
		// return new Inner();
		return new Inter() {

			@Override
			public void method() {
				// TODO Auto-generated method stub
				System.out.println("method run");
			}

		};
	}

}

關於內部類的概述總結

內部類有兩種情況:
(1) 在類中定義一個類(私有內部類,靜態內部類)
(2) 在方法中定義一個類(局部內部類,匿名內部類)
 
1、私有內部類 —— 在方法之間定義的內部類,非靜態
      我們首先看看類中內部類的兩個特點:
      (1) 在外部類的作用範圍內可以任意創建內部類對象,即使內部類是私有的(私有內部類)。即內部類對包圍它的外部類可見。
例如 (實際上,內部類是可以設置爲public公開的,但一般我是當做成員變量設置爲private)
  1. //代碼1:內部類對外部類可見 
  2. class Outer{ 
  3.     //創建私有內部類對象 
  4.     public Inner in=new Inner(); 
  5.  
  6.     //私有內部類 
  7.     private class Inner{ 
  8.          ... 
  9.     } 
 
      (2) 在內部類中可以訪問其外部類的所有域,即使是私有域。即外部類對內部類可見。
例如
  1. //代碼2:外部類對內部類可見 
  2. //(內部類可以訪問外部類的所有成員變量和方法) 
  3. class Outer{ 
  4.     //外部類私有數據域 
  5.     private int data=0
  6.  
  7.     //內部類 
  8.     class Inner{ 
  9.         void print(){ 
  10.             //內部類訪問外部私有數據域 
  11.             System.out.println(data); 
  12.         } 
  13.     } 
  14.  
       
總結一下編譯器對類中內部類做的手腳吧:
(1)  在內部類中偷偷摸摸的創建了包可見構造器,從而使外部類獲得了創建權限。
(2)  在外部類中偷偷摸摸的創建了訪問私有變量的靜態方法,從而 使 內部類獲得了訪問權限。
這樣,類中定義的內部類無論私有,公有,靜態都可以被包圍它的外部類所訪問。
 
2、靜態內部類  ——  在方法間定義的內部類,靜態
    內部類也有靜態的區別,這就是靜態內部類,我們來看看代碼:
  1. package hr.test; 
  2. //代碼3:靜態內部類對外部變量的引用 
  3. public class Outer{ 
  4.     private static int i=0
  5.  
  6.     //創建靜態內部類對象 
  7.     public Inner in=new Inner(); 
  8.  
  9.     //靜態內部類 
  10.     private static class Inner{ 
  11.         public void print(){ 
  12.             System.out.println(i);   //如果i不是靜態變量,這裏將無法通過編譯 
  13.         } 
  14.     }  
    靜態內部類和私有內部類最大的區別在於,靜態內部類中無法引用到其外圍類的非靜態成員。

   是說靜態內部類無法得到其外圍類對象的引用,那麼自然也就無法訪問外圍類的非靜態成員了。因此,靜態內部類只能訪問其外圍類的靜態成員,除此之外與非靜態內部類沒有任何區別。
 
3、局部內部類 —— 在方法中定義的內部類
      方法內部類也有兩個特點
      (1)  方法中的內部類沒有訪問修飾符, 即方法內部類對包圍它的方法之外的任何東西都不可見。
      (2)  方法內部類只能夠訪問該方法中的局部變量,所以也叫局部內部類。而且這些局部變量一定要是final修飾的常量
例如
  1. class Outter{ 
  2.     public void outMethod(){ 
  3.         final int beep=0
  4.         class Inner{ 
  5.             //使用beep 
  6.         } 
  7.  
  8.         Inner in=new Inner(); 
  9.     } 
  10.  
 
內部類的特點總結
 
(1)  在方法間定義的非靜態內部類: 
         外圍類和內部類可互相訪問自己的私有成員。
         內部類中不能定義靜態成員變量。

(2) 在方法間定義的靜態內部類:
         只能訪問外部類的靜態成員。
 
(3) 在方法中定義的局部內部類:
         該內部類沒有任何的訪問控制權限
         外圍類看不見方法中的局部內部類的,但是局部內部類可以訪問外圍類的任何成員。
         方法體中可以訪問局部內部類,但是訪問語句必須在定義局部內部類之後。
         局部內部類只能訪問方法體中的常量,即用final修飾的成員。

(4) 在方法中定義的匿名內部類:
         沒有構造器,取而代之的是將構造器參數傳遞給超類構造器。



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章