![](/img/trans.png)
[英]Abstract method from an abstract superclass as a static method within the subclass
[英]What happened when I called a method from a subclass from the abstract superclass activity?
我想从我的超类(扩展活动)中调用一个子类函数。 但是,我找不到子类的实例,所以我只是天真地尝试将我的抽象超类降级,并调用它的方法来查看会发生什么。 我没想到这会起作用-超类怎么知道在哪个实例上调用该方法?
public abstract class RootActivity extends Activity{
private flag someCondition;
@Override
protected void onCreate(Bundle savedInstanceState){
//...
}
// ...
public void startJob(JobAction.Id jobaction){
Log.d("Zlatan", "started a job");
if (!jobaction.someCondition){
return;
}else{
((SpecificJob) this).dontDelete(); //<--- What have I done?
startSomeLongAsynchronousJob(someCondition);
Log.d("Zlatan", "calling finish");
finish();
}
}
// ...
public void someOtherFunction(){
finish();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event){
//...
startJob(JobAction.SOMEENUM); //Startjob is being called in the superclass
}
}
}
我这里有一个子类。 该活动是由另一个活动启动的,我在此处也包含了清单片段。
public class SpecificJob extends SomeClassThatExtendsRootActivity{
//SomeClassThatExtendsRootActivity extends RootActivity - I've ommitted it
private boolean flag = false;
@Override
public void onCreate(Bundle bundle){
super.onCreate(bundle);
//...
}
// ... some code ...
public void dontDelete(){ //Not static
flag = true;
Log.d("Zlatan", "I set flag"); //This doesn't appear in log
}
@Override
public void onDestroy(){
Log.d("Zlatan", "When finishing, flag is now " + flag);
}
}
<activity
android:name=".SpecificJob"
android:label="@string/TXT_BOOKMARKS"
android:icon="@drawable/ic_launcher"
android:theme="@style/stuff"
android:launchMode="singleTask"
android:windowSoftInputMode="stateHidden"
android:taskAffinity=".SpecificJob">
<intent-filter>
<action android:name="com.me.feature.SOME_WORKFLOW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="concurrency"
android:value="DEFAULT_CONCURRENCES|printer"
/>
</activity>
令我惊讶的是,没有错误或崩溃。 我的结果是
D/Zlatan started a job
D/Zlatan calling finish
D/Zlatan﹕ When finishing, flag is now false
我看不到我在SpecificJob.dontDelete()中编写的日志。 我的问题是
1)这在运行时做了什么? 为什么我看不到“我设置了标志”,为什么它没有崩溃?
2)如何最好地从RootActivity调用SpecificJob中的函数?
直到运行时才强制取消强制转换,并且当您从RootActivity继承SpecificJob并仅在SpecificJob上调用startJob()时,结果对象仍为SpecificJob类型。 这意味着可以毫无问题地进行投射。 如果要扩展RootActivity并尝试在此新类上调用startJob(),它将无法正常工作。
您不应该从超类调用子类。 超类不应该知道如何扩展它。 可能有更好的方法,您为什么要这样做?
更新:因此,将RootActivity及其继承的所有类将使用的所有清理代码放入RootActivity的onDestroy方法中。
public abstract class RootActivity extends Activity{
@Override
public void onDestroy(){
// All cleanup code common to inherited classes goes here
}
}
然后在SpecificJob中调用super.onDestroy,然后调用SpecificJob唯一的任何代码。
public class SpecificJob extends SomeClassThatExtendsRootActivity{
@Override
public void onDestroy(){
super.onDestroy();
// All cleanup code unique to this class goes here
}
}
如前所述,这是有效的,因为对象仅在运行时检查“知道”其类型和类型强制转换。 因此,如果在SpecificJob
实例上调用startJob()
它将起作用。 但是,如果在另一个RootActivity
子类的实例上调用该方法,则将在运行时获得异常。 这也是为什么您应尽可能避免类型转换的原因。
在这种特殊情况下,以类型安全的方式编写代码很容易。 只需向dontDelete()
添加方法dontDelete()
的RootActivity
,就像这样
protected abstract void dontDelete();
这迫使具体的子类实现该方法,并使类型强制转换不再必要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.