Android, Generics and inhertitance - java

The title may be bit confusing but here is what I am facing
I have a class:
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);
}
}
}
Then I have a subclass as :
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);
}
Now I am extending this class as below:
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;
}
}
My Question is can I make handleDisplayData generic in some way so that I can pass any type to it. What I am trying to do is to reuse logic in BaseListFragmentActivity as much as possible and handle the only task specific to ListAccountsActivity or its subclass in that class/subclass.
I hope my question is clear, Thanks for any help

If I understand correctly, you want to be able to use type-specific methods from the base in the subclass, and for that you need to make everything generic:
public abstract class GenericBase<T> { ... }
public abstract class ExtendedGeneric<T> extends GenericBase<T> { ... }
public class ExtendedGenericSub<T> extends ExtendedGeneric<T> { ... }
Point being that if ExtendedGeneric extends GenericBase<DataOutput>, only methods of GenericBase<DataOutput> are accessible from ExtendedGeneric.

Is this what you want?
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);
}
This is of course only assumes that the data type C will come from DataOutput t. The idea is you can also make the ExtendenGeneric parameterized so you can make the classes extending it controls the datatype supplied to handleInSubClass.

Sure you can:
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){}
}
SubClass
public class SubClass extends GenericChild<SubClass> {
#Override
public void handleSubClass(SubClass t){
// Do Something Here...
}
}

Are we talking about this kind of thing?
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 */ }
}

Related

how to delete item/instence MVVM

I'm new to Programming and to Android and got please a question, so I have to build an Android app ( App to buy cars) using MVVM,LiveData, RecyclerView and Fragments.
I can creat an instance of car and then view that in a RecyclerView, but when I want to delete it, then I receive the following error:
Logcat:
java.lang.NullPointerException: **Attempt to invoke virtual method 'void com.example.da.ViewModel.MyViewModel.deleteCar(com.example.da.Model.Car)' on a null object reference**
at com.example.da.Adapter.RecyclerAdapter$MyViewHolder$2.onClick(RecyclerAdapter.java:127)
at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:174)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
I hope that someone can help me.Thanks a lot!
Dao
<pre><code>
#Dao
public interface CarDao {
#Insert(onConflict = OnConflictStrategy.REPLACE)
void addCar( Car car);
#Query("SELECT * FROM Car ORDER BY model ASC")
LiveData<List<Car>>getAllCars();
#Delete
public void deleteCar(Car car);
#Query("DELETE FROM Car")
void deleteAll();
#Update
void updateCar(Car car);
//User
#Insert
void registerUser(User user);
}
</pre></code>
Database
<pre><code>
#Database(entities = {Car.class, User.class},version =1, exportSchema = false)
public abstract class RoomDatabase extends androidx.room.RoomDatabase {
private static RoomDatabase roomDatabase;
private static final String databaseName="user";
// Dao including
public abstract CarDao carDao();
public abstract UserDao userDao();
public static synchronized RoomDatabase getUserDatabase(Context context)
{
if (roomDatabase==null)
{
roomDatabase= Room.databaseBuilder(context, RoomDatabase.class,databaseName)
.fallbackToDestructiveMigration()
.build();
}
return roomDatabase;
</pre></code>
Repository
<pre><code>
public class Repository {
private CarDao carDao;
private LiveData<List<Car>>getAllCars;
public Repository(Application application)
{
RoomDatabase db = RoomDatabase.getUserDatabase(application);
carDao=db.carDao();
getAllCars=carDao.getAllCars();
}
//CarDao methods
public void addCar( Car car)
{
new newAsyncTask(carDao).execute(car);
}
private static class newAsyncTask extends AsyncTask<Car, Void, Void>{
private CarDao myAsyncDao;
newAsyncTask(CarDao carDao){
myAsyncDao=carDao;
}
#Override
protected Void doInBackground(Car... cars) {
myAsyncDao.addCar(cars[0]);
return null;
}
}
public void updateCar( Car car)
{
new updateAsyncTask(carDao).execute(car);
}
private static class updateAsyncTask extends AsyncTask<Car, Void, Void>{
private CarDao myAsyncDao;
updateAsyncTask(CarDao carDao){
myAsyncDao=carDao;
}
#Override
protected Void doInBackground(Car... cars) {
myAsyncDao.updateCar(cars[0]);
return null;
}
}
public void deleteCar( Car car)
{
new deleteAsyncTask(carDao).execute(car);
}
private static class deleteAsyncTask extends AsyncTask<Car, Void, Void>{
private CarDao myAsyncDao;
deleteAsyncTask(CarDao carDao){
myAsyncDao=carDao;
}
#Override
protected Void doInBackground(Car... cars) {
myAsyncDao.deleteCar(cars[0]);
return null;
}
}
</pre></code>
RecyclerAdapter
<pre><code>
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
private List<Car>list;
Context context;
private MyViewModel myViewModel;
public RecyclerAdapter(List<Car> list) {
this.list = list;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.car_item,parent,false);
MyViewHolder myViewHolder = new MyViewHolder(view);
context=parent.getContext();
return myViewHolder;
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
Car car = list.get(position);
holder.tvModel.setText(car.getCarModel());
holder.tvColor.setText(car.getCarColor());
holder.tvDpl.setText(car.getCarDpl());
holder.tvDescription.setText(car.getCarDescription());
holder.tvPrice.setText(car.getCarPrice());
}
#Override
public int getItemCount() {
if(list !=null)
{
return list.size();
}
else return 0;
}
public void setData(List<Car>list){
this.list=list;
notifyDataSetChanged();
}
// generate ViewHolder
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView tvModel;
TextView tvColor;
TextView tvDpl;
TextView tvDescription;
TextView tvPrice;
Button btnDelete;
// Constructor of ViewHolder
public MyViewHolder(#NonNull View itemView) {
super(itemView);
// Inflate the views
tvModel=itemView.findViewById(R.id.model);
tvColor=itemView.findViewById(R.id.color);
tvDescription=itemView.findViewById(R.id.description);
tvDpl=itemView.findViewById(R.id.dpl);
tvPrice=itemView.findViewById(R.id.price);
btnDelete=itemView.findViewById(R.id.btn_delete);
// Listener for Delete button
btnDelete.setOnClickListener(this);
btnDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CreateAlertDialoge();
}
});
}
private void CreateAlertDialoge()
{
AlertDialog.Builder builder =new AlertDialog.Builder(context);
builder.setMessage("Are you sure to delete");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Car car = new Car();
int ID=list.get(getAdapterPosition()).getCarId();
car.setCarId(ID);
// if (car==null){
// return;
// }
//MainActivity.roomDatabase.carDao().deleteCar(car);
myViewModel.deleteCar(car);
MainActivity.fragmentManager.beginTransaction().replace(R.id.container,new BaseFragment(),null).commit();
Toast.makeText(context, "Yes", Toast.LENGTH_SHORT).show();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(context, "no", Toast.LENGTH_SHORT).show();
}
});
builder.create();
builder.show();
}
#Override
public void onClick(View v)
{
Car car = new Car();
int ID=list.get(getAdapterPosition()).getCarId();
car.setCarId(ID);
//MainActivity.roomDatabase.carDao().deleteCar(car);
myViewModel.deleteCar(car);
MainActivity.fragmentManager.beginTransaction().replace(R.id.container,new BaseFragment(),null).commit();
}
}
}
</pre></code>
ViewModel
<pre><code>
public class MyViewModel extends AndroidViewModel {
private Repository repository;
private LiveData<List<Car>>getAllCars;
public MyViewModel(#NonNull Application application) {
super(application);
repository=new Repository(application);
getAllCars=repository.getAllCars();
}
public LiveData<List<Car>>getGetAllCars(){
return getAllCars;
}
public void addCar( Car car)
{
repository.addCar(car);
}
public void updateCar(Car car){
repository.updateCar(car);
}
public void registerUser( User user)
{
repository.registerUser(user);
}
public void deleteCar(Car car)
{
repository.deleteCar(car);
}
public void deleteAll(){
repository.deleteAll();
}
}
</pre></code>
The main problem here is the myViewModel inside your RecyclerAdapter was never set a value. You may pass the instance of your ViewModel when instantiating the RecyclerAdapter. However, this is considered a bad idea.
A better approach would be creating a callback from RecyclerAdapter back to your Fragment. See: https://stackoverflow.com/a/53466188/9656117

How to implement the update method for Observer Pattern

I'm trying to adjust the observer pattern to my code, so in my case MSG0100 it's my Subject class that it updates the variable msg100PreselectionAplication, and the MainActivity class it's an concrete observer, and usually you have to create the Observer class, but my problem is that the MainActivity has to extend from that class and that's a problem because Java does not support multiple inheritance. Here is what i have until now, can some one give me an idea of what i need next? Please
MSG0100 class:
public class MSG0100 implements PreselectionAplicationUseCases {
private OnMsg100PreselectionChanged listener = null;
public void setOnMsgPreselectionChanged(OnMsg100PreselectionChanged listener) {
this.listener = listener;
}
public void setMsg100PreselectionAplication(boolean msg100PreselectionAplication) {
if(listener != null) {
listener.onPreselectionChanged(msg100PreselectionAplication);
}
}
}
interface OnMsg100PreselectionChanged {
void onPreselectionChanged(boolean isChanged);
}
Main activity class:
public class MainActivity extends AppCompatActivity {
private ExpandableListViewAdapter mExpandableListViewAdapter;
PreselectionAplicationUseCases preselectionAplicationUseCases;
public void Preselection(){
preselectionApplicationUseCases.setOnMsgPreselectionChanged(new OnMsg100PreselectionChanged {
#Override
void onPreselectionChanged(boolean isChanged) {
//do something with changed boolean
}
});
}
}
You should create Observer as an Interface which implemented by MainActivity like this:
interface Observer {
void update(Data data)
}
public class MainActivity extends AppCompatActivity implements Observer {
//…
#Override
public void update(Data data) {
// update your data to your UI here
}
//…
}
and modify your subject to receive observer
interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}
public class MSG0100 implements PreselectionAplicationUseCases, Subject {
private Data data = new Data();
private Observer o;
#Override
public void registerObserver(Observer o) {
this.o = o;
}
#Override
public void removeObserver(Observer o) {
o = null;
}
#Override
public void notifyObservers() {
o.update(data);
}
// ... other method that can update the data class
}
that is an Observer Pattern, but the way I see, you simply want to implement OnMsg100PreselectionChanged on Activity like:
public class MainActivity extends AppCompatActivity, OnMsg100PreselectionChanged {
void someMethod() {
MSG0100 msg0100 = new MSG0100();
msg0100.setOnMsgPreselectionChanged(this);
}
#Override
void onPreselectionChanged(boolean isChanged) {
}
}

How to fix "unchecked call to 'attachView(V)' as a member of raw type 'BasePresenter'"?

I have already looked up many answers here about this issue but for the life of me I can't seem to fix this problem on my end and I need some help.
BasePresenter:
public abstract class BasePresenter<V> {
private V mView;
public void attachView(V view) { mView = view; }
public void detachView() { mView = null; }
}
BaseFragment:
public abstract class BaseFragment<P extends BasePresenter> extends Fragment {
#Inject protected P mPresenter;
#Override
public void onResume() {
super.onResume();
mPresenter.attachView(this); // unchecked call to 'attachView(V)' as a member of raw type 'BasePresenter'
}
#Override
public void onPause() {
super.onPause();
mPresenter.detachView();
}
}
MyPresenter:
public class MyPresenter extends BasePresenter<MyPresenter.MyView> {
#Inject
public MyPresenter() {}
public interface MyView {}
}
MyFragment:
public class MyFragment extends BaseFragment implements MyPresenter.MyView {}
The problem is in the type-variable declaration:
class BaseFragment<P extends BasePresenter>
BasePresenter is a generic class, so you need to specify what its type parameter is. From this snippet:
mPresenter.attachView(this);
It would seem that you expect BaseFragment to be bound to the type-variable V in BasePresenter - so I would rewrite your BaseFragment declaration as follows:
abstract class BaseFragment<P extends BasePresenter<BaseFragment<P>>> { ... }
That should take care of the unchecked warning. That said, I strongly suspect that what you are really after is something like this:
abstract class BaseFragment<P extends BasePresenter<V>, V> { ... }
Where V is an independent type-variable modelling the 'view'.
Simple, instead of
public abstract class BaseFragment<P extends BasePresenter> extends Fragment {
It should be
public abstract class BaseFragment<V, P extends BasePresenter<V>> extends Fragment {
or
public abstract class BaseFragment<P extends BasePresenter<BaseFragment<P>>> extends Fragment {
or
public abstract class BaseFragment<V extends BaseFragment<V, P>, P extends BasePresenter<V>> extends Fragment {
Basically, make sure the BasePresenter is parametrized with something.
EDIT:
Okay, based on what you're actually trying to do, you should do it like this:
public abstract class BasePresenter<V> {
private V mView;
public void attachView(V view) { mView = view; }
public void detachView() { mView = null; }
}
public abstract class BaseFragment<V extends BaseFragment<V, P>, P extends BasePresenter<V>> extends Fragment {
protected abstract P getPresenter();
#Override
public void onResume() {
super.onResume();
getPresenter().attachView(this); // unchecked call to 'attachView(V)' as a member of raw type 'BasePresenter'
}
#Override
public void onPause() {
super.onPause();
getPresenter().detachView();
}
}
public class MyPresenter extends BasePresenter<MyPresenter.MyView> {
#Inject
public MyPresenter() {}
public interface MyView {}
}
public class MyFragment extends BaseFragment<MyFragment, MyPresenter> implements MyPresenter.MyView {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
MyFragmentComponent component = ((MainActivity)getActivity()).getComponent().myFragmentComponent();
component.inject(this);
View view = inflater.inflate(R.layout.blah, container, false);
ButterKnife.bind(this, view);
return view;
}
}
EDIT2: Based on provided example:
public class RexTester {
// MAIN CLASS
static class Rextester {
public static void main(String args[]) {
new MyFragment();
}
}
// MVP CODE
interface BaseView {}
final static class MyPresenter extends BasePresenter<MyPresenter.MyView> {
public MyPresenter() {}
public void executeAction() {
mView.onCallback();
}
interface MyView extends BaseView {
void onCallback();
}
}
abstract static class BasePresenter<V extends BaseView> {
protected V mView;
public void attachView(V view) { mView = view;}
public void detachView() { mView = null; }
}
final static class MyFragment extends BaseFragment<MyPresenter.MyView, MyPresenter> implements MyPresenter.MyView {
private MyPresenter mPresenter;
public MyFragment() {
mPresenter = new MyPresenter();
onResume(); // Mock onResume() lifecycle event!
mPresenter.executeAction();
onPause(); // Mock onPause() lifecycle event!
}
protected MyPresenter getPresenter() {
return mPresenter;
}
#Override
protected MyPresenter.MyView getThis() {
return this;
}
public void onCallback() {
System.out.println("Hello AndroidMVP!");
}
}
abstract static class BaseFragment<V extends BaseView, P extends BasePresenter<V>> extends Fragment implements BaseView {
protected abstract P getPresenter();
protected void onResume() {
super.onResume();
getPresenter().attachView(getThis());
}
protected abstract V getThis();
protected void onPause() {
super.onPause();
getPresenter().detachView();
}
}
// ANDROID FRAMEWORK MOCK
abstract static class Fragment {
protected void onResume() {}
protected void onPause() {}
}
}

Access var from MainActivity in another Extended class

So I need to have access to a variable from MainActivty from another class. what's the best way to do so. Below is the scenario but I cannot call frag.receiveInt(give_this_int_to_fragment);
MainActivity.java:
import com.me.fragments.FragmentExtender
public class MainActivity{
int give_this_int_to_fragment;
protected void onCreate(...){
Fragment frag = new FragmentExtender();
give_this_int_to_frag = new int();
frag.receiveInt(give_this_int_to_frag);
}
}
FragmentExtender.java:
public class FragmentExtender extends Fragment{
int receive_int_from_main;
public View onCreateView(...){...}
receiveInt(int_from_main){
receive_int_from_main = int_from_main;
}
}
I'm not trying to create a duplicate variable, just a pointer to that variable in MainActivity if you catch my drift.
Create getter and setter for that variable in Activity
public class MainActivity{
int give_this_int_to_fragment;
protected void onCreate(...){
Fragment frag = new FragmentExtender();
}
}
public int getgive_this_int_to_fragment(){
return give_this_int_to_fragment;
}
public void getgive_this_int_to_fragment(int var){
give_this_int_to_fragment = var;
}
Now, in fragment you can use getActivity() to get activity context and then call getter
public class FragmentExtender extends Fragment{
public View onCreateView(...){
//....
int var = ((MainActivity) getActivity()).getgive_this_int_to_fragment();
}
}
The more elegant way will be to implement an interface in the Fragment and make the app inherit from it. That way you can comunicate that way.
interface FragmentInterface{
Object getMainValue();
void passValueToMain(Object obj);
}
With this code, you just have to add it to the MainActivity declaration and in the fragment constructor
public class MainActivity implements FragmentInterface{
int give_this_int_to_fragment;
protected void onCreate(...){
Fragment frag = new FragmentExtender();
....
}
}
And then in the Fragment
public class FragmentExtender extends Fragment{
private FragmentInterface mInterface;
int receive_int_from_main;
public View onCreateView(...){...}
#Override
public void onAttach(Context context) {
super.onAttach(context);
setListeners(context);
}
//This is for pre Marshmallow versions
#SuppressWarnings("deprecation")
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
setListeners(activity);
}
}
private void setListeners(Object object) {
if (object instanceof FragmentInterface) {
mListener = (FragmentInterface) object;
} else {
throw new RuntimeException(object.toString()
+ " must implement FragmentInterface");
}
}
}
This will work for any fragment and any activity that implement them

Java class's field dynamic cast

I'm working on my abstract swt mvc controller noob-class:
Here are code's snippets:
public abstract class Controller {
protected View view;
public Controller(View v) {
view = v;
}
protected void render() {
data();
view.setData(data);
view.render();
listeners();
if (display)
view.open();
}
protected void data() {}
protected void listeners() {}
}
AboutController.java (represends new window):
public class AboutController extends Controller {
public AboutController() {
super(new AboutView());
super.render();
}
}
And I've faced with an obstacle: in abstract contoller i have a field View view, but it's child classes can represend a sub-class of View (like AboutView that extends View), and I cant access to non-View fields and methods (that are new in AboutView).
Can i clarify the class's field view in it's child-classes?
I understand that most likely this is a bug in my classes's architecture, but i cant figure out what to do.
The best / most idiomatic way is to use Generics.
public abstract class Controller<T extends View> {
protected T view;
public Controller(T v) {
view = v;
}
protected void render() {
data();
view.setData(data);
view.render();
listeners();
if (display)
view.open();
}
protected void data() {}
protected void listeners() {}
}
public class AboutController extends Controller<AboutView> {
public AboutController() {
super(new AboutView());
super.render();
}
public void doSomething() {
view.getAboutStuff();
}
}

Categories

Resources