1. 程式人生 > >10 面向物件_許可權修飾符&匿名內部類

10 面向物件_許可權修飾符&匿名內部類

10.01_面向物件(package關鍵字的概述及作用)(瞭解)

  • A:為什麼要有包(資料夾)

    • 將位元組碼(.class)進行分類存放
    • 包其實就是資料夾
  • B:包的概述

  • 舉例:
    學生:增加,刪除,修改,查詢
    老師:增加,刪除,修改,查詢

      方案1:按照功能分
      	com.heima.add
      		AddStudent
      		AddTeacher
      	com.heima.delete
      		DeleteStudent
      		DeleteTeacher
      	com.heima.update
      		UpdateStudent
      		UpdateTeacher
      	com.heima.find
      		FindStudent
      		FindTeacher
      
      方案2:按照模組分
      	com.heima.teacher
      		AddTeacher
      		DeleteTeacher
      		UpdateTeacher
      		FindTeacher
      	com.heima.student
      		AddStudent
      		DeleteStudent
      		UpdateStudent
      		FindStudent
    

10.02_面向物件(包的定義及注意事項)(掌握)

  • A:定義包的格式
    • package 包名;
    • 多級包用.分開即可,表示路徑:com.heima.add
  • B:定義包的注意事項
    • A:package語句必須是程式的第一條可執行的程式碼
    • B:package語句在一個java檔案中只能有一個
    • C:如果沒有package,預設表示無包名
  • C:案例演示
    • 包的定義及注意事項

10.03_面向物件(帶包的類編譯和執行)(掌握)

  • A:如何編譯執行帶包的類
    • a:javac編譯的時候帶上-d即可
      • javac -d . HelloWorld.java
    • b:通過java命令執行。
      • java 包名.HelloWord(類名)

10.04_面向物件(不同包下類之間的訪問)(掌握)

  • A:案例演示
    • 不同包下類之間的訪問

10.05_面向物件(import關鍵字的概述和使用)(掌握)

  • A:案例演示
    • 為什麼要有import
      • 其實就是讓有包的類對呼叫者可見,不用寫全類名了
  • B:導包格式
    • import 包名;
      //java.util.Scanner;
    • 注意:
    • 這種方式匯入是到類的名稱。
    • 雖然可以最後寫*,但是不建議。//java.util.* *表示萬用字元,他會到該包下挨個匹配,匹配就匯入

    在開發中我們都是匯入具體的類

  • C:package,import,class有沒有順序關係(面試題)

有,123

10.06_面向物件(四種許可權修飾符的測試)(掌握)

  • A:案例演示
    • 四種許可權修飾符
  • B:結論
  •   		        本類	 同一個包下(子類和無關類)	不同包下(子類)	不同包下(無關類)
      private 	    Y		
      預設			Y		            Y
      protected  	Y		            Y					Y
      public	    Y		            Y				    Y				Y
    

10.07_面向物件(類及其組成所使用的常見修飾符)(掌握)

  • A:修飾符:

    • 許可權修飾符:private,預設的,protected,public
    • 狀態修飾符:static,final
    • 抽象修飾符:abstract
  • B:類:

    • 許可權修飾符:預設修飾符,public

    • 狀態修飾符:final

    • 抽象修飾符:abstract

    • 用的最多的就是:public

  • C:成員變數:

    • 許可權修飾符:private,預設的,protected,public

    • 狀態修飾符:static,final

    • 用的最多的就是:private

  • D:構造方法:

    • 許可權修飾符:private,預設的,protected,public

    • 用的最多的就是:public(當類中所有方法全是靜態的,需要將構造方法私有private)

  • E:成員方法:

    • 許可權修飾符:private,預設的,protected,public

    • 狀態修飾符:static,final

    • 抽象修飾符:abstract

    • 用的最多的就是:public

  • F:除此以外的組合規則:

    • 成員變數:public static final 介面
    • 成員方法:
      • public static
      • public abstract
      • public final

10.08_面向物件(內部類概述和訪問特點)(瞭解)

  • A:內部類概述(成員內部類位於類裡面)
  • B:內部類訪問特點
    • a:內部類可以直接訪問外部類的成員,包括私有。
    • b:外部類要訪問內部類的成員,必須建立物件。
    • 外部類名.內部類名 物件名 = 外部類物件.內部類物件;
  • C:案例演示
    • 內部類極其訪問特點
class Demo1_InnerClass {
	public static void main(String[] args) {
		//外部類名.內部類名 = 外部類物件.內部類物件
		Outer.Inner oi = new Outer().new Inner();			//建立內部類物件
		oi.method();

	}
}
class Outer {
	private int num = 10;
	 class Inner {
		public void method() {
			System.out.println(num);
		}
	}
}

10.09_面向物件(成員內部類私有使用)(瞭解)

  • private

10.10_面向物件(靜態成員內部類)(瞭解)

靜態內部類

  • static
  • B:成員內部類被靜態修飾後的訪問方式是:
    • 外部類名.內部類名 物件名 = 外部類名.內部類物件;
class Demo2_InnerClass {
	public static void main(String[] args) {
		Outer.Inner oi = new Outer().Inner();//只有一個new,而且是Inner()的
		oi.method();
	}
}

class Outer {
	static class Inner {//靜態類中有非靜態方法
		public void method() {
			System.out.println("method");
		}
	}
}
class Demo2_InnerClass {
	public static void main(String[] args) {
		Outer.Inner.method();//直接用類名呼叫
	}
}

class Outer {
	static class Inner {//靜態類中有靜態方法
		public static void method() {
			System.out.println(num);
		}
	}
}

10.11_面向物件(成員內部類的面試題)(掌握)

  • A:面試題
  •   要求:使用已知的變數,在控制檯輸出30,20,10。
      
      class Outer {
      	public int num = 10;
      	class Inner {
      		public int num = 20;
      		public void show() {
      			int num = 30;
      			System.out.println(num);
      			System.out.println(this.num);
      			System.out.println(Outer.this.num);//內部類之所以能獲取到外部類的成員,是因為他能獲取到外部類的引用外部類名.this
      		}
      	}
      }
      class InnerClassTest {
      	public static void main(String[] args) {
      		Outer.Inner oi = new Outer().new Inner();
      		oi.show();
      	}	
      }
    

10.12_面向物件(區域性內部類訪問區域性變數的問題)(掌握)

  • A:案例演示(類在方法裡面)
    • 區域性內部類訪問區域性變數必須用final修飾

    • 區域性內部類在訪問他所在方法中的區域性變數必須用final修飾,為什麼?
      因為當呼叫這個方法時,區域性變數如果沒有用final修飾,他的生命週期和方法的生命週期是一樣的,當方法彈棧,這個區域性變數也會消失,那麼如果區域性內部類物件還沒有馬上消失想用這個區域性變數,就沒有了,如果用final修飾會在類載入的時候進入常量池,即使方法彈棧,常量池的常量還在,也可以繼續使用

      但是jdk1.8取消了這個事情,所以我認為這是個bug,雖然取消,如果在書寫程式碼時候,沒有手動新增,系統底層也會默給你final

class Demo1_InnerClass {
	public static void main(String[] args) {
		Outer o = new Outer();
		o.method();
	}
}
//區域性內部類
class Outer {
	public void method() {
		final int num = 10; //Demo1_InnerClass.java:13: 錯誤: 從內部類中訪問本地變數num; 需要被宣告為最終型別
		class Inner {
			public void print() {
				System.out.println(num);
			}
		}
		Inner i = new Inner();
		i.print();
	}

	/*public void run() {
		Inner i = new Inner();				//區域性內部類,只能在其所在的方法中訪問
		i.print();
	}*/
}

10.13_面向物件(匿名內部類的格式和理解)

  • A:匿名內部類
    • 就是內部類的簡化寫法。
  • B:前提:存在一個類或者介面
    • 這裡的類可以是具體類也可以是抽象類。
  • C:格式:
  •   new 類名或者介面名(){//繼承類,或者實現介面
      	重寫方法;
      }
    
  • D:本質是什麼呢?
    • 是一個繼承了該類或者實現了該介面的子類匿名物件。
  • E:案例演示
    • 按照要求來一個匿名內部類
class Demo1_NoNameInnerClass {
	public static void main(String[] args) {
		Outer o = new Outer();
		o.method();
	}
}

interface Inter {
	public void print();//預設抽象
}

class Outer {
	class Inner implements Inter {
		public void print() {
			System.out.println("print");
		}
	}

	public void method(){
		//Inner i = new Inner();
		//i.print();
		//new Inner().print();
		//Inter i = new Inner();			//父類引用指向子類物件
		
		new Inter() {						//實現Inter介面
			public void print() {			//重寫抽象方法
				System.out.println("print");
			}
		}.print();//{}裡面代表Inter的子類物件,可以直接呼叫其print()方法
	}
}

10.14_面向物件(匿名內部類重寫多個方法呼叫)

  • A:案例演示
    • 匿名內部類的方法呼叫
class Demo2_NoNameInnerClass {
	public static void main(String[] args) {
		Outer o = new Outer();
		o.method();
	}
}

interface Inter {
	public void show1();
	public void show2();
}
//匿名內部類只針對重寫一個方法時候使用
class Outer {
	public void method() {
		/*new Inter(){
			public void show1() {
				System.out.println("show1");
			}

			public void show2() {
				System.out.println("show2");
			}
		}.show1();

		new Inter(){
			public void show1() {
				System.out.println("show1");
			}

			public void show2() {
				System.out.println("show2");
			}
		}.show2();*/

		Inter i = new Inter(){//父類引用指向子類物件
			public void show1() {
				System.out.println("show1");
			}

			public void show2() {
				System.out.println("show2");
			}

			/*public void show3() {//子類特有的方法,父類引用沒法呼叫,編譯失敗
				System.out.println("show3");
			}*/
		};

		i.show1();
		i.show2();
		//i.show3();						//匿名內部類是不能向下轉型的,因為沒有子類類名
	}
}

10.15_面向物件(匿名內部類在開發中的應用)

  • A:程式碼如下
  •   //這裡寫抽象類,介面都行
      abstract class Person {
      	public abstract void show();
      }
    
      class PersonDemo {
      	public void method(Person p) {
      		p.show();
      	}
      }
    
      class PersonTest {
      	public static void main(String[] args) {
      		//如何呼叫PersonDemo中的method方法呢?
      		PersonDemo pd = new PersonDemo ();
      		pd.method(new Person(){//Person的子類物件,當做引數傳遞(把匿名內部類看做一個物件)
      			public void show(){
      				System.out.println("show");
      			}
      		});
      	}
      }
    

10.16_面向物件(匿名內部類的面試題)

  • A:面試題
  •   按照要求,補齊程式碼
      interface Inter { void show(); }
      class Outer { 
      	public static Inter method(){
      		return new Inter(){
      			public void show()
      			{
      				System.out.println("HelloWorld");
      			}
      		};
      	}
      } //補齊程式碼
      class OuterDemo {
      	public static void main(String[] args) {
      		  Outer.method().show();//鏈式程式設計,每次呼叫方法後還能繼續呼叫方法,說明呼叫方法返回的是一個物件
      	  }
      }
      要求在控制檯輸出”HelloWorld”