1. 程式人生 > >Java 面向物件程式設計之介面內部類

Java 面向物件程式設計之介面內部類

介面,內部類,抽象類本質上也是類,是抽象的抽象類,這三種類有各自的特點。

1. 抽象類、 設計與實現的分開

  1. 抽象類:定義了抽象方法的類,不能例項化,只能被子類實現 , 用關鍵字abstract修飾。
  2. 抽象方法:只定義了方法體,沒有定義內容。
  3. 作用:為所有子類建立一個模板。
    抽象類具有具有以下的語法規則需要遵循:
      1、一個類中如果有抽象方法,則這個類必須是抽象類。
      2、抽象類中可以沒有抽象方法。
      3、抽象類是不能存在例項物件的,換句話說就是抽象類就是為了被繼承而存在的。
      4、一個子類如果繼承了抽象類,必須實現抽象類中定義的所有抽象方法。
      5、抽象類可以繼承抽象類,可以不重寫父類的方法。
abstract class Person{
    public abstract void study()    ;   //抽象方法
    public void eat(){
        System.out.println("吃的技能");
    }
}

簡單地說:萬物可歸類,類本身是對於客觀世界的抽象,在描述客觀世界的過程中 ,需要抽象出高度抽象的類,用來描述同類事物的共性,可以用abstract來修飾,抽象類有抽象方法,也有常規方法,方法是對於事物行為的描述,抽象方法對於同類事物的相同行為的描述,比如說,抽象類動物有抽象方法吃飯和睡覺,具體類貓也有吃飯和睡覺的行為,貓類實現抽象類動物類,繼承抽象方法吃飯和睡覺,這樣貓也就有了吃飯和睡覺的方法,通過重寫類實現貓的吃飯和睡覺的具體行為。
2.介面 規範和具體實現的分離

  1. 定義: 只包含有抽象方法和常量,通過 interface修飾,介面可以實現多繼承。
    常量用public static final 修飾,只有方法識別符號,沒有方法體。
  2. 作用:用來描述類有哪些行為,對內的一組行為的描述,介面不能例項化。
    介面是規範,定義了一組規則,在現實世界中,如果你是,,,,那麼你應該,,,,
    本質是契約,開發專案往往是面向介面程式設計。
  3. 定義一個介面
    在這裡插入圖片描述
    4.實現介面
    在這裡插入圖片描述
  • 介面和抽象類的比較
    在這裡插入圖片描述

1.語法層面上的區別

1)抽象類可以提供成員方法的實現細節,而介面中只能存在public abstract 方法;

2)抽象類中的成員變數可以是各種型別的,而介面中的成員變數只能是public static final型別的;

3)介面中不能含有靜態程式碼塊以及靜態方法,而抽象類可以有靜態程式碼塊和靜態方法;

4)一個類只能繼承一個抽象類,而一個類卻可以實現多個介面。

2.設計層面上的區別
  1)抽象類是對一種事物的抽象,即對類抽象,而介面是對行為的抽象。抽象類是對整個類整體進行抽象,包括屬性、行為,但是介面卻是對類區域性(行為)進行抽象。舉個簡單的例子,飛機和鳥是不同類的事物,但是它們都有一個共性,就是都會飛。那麼在設計的時候,可以將飛機設計為一個類Airplane,將鳥設計為一個類Bird,但是不能將 飛行 這個特性也設計為類,因此它只是一個行為特性,並不是對一類事物的抽象描述。此時可以將 飛行 設計為一個介面Fly,包含方法fly( ),然後Airplane和Bird分別根據自己的需要實現Fly這個介面。然後至於有不同種類的飛機,比如戰鬥機、民用飛機等直接繼承Airplane即可,對於鳥也是類似的,不同種類的鳥直接繼承Bird類即可。從這裡可以看出,繼承是一個 "是不是"的關係,而 介面 實現則是 "有沒有"的關係。如果一個類繼承了某個抽象類,則子類必定是抽象類的種類,而介面實現則是有沒有、具備不具備的關係,比如鳥是否能飛(或者是否具備飛行這個特點),能飛行則可以實現這個介面,不能飛行就不實現這個介面。
  2)設計層面不同,抽象類作為很多子類的父類,它是一種模板式設計。而介面是一種行為規範,它是一種輻射式設計。什麼是模板式設計?最簡單例子,大家都用過ppt裡面的模板,如果用模板A設計了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,如果它們的公共部分需要改動,則只需要改動模板A就可以了,不需要重新對ppt B和ppt C進行改動。而輻射式設計,比如某個電梯都裝了某種報警器,一旦要更新報警器,就必須全部更新。也就是說對於抽象類,如果需要新增新的方法,可以直接在抽象類中新增具體的實現,子類可以不進行變更;而對於介面則不行,如果介面進行了變更,則所有實現這個介面的類都必須進行相應的改動。
3. 內部類

public class OuterClass {
    private String name ;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    
    class InnerClass{
        public InnerClass(){
            name = "chenssy";
            age = 23;
        }
    }
}

- 內部類定義
內部類是定義在一個類中的類。 如同一個人是由大腦、肢體、器官等身體結果組成,而內部類相當於其中的某個器官之一,例如心臟:它也有自己的屬性和行為(血液、跳動) ,顯然,此處不能單方面用屬性或者方法表示一個心臟,而需要一個類,而心臟又在人體當中,正如同是內部類在外部內當中
每個內部類都能獨立的繼承一個介面的實現,所以無論外部類是否已經繼承了某個(介面的)實現,對於內部類都沒有影響。內部類使得多繼承的解決方案變得完整,內部類的存在使得Java的多繼承機制變得更加完善。
java中的內部類和介面加在一起,可以的解決常被C++程式設計師抱怨java中存在的一個問題 沒有多繼承。實際上,C++的多繼承設計起來很複雜,而java通過內部類加上介面,可以很好的實現多繼承的效果。
- 內部類 型別
在Java中內部類主要分為成員內部類、區域性內部類、匿名內部類、靜態內部類。
- [ ] 成員內部類
成員內部類也是最普通的內部類,它是外圍類的一個成員,所以他是可以無限制的訪問外圍類的所有 成員屬性和方法, 包括private的,但是外圍類要訪問內部類的成員屬性和方法則需要通過內部類例項來訪問。
在成員內部類中要注意兩點,第一:成員內部類中不能存在任何static的變數和方法;第二:成員內部類是依附於外圍類的,所以只有先建立了外圍類才能夠建立內部類,如下例中,構建內部類的例項,要求必須外部類的例項先存在 ,外部類的外部/外部類的靜態方法:new Outer().new Inner();
外部類的例項方法: new Inner(); this.new Inner();

  • 內部類和外部類的訪問關係
    當成員內部類擁有和外部類同名的成員變數或者方法時,會發生隱藏現象,即預設情況下訪問的是成員內部類的成員。如果要訪問外部類的同名成員,需要以下面的形式進行訪問:
    外部類.this.成員變數
    外部類.this.成員方法
    成員內部類可以無條件地訪問外部類的成員,而外部類想訪問成員內部類的成員卻不是這麼隨心所欲了。在外部類中如果要訪問成員內部類的成員,必須先建立一個成員內部類的物件,再通過指向這個物件的引用來訪問:
class MemberOuter{
	private String s1 = "Outer InstanceMar";
	private String s2 = "OuterStatic s2";
	public void setS1(String s1) {
		this.s1 = s1;
		new MemberOuter().new MemberInner();
		this.new MemberInner();  //此時MemberOuter已經例項化完成,所以可以使用this
		new MemberInner().test2();
	}
	public static void  test2 (){
		new MemberOuter().new MemberInner();
		/*this.new MemberInner();  
		 * 此時MemberOuter沒有例項化完成,所以不可以使用this
		 * static 是在MemberOuter構造器前使用,所以此時this不能使用
		 * 
*/
}
  	class MemberInner{
		 String s1= "Inner  instanceMae  ";
		static final String s4 = "static final  MemberInner";
			
				void test2(){
					System.out.println(" s1 =" + s1);
					System.out.println(" Outter MemberOuter.this.s1 =" + MemberOuter.this.s1);
					System.out.println("s2 = "+s2);
				}
		}
}
 public class MemberInnerTest {
	public static void main (String args []){
	/*	MemberOuter.MemberInner mm =  new MemberOuter().new MemberInner();
		mm.test2();*/
		MemberOuter mo = new MemberOuter();
		mo.setS1("");		
	}
}

執行結果:
在這裡插入圖片描述

  • 區域性內部類
    區域性內部類是定義在一個方法或者一個作用域裡面的類,它和成員內部類的區別在於區域性內部類的訪問僅限於方法內或者該作用域內。部內部類就像是方法裡面的一個區域性變數一樣,是不能有public、protected、private以及static修飾符的。
    區域性內部類可以訪問的外部類的成員根據所在方法體不同, 如果在靜態方法中,可以訪問外部類中所有靜態成員,包含私有。如果在例項方法中,可以訪問外部類中所有的成員,包含私有。區域性內部類可以訪問所在方法中定義的區域性變數,但是要求區域性變數必須使用final修飾。
public class LocalInnerTest {
 private int a = 1;
 private static int b = 2;
 public void test() {
 	final int c = 3;
 	class LocalInner {
 		public void add1() {
 			System.out.println("a= " + a);
 			System.out.println("b= " + b);
 			System.out.println("c= " + c);
 		}
 	}
 	new LocalInner().add1();
 }
 static public void test2() {
 	final int d = 5;
 	class LocalInner2 {
 		public void add1() {
 			// System.out.println("a= " + a);
 			System.out.println("b= " + b);
 			System.out.println("c= " + d);
 		}
 	}
 	new LocalInner2().add1();
 }
 public static void main(String args[]) {
 	// LocalInnerTest() lc = new LocalInnerTest();
 	new LocalInnerTest().test2();
 	new LocalInnerTest().test();
 }
}

執行結果如下:
在這裡插入圖片描述
- [ ] 匿名內部類
假如只建立了一個類的物件,而沒有命名,這樣的類就是內部類 ,沒有構造器。一般隱式的繼承某一個父類或者實現某一個介面,沒有class,interfaceimplements,extends關鍵字。

 interface Pen {
	public void write();
}
class  Pencil implements Pen {
	@Override
	public void write() {
		//鉛筆 的工廠
	}
} 
class Person {
	public void user(Pen pen) {
		pen.write();
	}
}
 
public class tEST1 {
	public static void main(String args[]) {
		Person guo = new Person();
		
		guo.user(new Pen() {
			@Override
			public void write() {
				System.out.println("寫字");
			}
		});
	}
 
}

執行結果:
在這裡插入圖片描述
匿名內部類適用的比較多,要麼定義一個介面,然後直接new一個介面並完善該類的方法,要麼直接呼叫import已經寫好的類,如在設計Java swing中的字型時:enterbutton.setFont(new Font("華文行楷",Font.BOLD,35)); 這樣相當於直接new Font()來設計字型。
參考 Java提高篇(十)詳解匿名內部類

  • 靜態內部類
    靜態內部類也是定義在另一個類裡面的類,只不過在類的前面多了一個關鍵字static。靜態內部類是不需要依賴於外部類的。和非靜態內部類相比,區別就在於靜態內部類沒有了指向外部的引用
class Out {
    private static int age = 12;
     
    static class In {
        public void print() {
            System.out.println(age);
        }
    }
} 
public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out.In();
        in.print();
    }
 }

執行結果 12

Java介面 抽象類和內部類是常用的類的變形,也就是說,他們是類,是對於類的抽象,以便更好的實現對於客觀世界的描述。
引用:
https://www.cnblogs.com/dolphin0520/p/3811437.html