(一) 抽取Activity基类--BaseActivity

为什么要抽取Activity基类?

主要原因有两个:
第一个原因是方便代码编写,减少重复代码,快速开发。
第二个原因是优化代码结构,降低耦合度,方便修改。
还有一些其他原因:提高代码可读性,代码显得井井有条,看起来很优美。

举例

比如我们可以抽取一个最简单的BaseActivity。

public abstract class MyBaseActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 初始化ui
        initView();
        // 初始化数据
        initData();
        // 添加监听器
        initListener();
    }

    // 初始化ui
    protected abstract void initView();

    // 初始化数据
    protected abstract void initData();

    // 添加监听器
    protected abstract void initListener();
}

其中initView()用来初始化ui,initData()用来处理数据,initListener()用来给控件添加监听器。注意BaseActivity类为抽象类,initView()、initData()和initListener()这三个方法为抽象方法,子类必须实现。

那么我们怎么使用BaseActivity呢?

我们只需要将我们需要写的Activity继承BaseActivity即可,如:

public class MyActivity extends MyBaseActivity {
    @Override
    protected void initView() {
        // 用来出来初始化视图
        // 别忘了setContentView(R.layout.XXX);加载布局文件
        // findViewByid
    }

    @Override
    protected void initData() {
        // 用来初始化数据以及处理数据
    }

    @Override
    protected void initListener() {
        // 用来给控件添加监听器,可以在里面写如btn.setonClickListener(){}; .....等监听器。
    }
}

注意在initView()中别忘了使用setContentView(R.layout.xxx)方法加载布局文件。
这样看起来是不是很有层次?是不是可读性更高?和所有代码全写在oncreate()方法中相比是不是代码优美许多?
你可能会问,这代码量和不用基类差不多吗?它的好处当然不止如此,上面的写法只是最简单的写法,让你体会一下这种写法而已。我们可以BaseActivity添加一些公共的代码。如:
我们可以在BaseActivity中添加这样一个方法

public void openActivity(Class<?> targetActivityClass, Bundle bundle) {
        Intent intent = new Intent(this, targetActivityClass);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivity(intent);
    }

这样我们就不用每次跳转Activity的时候都去new一个Intent,然后startActivity(intent);有了它我们只需一行代码就搞定:openActivity(xxxActivity,bundler)
但是你会问,我们大部分时候是不用携带参数bundle的,那怎么办?
那么我们可以在此基础上再添加几个方法:
这是不携带bundle参数的

public void openActivity(Class<?> targetActivityClass) {
        openActivity(targetActivityClass, null);
    }

这是打开新的Activity并关闭当前Activity的方法:

public void openActivityAndCloseThis(Class<?> targetActivityClass) {
        openActivity(targetActivityClass);
        this.finish();
    }

我们还可以添加这样的方法:

// short吐司
    public void showShort(String text) {
        Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
    }

    // long吐司
    public void showLong(String text) {
        Toast.makeText(this, text, Toast.LENGTH_LONG).show();
    }

那么我们写吐司的时候就不用写那么长一段代码了,只需showShort(text),showLong(text)就可以实现了。

还有的时候我们需要添加许多监听器的时候,我们可以给BaseActivity实现onClickListener()接口:

public abstract class MyBaseActivity extends Activity implements OnClickListener {......}

然后再我们自己的Acitvity中重写onClick()方法即可:

public class MyActivity extends MyBaseActivity {
    @Override
    protected void initView() {
        // 用来出来初始化视图
        // 别忘了setContentView(R.layout.XXX);加载布局文件
        // findViewByid
    }

    @Override
    protected void initData() {
        // 用来初始化数据以及处理数据
    }

    @Override
    protected void initListener() {
        // 用来给控件添加监听器,可以在里面写如btn.setonClickListener(){}; .....等监听器。
    }

    @Override
    public void onClick(View arg0) {
        switch (arg0.getId()) {
        //控件id
        case R.id.xxx:
            break;
        default:
            break;
        }
    }
}

还有一些时候我们的Activity需要用到Fragment的时候,我们的基类BaseActivity可以通过继承FragmentActivity实现:
public abstract class MyBaseActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 初始化ui
initView();
// 初始化数据
initData();
// 添加监听器
initListener();
}

// 初始化ui
protected abstract void initView();

// 初始化数据
protected abstract void initData();

// 添加监听器
protected abstract void initListener();

/*
 * ************Fragement相关方法************************************************
 * 
 */
private Fragment currentFragment;

/** Fragment替换(当前destrory,新的create) */
public void fragmentReplace(int target, Fragment toFragment, boolean backStack) {
    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    String toClassName = toFragment.getClass().getSimpleName();
    if (manager.findFragmentByTag(toClassName) == null) {
        transaction.replace(target, toFragment, toClassName);
        if (backStack) {
            transaction.addToBackStack(toClassName);
        }
        transaction.commit();
    }
}

/** Fragment替换(核心为隐藏当前的,显示现在的,用过的将不会destrory与create) */
public void smartFragmentReplace(int target, Fragment toFragment) {
    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    // 如有当前在使用的->隐藏当前的
    if (currentFragment != null) {
        transaction.hide(currentFragment);
    }
    String toClassName = toFragment.getClass().getSimpleName();
    // toFragment之前添加使用过->显示出来
    if (manager.findFragmentByTag(toClassName) != null) {
        transaction.show(toFragment);
    } else {// toFragment还没添加使用过->添加上去
        transaction.add(target, toFragment, toClassName);
    }
    transaction.commit();
    // toFragment更新为当前的
    currentFragment = toFragment;
}

/***********************************************************************/

}

注意FragmentActivity和Fragment使用supportV4包里的

其中的fragmentReplace(int target, Fragment toFragment, boolean backStack)方法和smartFragmentReplace(int target, Fragment toFragment)方法是用来处理Fragment切换的,我们切换fragment的时候只需调用这两个方法即可,不用每次敲一大段冗余的代码。

诸如此类,只要我们多个Activity可能要用的方法都可以写到BaseActivity中,这样就可以减少一些重复的代码了。读者可自行添加自己需要的一些公共方法到BaseActivity中。

下面是笔者使用的比较多的一个BaseActivity

/**
 * BaseActivity
 * 
 * @author RaphetS
 * 
 */
public abstract class BaseActivity extends FragmentActivity {

    /** 用来保存所有已打开的Activity */
    private static Stack<Activity> listActivity = new Stack<Activity>();

    /** 提示信息 **/
    private Toast mToast;

    /** 记录上次点击按钮的时间 **/
    private long lastClickTime;
    /** 按钮连续点击最低间隔时间 单位:毫秒 **/
    public final static int CLICK_TIME = 500;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 设置activity为无标题栏
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        // 将activity推入栈中
        listActivity.push(this);
        // 初始化ui
        initUI();
        // 初始化数据
        initData();
        // 事件监听
        initListener();

    }

    /** 初始化ui **/
    protected abstract void initUI();

    /** 初始化数据 **/
    protected abstract void initData();

    /** 初始化监听 **/
    protected abstract void initListener();

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        saveInstanceState(outState);
        super.onSaveInstanceState(outState);
    }

    /** 保存activity状态 **/
    protected void saveInstanceState(Bundle outState) {

    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();

    }

    public void onBack(View v) {
        finish();

    }

    @Override
    protected void onResume() {
        super.onResume();

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 从栈中移除当前activity
        if (listActivity.contains(this)) {
            listActivity.remove(this);
        }

    }

    /********************** activity跳转 **********************************/
    public void openActivity(Class<?> targetActivityClass) {
        openActivity(targetActivityClass, null);
    }

    public void openActivity(Class<?> targetActivityClass, Bundle bundle) {
        Intent intent = new Intent(this, targetActivityClass);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivity(intent);
    }

    public void openActivityAndCloseThis(Class<?> targetActivityClass) {
        openActivity(targetActivityClass);
        this.finish();
    }

    public void openActivityAndCloseThis(Class<?> targetActivityClass, Bundle bundle) {
        openActivity(targetActivityClass, bundle);
        this.finish();
    }

    /***************************************************************/

    /** 验证上次点击按钮时间间隔,防止重复点击 */
    public boolean verifyClickTime() {
        if (System.currentTimeMillis() - lastClickTime <= CLICK_TIME) {
            return false;
        }
        lastClickTime = System.currentTimeMillis();
        return true;
    }

    /** 收起键盘 */
    public void closeInputMethod() {
        // 收起键盘
        View view = getWindow().peekDecorView();// 用于判断虚拟软键盘是否是显示的
        if (view != null) {
            InputMethodManager inputmanger = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
            inputmanger.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }

    /**
     * 获取string
     * 
     * @param mRid
     * @return
     */
    public String getStringMethod(int mRid) {
        return this.getResources().getString(mRid);
    }

    /**
     * 获取demin
     * 
     * @param mRid
     * @return
     */
    protected int getDemonIntegerMethod(int mRid) {
        return (int) this.getResources().getDimension(mRid);
    }

    /**
     * 关闭所有(前台、后台)Activity,注意:请已BaseActivity为父类
     */
    protected static void finishAll() {
        int len = listActivity.size();
        for (int i = 0; i < len; i++) {
            Activity activity = listActivity.pop();
            activity.finish();
        }
    }

    /***************** 双击退出程序 ************************************************/
    private long exitTime = 0;

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if (KeyEvent.KEYCODE_BACK == keyCode) {
            // 判断是否在两秒之内连续点击返回键,是则退出,否则不退出
            if (System.currentTimeMillis() - exitTime > 2000) {
                Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show();
                // 将系统当前的时间赋值给exitTime
                exitTime = System.currentTimeMillis();
            } else {
                finishAll();
            }
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    /*
     * ************Fragement相关方法************************************************
     * 
     */
    private Fragment currentFragment;

    /** Fragment替换(当前destrory,新的create) */
    public void fragmentReplace(int target, Fragment toFragment, boolean backStack) {
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        String toClassName = toFragment.getClass().getSimpleName();
        if (manager.findFragmentByTag(toClassName) == null) {
            transaction.replace(target, toFragment, toClassName);
            if (backStack) {
                transaction.addToBackStack(toClassName);
            }
            transaction.commit();
        }
    }

    /** Fragment替换(核心为隐藏当前的,显示现在的,用过的将不会destrory与create) */
    public void smartFragmentReplace(int target, Fragment toFragment) {
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        // 如有当前在使用的->隐藏当前的
        if (currentFragment != null) {
            transaction.hide(currentFragment);
        }
        String toClassName = toFragment.getClass().getSimpleName();
        // toFragment之前添加使用过->显示出来
        if (manager.findFragmentByTag(toClassName) != null) {
            transaction.show(toFragment);
        } else {// toFragment还没添加使用过->添加上去
            transaction.add(target, toFragment, toClassName);
        }
        transaction.commit();
        // toFragment更新为当前的
        currentFragment = toFragment;
    }

    /***********************************************************************/
}
<think>首先,用户的问题是:“我想了解基类-子类的设计模式类型 请问面向对象编程中基类和子类属于哪种设计模式”。用户想知道基类和子类的概念属于哪种设计模式。 从系统级指令中,我需要: - 使用$...$格式表示行内数学表达式(但这里可能不需要数学表达式)。 - 独立公式使用$$...$$格式并单独成段(但这里可能没有公式)。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 - 回答结构清晰,帮助用户逐步解决问题。 - 参考站内引用:[^1]、[^2]、[^3]。 站内引用: - [^1]: 继承是面向对象编程(OOP)中的项基本机制... 它描述了继承的基本概念。 - [^2]: 简单工厂模式、工厂方法模式、抽象工厂模式。 - [^3]: 原型模式和结构型模式。 用户的问题是关于基类-子类的设计模式类型。在面向对象编程中,基类和子类是继承机制的体现,但设计模式是更高层次的抽象。设计模式如工厂模式、单例模式等,是解决特定问题的模板。 基类和子类本身不是种设计模式;它们是面向对象编程的基本构建块。设计模式如“模板方法模式”或“工厂方法模式”可能使用继承。 参考引用: - [^1] 直接谈到了继承:基类和子类的关系是继承。 - [^2] 提到了工厂模式,其中工厂方法模式使用继承。 - [^3] 提到了原型模式。 所以,基类-子类不属于个特定的设计模式;它是OOP的核心概念。但些设计模式依赖于继承,例如: - **模板方法模式**:在基类中定义个算法的骨架,子类实现特定步骤。 - **工厂方法模式**:定义个创建对象的接口,但让子类决定实例化哪个类。 - **策略模式**:定义系列算法,将它们封装起来,并使它们可以互换。 在回答中,我应该澄清基类-子类不是设计模式本身,而是被设计模式使用。 回答结构: 1. **澄清概念**:解释基类和子类是继承机制的部分,不是种设计模式。 2. **相关设计模式**:介绍些使用继承的设计模式。 3. **引用支持**:自然地引用站内内容。 4. **生成相关问题**:在末尾添加相关问题。 使用中文回答。 最终回答应包括: - 引言:基类-子类在OOP中的角色。 - 解释:它们不属于特定设计模式,但被多个模式使用。 - 例子:如模板方法模式、工厂方法模式。 - 引用:在相关段落末尾添加[^1]、[^2]等。 - 相关问题:生成3个相关问题。 相关问题示例: 1. 什么是模板方法模式? 2. 工厂方法模式如何利用继承? 3. 在OOP中,继承和组合有什么区别? 确保引用自然: - 例如,“继承是面向对象编程的基本机制[^1]。” - 对于设计模式,引用[^2]。 完整回答大纲: 1. 开头:直接回答用户问题。 2. 中间:解释并举例。 3. 结尾:总结并添加相关问题。</think>### 基类-子类在设计模式中的定位 在面向对象编程(OOP)中,基类(父类)和子类(派生类)的关系本质上是**继承机制**的核心组成部分,而不是种独立的“设计模式”。继承允许子类复用基类的属性和方法,同时支持扩展或重写功能,这是OOP的基本特性[^1]。设计模式则是更高层次的、可复用的解决方案模板,用于解决特定软件设计问题。基类-子类结构常被用于实现某些设计模式,特别是那些依赖于继承的模式,如模板方法模式或工厂方法模式。下面我将逐步解释: 1. **基类-子类不是设计模式,而是设计模式的构建基础** 基类-子类关系直接源于OOP的继承概念,它本身不属于某个设计模式类别。相反,它是许多设计模式的基础构件。例如,在模板方法模式中,基类定义个算法的骨架(如操作步骤),而子类实现具体的细节,这体现了继承的“扩展”特性[^1]。类似地,工厂方法模式使用基类定义创建对象的接口,子类负责实例化具体对象[^2]。因此,基类-子类更像是设计模式的“原材料”,而非模式本身。 2. **常见使用基类-子类的设计模式** 以下是些典型的设计模式,它们依赖于基类-子类继承机制: - **模板方法模式(Template Method Pattern)**:基类定义个操作流程的框架(如算法步骤),子类通过重写方法来实现具体行为。例如,个数据处理基类可能定义`process()`方法,子类实现`readData()`和`transformData()`等细节[^2]。 - **工厂方法模式(Factory Method Pattern)**:基类定义个创建对象的抽象方法(如`createProduct()`),子类决定实例化哪个具体类。这避免了客户端代码直接依赖具体类,提升了灵活性[^2]。 - **策略模式(Strategy Pattern)**:基类定义组算法接口,子类实现不同算法策略(如排序算法)。客户端可以动态切换策略,而无需修改基类代码。 这些模式都利用继承来实现“变化点”的封装,但基类-子类本身不是模式,而是实现手段。 3. **为什么不是所有设计模式都依赖基类-子类** 设计模式分为创建型、结构型和行为型三类。基类-子类主要应用于行为型模式(如模板方法)和部分创建型模式(如工厂方法)。但其他模式可能使用组合而非继承,例如: - **组合模式(Composite Pattern)**:使用对象树结构来处理部分-整体关系,不强制依赖继承。 - **原型模式(Prototype Pattern)**:通过复制现有对象创建新实例,而不是通过子类化[^3]。 因此,继承只是设计模式的种工具,而非模式本身。 总之,基类-子类属于OOP的继承机制,而非具体设计模式。但在实际应用中,它是实现如模板方法或工厂方法等模式的关键。如果您有特定场景(如设计个可扩展的框架),我可以进步解释如何选择合适模式。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值