2012-05-04 50 views
0

標題可能有點混亂,但這裏是我面臨的的Android,泛型和inhertitance

我有一個類:

public abstract class BaseFragmentActivity<T> extends FragmentActivity { 
    static final int PROGRESS_DIALOG = 0; 
    Dialog progessDialog; 

    public abstract void displayData(T output); 

    @Override 
    protected Dialog onCreateDialog(int id) { 
     if (id == PROGRESS_DIALOG) { 
      ProgressDialog progressDialog = ProgressDialog.show(this, "", 
        "Loading. Please wait...", true); 
      progessDialog = progressDialog; 
     } 

     return progessDialog; 
    } 

    class PerformOPTask extends AsyncTask<Void, String, T> { 
     // connector=new JSONConnector(); 
     Connector connector; 
     String curUrl; 
     Class<T> clazz; 

     PerformOPTask(String url, Class<T> curClazz) { 
      //connector = new UnitTestConnector(); 
      connector = new JSONConnector(); 
      curUrl = url; 
      clazz = curClazz; 
     } 

     @Override 
     protected T doInBackground(Void... params) { 

      return connector.getData(URLUtils.getFormattedUrl(curUrl),clazz); 
     } 

     @Override 
     protected void onPostExecute(T output) { 
      displayData(output); 

     } 
    } 




} 

然後,我有一個子類,如:

public abstract class BaseListFragmentActivity<T> extends BaseFragmentActivity<T> implements OnItemClickListener, OnClickListener{ 

    protected ListView mList; 


    /** Called when the activity is first created. */ 
    public void onCreate(Bundle icicle) { 
     super.onCreate(icicle); 
     setContentView(R.layout.table_list); 
     CommonUtil.getActionBarWithBackButton(this,getLayoutInflater()); 
     mList=(ListView)findViewById(R.id.table_list_listView); 
     mList.setOnItemClickListener(this); 

    } 

    public void onBackABButtonPressed(View view) { 
     finish(); 
    } 

    @Override 
    public void onClick(View v) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public abstract void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3); 


} 

現在我正在擴展這個類如下:

public class ListAccountsActivity<T> extends BaseListFragmentActivity<AccountData> { 

    protected Acct[] mItems; 
    private String[] mIcons; 
    protected boolean displayHandledBySubClass=false; 


    /** Called when the activity is first created. */ 
    public void onCreate(Bundle icicle) { 
     super.onCreate(icicle); 


     new PerformOPTask(getString(R.string.get_account),AccountData.class).execute(); 
     showDialog(PROGRESS_DIALOG); 
     //.getData(URLUtils.getFormattedUrl(getString(R.string.get_account)),actData); 




    } 

    @Override 
    public void onItemClick(AdapterView<?> lv, View view, int position, long id) { 
     // super.onListItemClick(l, v, position, id); 
     // Get the item that was clicked 
     Acct account = (Acct) mList.getAdapter().getItem(position); 
     Intent intent=new Intent(this,AccountDetailViewActivity.class); 
     intent.putExtra("selectedAccount",account); 
     startActivity(intent); 
    } 

    @Override 
    public void displayData(AccountData output){ 


     if(displayHandledBySubClass){ 
      //handle display in subclass 
      handleDisplayData(output); 
     } 
     else { 
      Acct[] accountArray = new Acct[output.getAccount().size()]; 
      mItems = output.getAccount().toArray(accountArray); 
      IWMArrayAdapter<Acct> adapter = new IWMArrayAdapter<Acct>(this, mItems); 
      adapter.setIcons(mIcons); 
      adapter.setArrowNeeded(); 
      //mList is superClassVariable 
      mList.setAdapter(adapter); 
      dismissDialog(PROGRESS_DIALOG); 
      adapter.notifyDataSetChanged(); 
     } 
    } 

    public void handleDisplayData(T output){ 

    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     //Toast.makeText(this, "Tapped search", Toast.LENGTH_SHORT).show(); 
     super.onCreateOptionsMenu(menu); 
     MenuInflater menuInflater = getMenuInflater(); 
     menuInflater.inflate(R.menu.list_servers_menu, menu); 

     // Calling super after populating the menu is necessary here to ensure 
     // that the 
     // action bar helpers have a chance to handle this event. 
     return true; 
    } 


} 

我的問題是我可以製作handleDisplayData通用某種方式,以便我可以傳遞任何類型。我試圖做的是儘可能多地重用BaseListFragmentActivity中的邏輯,並處理唯一的特定於ListAccountsActivity或其子類的子任務。

我希望我的問題很清楚,謝謝你的幫助

回答

2

如果我理解正確的話,你希望能夠在子類中使用特定類型的方法從基礎,爲此,你需要做的一切通用:

public abstract class GenericBase<T> { ... } 
public abstract class ExtendedGeneric<T> extends GenericBase<T> { ... } 
public class ExtendedGenericSub<T> extends ExtendedGeneric<T> { ... } 

點是如果ExtendedGeneric擴展了GenericBase<DataOutput>,只有GenericBase<DataOutput>的方法可從ExtendedGeneric訪問。

+0

我希望能夠做的就是在ExtendedGeneric實施displayData除了在這裏我想ExtendedGenericSub處理dislay在這種情況下,我會用handleInSubClass方法的情況。我面臨的挑戰是我可以得到一個DataOutput或其他類型說ServerOutput是無關的,但如果DataOutput是我想在ExtendedGeneric中處理的類型,但如果類型是ServerOutput我想處理ExtendedGenericSub中handleInSubClass方法 – sab

+0

用法例如勝過千言萬語。現在我不確定「獲取另一個類型」的含義是什麼 - handleInSubClass從其他方法調用?還是在'displayData(DataOutput)'中的某個其他對象上調用? – trutheality

+0

對不起,這裏是如何調用它:displayData(dataOutput),在這種情況下,我不想調用handleInSubClass,但displayData(serverOutput)應該調用handleInSubClass(s​​erverOutput)。 – sab

2

這是你想要的嗎?

public abstract class ExtendedGeneric<C> extends GenericBase<DataOutput> { 

boolean handleInSub; 

@Override 
public void displayData(DataOutput t) { 
    if(handleInSub){ 
     handleInSubClass(getValue(t)); 
    } 

    //handle here 
    System.out.println(t); 

} 

protected abstract void handleInSubClass(C c); 
protected abstract C getValue(DataOutput t); 

}

這當然只是假設數據C型將來自DataOutput中噸。這個想法是你也可以使ExtendenGeneric參數化,這樣你可以擴展它的類來控制提供給handleInSubClass的數據類型。

1

當然,您可以:

GenericParent

public abstract class GenericParent<T> { 

    public abstract void displayData(T t); 

} 

GenericChild

public class GenericChild<T> extends GenericParent<GenericChild> { 

    @Override 
    public void displayData(GenericChild t) { 
     // Do Something Here... 
    } 

    /** 
    * Using protected better than public, 
    * to prevent other class access directly to this method. 
    * But make sure this the other class is not same package with this GenericChild, 
    * because if it same package than the other class can access directly this method. 
    **/ 
    protected void handleSubClass(T t){} 
} 

子類

public class SubClass extends GenericChild<SubClass> { 

    @Override 
    public void handleSubClass(SubClass t){ 
     // Do Something Here... 
    } 
} 
1

我們在談論這類事情嗎?

class Vehicle {}; 

abstract class RoadVehicle extends Vehicle { 
    abstract int getNumberOfWheels(); 
} 

class Truck extends RoadVehicle { 
    int getNumberOfWheels() { 
    return 8; 
    } 
} 

class Car extends RoadVehicle { 
    int getNumberOfWheels() { 
    return 4; 
    } 
} 

abstract class GenericHandler<T extends Vehicle> { 
    public abstract void displayData(T t); 
} 

abstract class RoadVehicleHandler<T extends RoadVehicle> 
    extends GenericHandler<T> { 
    public void displayData(T t) { 
    System.out.println(t.getNumberOfWheels() + " wheels"); 
    specialStuff(); 
    } 

    abstract void specialStuff(); 
} 

class CarHandler extends RoadVehicleHandler<Car> { 
    void specialStuff() { /* honk horn */ } 
} 

class TruckHandler extends RoadVehicleHandler<Truck> { 
    void specialStuff() { /* flash lights */ } 
} 
+0

如果你的所有類都在同一個'package'中,那麼使用'default'修飾符是可以的,但是如果你想從另一個'package'訪問,一定要使它成爲'public'。 – Crazenezz