1. 程式人生 > >抽象類與介面及簡單的工廠模式

抽象類與介面及簡單的工廠模式

抽象類;

(1得1失)得到抽象方法的能力,失去建立例項的能力

某個父類只知道子類可能需要有這些方法,但是不知道具體的實現方式;
抽象類和抽象方法能更好的發揮多型
理由:一定發生繼承。一定會發生方法的重寫();類的多型性體現!

eg:baseFragment:

注意到除了生命周器的抽取外,其中的MainActivitiy 是fragment和所在Activity中元件溝通的重要橋樑!

public abstract class BaseFragment extends Fragment
{
       這也是fragment和activity內的元件溝通的重要橋樑
	protected MainActivity mainActivity;//上下文
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		mainActivity = (MainActivity) getActivity();//獲取fragment所在Activity;
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View root = initView(); //View
		return root;
	}
	
	/**
	 * 必須覆蓋此方法來完全介面的顯示
	 * @return
	 */
	public abstract View initView();
	

	/**
	 * 子類覆蓋此方法來完成資料的初始化
	 */
	public void initData(){
		
	}
	
	/**
	 * 子類覆蓋此方法來完成事件的新增
	 */
	public void initEvent(){
		
	}

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		//初始化事件和資料
		super.onActivityCreated(savedInstanceState);
		initData();//初始化資料
		initEvent();//初始化事件
	}
	
}

當介面相似的情況下,我們一可以通過類的方式抽取基類進行簡化處理:

例如  Viewpager 中幾個相似的View 介面都很相似,我們抽取後只需要 覆寫幾個方法即可完成不同介面的相似性佈局。

eg:

public class BaseTagPage
{
	protected MainActivity mainActivity;
	protected View	root;
	protected ImageButton	ib_menu;//按鈕ib
	protected TextView	tv_title;
	protected FrameLayout	fl_content;
	protected ImageButton ib_listOrGrid;
	public BaseTagPage(MainActivity context){
		this.mainActivity = context;
		initView();//初始化佈局
		
		initEvent();
	}

	public  void initView() {
		//介面的根佈局
		root = View.inflate(mainActivity, R.layout.fragment_content_base_content, null);
		
		ib_menu = (ImageButton) root.findViewById(R.id.ib_base_content_menu);
		
		tv_title = (TextView) root.findViewById(R.id.tv_base_content_title);
		
		fl_content = (FrameLayout) root.findViewById(R.id.fl_base_content_tag);
		
		ib_listOrGrid = (ImageButton) root.findViewById(R.id.ib_base_content_listorgrid);
	}
	
	public void initEvent(){
		//給選單按鈕新增點選事件
		ib_menu.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				//開啟或者關閉左側選單
				mainActivity.getSlidingMenu().toggle();//左側選單的開關
			}
		});
	}
	
	/**
	 * 此方法在該頁面資料顯示的時候再呼叫
	 */
	public void initData(){
		
	}
	
	
	
	public View getRoot(){
		return root;
	}
}

當子類繼承父類是 直接在initview()中修改控制元件的屬性。

重寫事件和資料的方法即可! 

採用上面方式抽取時要注意 initdata 的呼叫 大多數 會在從 結合取出之前先行初始化,例如從建構函式中傳遞 一個集合,下面可能會用到 ,所以設定了空引用。

這是 初始化可以避免引用為空!!

普通定義介面抽取類: 當佈局完全不同,完全自定義,甚至後面還是需要自定義佈局模組的情況下,可以採用下面這種基類抽取方式:
public abstract class BaseCenterPaper {
    private View root ;
    MainActivity mainActivity;
    public BaseCenterPaper(Context context) {
        this.mainActivity= (MainActivity)context;
        this.root=initView();
        initEvent();
    }
    public abstract View initView();
    public void initData(){

    }
    public void initEvent(){

    }

    public View getRoot() {
        return root;
    }
}
和上面相比唯一不同的就是子類不可以獲取到基類的控制元件了。 因為子類有自己的佈局 而 所需要的資料  可以在建構函式中進行傳遞。 然後將資料初始化給所繼承的子類 !取出這個例項時提前呼叫initdata方法

介面:

介面;裡面只有抽象方法;更徹底的抽取
介面:(不能建立例項,但可以作為,引用型別)
介面只能用public 或者預設修飾符修飾。
在介面中常量預設的修飾符是public static final
當介面作為引用型別引用,介面的實現類時,體現出介面的多型性!


eg: interface Product{
     int getProduceLine();
}
class Printer implent Product{
   int  getProduceLine(){
       syso.printf("line")
  }
}
class client{
  public void main (String[] args){
     Product p=new Printer();
     p.getProduceLine();
 }
}


這裡將多型的第1個必要條件,必須要有繼承替換成了,實現介面。

簡單的工廠模式:

面向介面程式設計:
實現低耦合,高內聚的一種程式設計方法
簡單的工廠模式(情景A使用B物件,為了減少A物件對B物件的耦合,和B物件的替換,不採用組合方式而是採用工廠模式):
思路:
B物件即被使用的物件是一個介面。將需要使用的物件B,放在使用者建構函式中,並在內部對其使用。
當A物件需要使用B物件時,通過工廠產生一個介面放入B物件中。由於介面的標準是相同的,
替換B物件只需要C物件實現介面並在工廠中返回C物件即可,A的內部不用進行任何改變

eg:
A為電腦 B為印表機 C為另一種印表機


interface Output {
   public void output();
} 
因為介面的存在使得Computer使用印表機的方式完全透明(因為方法規範)。
class Computer {
   private Output o;
    public computer(Output output)
    {     this.output=output;
    }
    public void print(){
     o.output();
}}
 class Aoutput implentment Output(){
   public output(){
         syso.printf("a的列印方式");
     }   
   
 }


class Factory{
    getOutput() {
         return new Aoutput();//如需替換A則只需要在工廠返回時替換A物件為C物件即可
     }
    public void main(String[] args)
    {
      Factory factory=new Factory();     
      Computer c=new computer(factory.getOutput());
      c.output();
    }
}