黑馬程序員--- 學習筆記(第八天)

 —————————— ASP.Net+Android+IOS開發.Net培訓、期待與您交流!——————————
多態:
某一些事物的多種表現形態


例如人(Person): 男人(man),女人(women)
例如動物(Animal):貓(cat),狗(dog)
     
1.多態的體現
父類的引用指向了子類對象
2.多態的前提
必須是類與類之間有關係,要麼繼承,要麼實現
3.多態的好處:
大大提高了程序的擴展性,通常還有一個前提,存在覆蓋
4.多態的弊端:
提高了擴展性,但是不能使用的父類的引用訪問父類中的成員


Animal a=new Cat(); //類型轉換 向上轉換


如果想要調用貓的特有方法時,如何操作?
可以強制將父類的引用,轉成子類類型,向下轉型
Cat c=(Cat)a;
c.子類特有方法();


千萬別出現這樣的操作,將父類的對象轉成子類類型,
我們轉換的是父類的引用指向自己子類時,該引用可被提升
,也可以被強制轉換.
Animal a=new Animal();
Cat c=(Cat)a;  //這樣是錯誤的


多態自始至終都是子類對象做着變化




instanceOf關鍵字:
判斷某一些類型引用是否指向某一些類型
例如 a instanceOf Cat

5.多態的應用

/*
多態的應用 例子一

基礎班學生:  學習  睡覺  
高級班學生:  學習 睡覺(坐着睡覺)

可以將這兩類事物向上抽取,發現功能定義相同,內容不同
*/
class Demo1 
{
	public static void main(String[] args) 
	{	  /*
		  Student s=new AdvStudent();
		  s.study();
		  s.sleep();
		  s.function();	//錯誤的, 編譯時看父類引用是否有該方法
		  */
		  method(new BaseStudent());
		  method(new AdvStudent());
	}
	public static void method(Student ss){
		ss.study();
			ss.sleep();
		/*使用子類的特有方法要進行判斷,進行強制向下轉換*/
		if(ss instanceof BaseStudent){
			BaseStudent s=(BaseStudent)ss;
			
		}else if(ss instanceof AdvStudent){
			AdvStudent a=(AdvStudent)ss;
			a.function();
		}
		
	}
}
abstract class Student
{
	public abstract void study();
	public  void sleep(){
		System.out.println("躺着睡覺");
	}
}
class BaseStudent  extends Student
{
	public void study(){
		System.out.println("學習基礎知識");
	}

}
class AdvStudent   extends Student
{
	public void study(){
		System.out.println("學的就業知識");
	}
	public void sleep(){
		System.out.println("哥們是站着睡的");
	}
	public void function(){
		System.out.println("哥有自己的特有方法");
	}
}




/*
多態的應用 例子二
  接口多態
主板的運行示例
*/
class Demo3 
{
	public static void main(String[] args)throws Exception 
	{
		MainBoard mb=new MainBoard();
		mb.run();
		mb.userPCI(new NetCard());//網卡
		mb.userPCI(new SoundCard());//聲卡

	   //三秒主板關閉,電腦結束運行
		Thread.sleep(3000);
		mb.close();
	}
}

/*主板類*/
class MainBoard	 
{
	public void run(){
		System.out.println("主板開啓了");
	}
	public void reset(){
		System.out.println("主板重啓了");
	}
	public void close(){
		System.out.println("主板關閉了");
	}
	public void userPCI(PCI p){	//實現PCI擴展功能
	  p.open();
	  p.close();
	}
}
/*網卡,聲卡等PCI卡槽*/
interface PCI
{
	public abstract void open();
	public abstract void close();
}
/*網卡 實現PCI卡槽同一標準f*/
class NetCard implements PCI
{
	public void open(){
	   System.out.println("網卡開啓");
	}
	public void close(){
		System.out.println("網卡關閉");
	}
}
/*聲卡卡 實現PCI卡槽同一標準f*/
class SoundCard implements PCI
{
	public void open(){
	   System.out.println("聲卡開啓");
	}
	public void close(){
		System.out.println("聲卡關閉");
	}
}



/*
數據庫操作 例子三

假如本來使用jdbc對數據進行操作,然後改用框架高級操作了
 只要修改BaseDao的連接 關閉方法即可,
 
 Data Access Object  DAO

此代碼不準備運行 
*/
class Demo4 
{
	public static void main(String[] args) 
	{
		  new UserDaoImple();// 調用方法進行傳參即可
	}
}
class EntityDao
{
	private int age;
	public void setAge(int age){
		this.age=age;
	}
	public int getAge(){
		return age;
	}
}
class BaseDao
{
	 //使用jdbc鏈接數據庫

	 //關閉數據庫鏈接
}
interface  UserDao
{
	 public void add(EntityDao e);
}
class UserDaoImpl implements UserDao
{
	public void add(EntityDao e){
		BaseDao.開啓數據庫();
		//執行add 操作
		//Base.closeAll(con,pst,rs); 關閉全部

	}
}







6.多態的出現代碼中的特點(多態使用注意事項):
在多態中非靜態成員函數的特點(父類引用指向了子類對象):
在編譯時期,參閱引用類型變量所屬類中是否有該方法,有側編譯通過,
否則,編譯失敗.


簡而言之:非靜態成員函數在多態中,編譯看左邊,運行看右邊


在多態中成員變量的特點:
無論編譯還是運行都是看參考左邊(引用類型所屬的類)


在多態中靜態方法的特點:
無論編譯還是運行都參考左邊


方法區分靜態方法區和非靜態方法區


/*
多態出先在成員中的特點
*/
class Demo2 
{
	public static void main(String[] args) 
	{
		/*
		編譯時期看父類,運行就運行子類的 
		這個是可以的
		Test1 t=new Test2();
		t.method_1();
		t.method_2(); 
		*/
	
	/*
		//編譯時期看父類,運行就運行子類的 
		//這個是不可以的
		Test1 t=new Test2();
		t.method_1();
		t.method_2(); 
		t.method_3();  //父類沒有這個方法,編譯出錯
		*/
	   /*
		//要上訴的編譯運行,需要進行強制轉換
		Test1 t=new Test2();
		t.method_1();
		t.method_2();
		Test2 t2=(Test2)t;
		t2.method_3(); 
		*/
		//new Test3().method_3();	//final方法可以被繼承,不能覆蓋


		 //靜態成員變量,非靜態成員變量,靜態方法編譯運行都是看左邊
		 Test1 t= new Test2();
		 System.out.println(t.num);	//輸出的父類引用的num值	即使是static所修飾的
		 t.method_4();	//static函數輸出的也是父類的內容
		 System.out.println(t.getN());//沒有重寫輸出的是父類的

	}
}
/*
父類 test1
*/
abstract class Test1
{
	static  int num=3;
	private int n=50;
	public int getN()
	{
		return n;
	}
	public abstract void method_1();
	public void method_2(){
		System.out.println("fu    method_2");
	}
	public static void method_4(){
		System.out.println("fu   static");
	}
}
/*
test2 繼承 test1
*/
class Test2	 extends Test1
{
	static int num=30;
	private int n=5;
	/*
	//如果重寫getN() 那麼獲取就是本類的 
	public int getN()
	{
		return n;
	}
	*/
   public  void method_1(){
   		System.out.println("zi  method_1");
   }
   public final  void method_3(){
   		System.out.println("zi  method_3");
   }
   public static void method_4(){
		System.out.println("zi   static");
	}
}
/*測試類*/
 class Test3 extends Test2
 {
		
 }





Object
object是所有父類對象直接 或間接的父類
該類中定義的功能肯定所有對象都具備的功能


equals(Object obj)
指示其他某個對象是否與此對象“相等”。 


object類中已經提供與對象是否相同的比較功能.
如果自定義類中也有比較相同的功能,沒有必要重新定義,
只要沿襲父類中的功能建立自己特有的比較的內容即可,就是覆蓋


toString()
返回該對象的字符串表示。通常,toString 方法會返回一個“以文本方式表示”此對象的字符串。
結果應是一個簡明但易於讀懂的信息表達式。建議所有子類都重寫此方法。


hashCode();//object類中的方法,  返回該對象的哈希碼值。
Integer.toHexString();//integet類方法 十進制轉16進制
getClass(); //obejct方法  返回此 Object 的運行時類。


class文件運行一進內存,類就被封裝成對象,所以有一個Class類描述這些class文件
Class中有這些class對象的共性方法,例如名稱,一般方法,構造函數


方法:
getName();
以 String 的形式返回此 Class 對象所表示的實體(類、接口、數組類、基本類型或 void)名稱。 

class Demo5 
{
	public static void main(String[] args) 
	{


		One one=new One();
		one.setNum(4);
		Two two=new Two();
		two.setNum(4);

		Three three=new Three();
		three.setNum(5);
		System.out.println(one.equals(two));
		//System.out.println(one.euqals(three));//編譯通過,運行異常
	

		//直接或間接之類都擁有object類的功能,不復寫一樣可以equals
		System.out.println(three.equals(two));

		System.out.println(two.toString());
		System.out.println(three.toString());
	}
}
/*
one類要有一個比較的方法,直接複寫equals即可
*/
class One
{
	private int num;
	public void setNum(int num){
		this.num=num;
	}
	public int getNum(){
		return num;
	}
	/*複寫equals  比較兩個對象的num屬性時候相同*/
	public boolean equals(Object obj){
		if(!(obj instanceof Two))
			throw new RuntimeException("傳入對象類型失敗");
			Two t=(Two)obj;
		return this.getNum()==t.getNum();
	
	}
}
class Two
{
	private int num;
	public void setNum(int num){
		this.num=num;
	}
	public int getNum(){
		return num;
	}
}
class Three
{
	private int num;
	public void setNum(int num){
		this.num=num;
	}
	public int getNum(){
		return num;
	}
	/*複寫 toString*/
	public String toString(){
		return this.getClass().getName()+"@"+Integer.toHexString(this.hashCode());
	}
}








 —————————— ASP.Net+Android+IOS開發.Net培訓、期待與您交流!——————————

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