- Java 基础之继承与接口的区别
- 抽象类:
抽象类体现了数据抽象的思想,是实现多态的一种机制。它定义了一组抽象的方法,至于这组抽象方法的具体表现形式由派生类来实现。同时抽象类提供了继承的概念,它的出发点就是为了继承,否则它没有存在的任何意义。所以说定义的抽象类一定是用来继承的,同时在一个以抽象类为节点的继承关系等级链中,叶子节点一定是具体的实现类。 在语法方面: 1.由abstract关键词修饰的类称之为抽象类。 2.抽象类中没有实现的方法称之为抽象方法,也需要加关键字abstract。 3.抽象类中也可以没有抽象方法,比如HttpServlet方法。 4.抽象类中可以有已经实现的方法,可以定义成员变量。
- 接口: 接口是用来建立类与类之间的协议,它所提供的只是一种形式,而没有具体的实现。同时实现该接口的实现类必须要实现该接口的所有方法,通过使用implements关键字。 接口是抽象类的延伸,java为了保证数据安全是不能多重继承的,也就是说继承只能存在一个父类,但是接口不同,一个类可以同时实现多个接口,不管这些接口之间有没有关系,所以接口弥补了抽象类不能多重继承的缺陷, 语法方面: 1.由interface关键词修饰的称之为接口; 2.接口中可以定义成员变量,但是这些成员变量默认都是public static final的常量。 3.接口中没有已经实现的方法,全部是抽象方法。 4.一个类实现某一接口,必须实现接口中定义的所有方法。 5.一个类可以实现多个接口。
区别: 一.语法层次上:如上所述。 二.设计层次上: 1、 抽象层次不同。抽象类是对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。 2、 跨域不同。抽象类所跨域的是具有相似特点的类,而接口却可以跨域不同的类。我们知道抽象类是从子类中发现公共部分,然后泛化成抽象类,子类继承该父类即可,但是接口不同。实现它的子类可以不存在任何关系,共同之处。例如猫、狗可以抽象成一个动物类抽象类,具备叫的方法。鸟、飞机可以实现飞Fly接口,具备飞的行为,这里我们总不能将鸟、飞机共用一个父类吧!所以说抽象类所体现的是一种继承关系,要想使得继承关系合理,父类和派生类之间必须存在"is-a" 关系,即父类和派生类在概念本质上应该是相同的。对于接口则不然,并不要求接口的实现者和接口定义在概念本质上是一致的, 仅仅是实现了接口定义的契约而已,相当于是"like-a"的关系。 3、 设计层次不同。对于抽象类而言,它是自下而上来设计的,我们要先知道子类才能抽象出父类,而接口则不同,它根本就不需要知道子类的存在,只需要定义一个规则即可,至于什么子类、什么时候怎么实现它一概不知。比如我们只有一个猫类在这里,如果你这是就抽象成一个动物类,是不是设计有点儿过度?我们起码要有两个动物类,猫、狗在这里,我们在抽象他们的共同点形成动物抽象类吧!所以说抽象类往往都是通过重构而来的!但是接口就不同,比如说飞,我们根本就不知道会有什么东西来实现这个飞接口,怎么实现也不得而知,我们要做的就是事前定义好飞的行为接口。所以说抽象类是自底向上抽象而来的,接口是自顶向下设计出来的。
onCreate Activity 创建时的初始化工作 如设置页面的ContentView、接收参数等.
onRestart 在Activity的onStop后重新启动时,回调onRestart
onStart 正在启动,即将开始,没有出现在前台,还无法和用户交互,可以理解为已经初始化完成,但是处于后台我们暂时没法看见。
onResume 可见了并且处于激活态,处于前台,和onStart最大的不同就是onStart是在后台已经初始化完,但是无法交互。
onPause 失去焦点不可以交互、处于后台。
onStop 即将停止,做一些稍微重量级回收类的工作
onDestory Activity即将被销毁,需要们做一些回收和资源释放类的工作。
方法 描述 是否能事后终止? 后接
onCreate()
首次创建 Activity 时调用。 您应该在此方法中执行所有正常的静态设置— 创建视图、将数据绑定到列表等等。系统向此方法传递一个 Bundle 对象,其中包含 Activity 的上一状态,不过前提是捕获了该状态(请参阅后文的保存 Activity 状态)。 始终后接
onStart()
。否 onStart()
onRestart()
在 Activity 已停止并即将再次启动前调用。 始终后接
onStart()
否 onStart()
onStart()
在 Activity 即将对用户可见之前调用。 如果 Activity 转入前台,则后接
onResume()
,如果 Activity 转入隐藏状态,则后接onStop()
。否 onResume()
或
onStop()
onResume()
在 Activity 即将开始与用户进行交互之前调用。 此时,Activity 处于 Activity 堆栈的顶层,并具有用户输入焦点。 始终后接
onPause()
。否 onPause()
onPause()
当系统即将开始继续另一个 Activity 时调用。 此方法通常用于确认对持久性数据的未保存更改、停止动画以及其他可能消耗 CPU 的内容,诸如此类。 它应该非常迅速地执行所需操作,因为它返回后,下一个 Activity 才能继续执行。 如果 Activity 返回前台,则后接
onResume()
,如果 Activity 转入对用户不可见状态,则后接onStop()
。是 onResume()
或
onStop()
onStop()
Activity 对用户不再可见时调用。如果 Activity 被销毁,或另一个 Activity(一个现有 Activity 或新 Activity)继续执行并将其覆盖,就可能发生这种情况。 如果 Activity 恢复与用户的交互,则后接
onRestart()
,如果 Activity 被销毁,则后接onDestroy()
。是 onRestart()
或
onDestroy()
onDestroy()
在 Activity 被销毁前调用。这是 Activity 将收到的最后调用。 当 Activity 结束(有人调用 Activity 上的 ),或系统为节省空间而暂时销毁该 Activity 实例时,可能会调用它。 您可以通过
finish()
方法区分这两种情形。
isFinishing()
是 无
正常生命周期
1.正常打开单个Activity,然后退出应用:
这种情况是最普通的状况,Activity的生命周期会按照上图从上到下的方式走。即:onCreate --> onStart --> onResume --> 运行--> 按返回键结束程序--> onPause-->onStop-->onDestory
打开一个Activity A,然后再打开另一个Activity B
对于A:onCreate --> onStart --> onResume --> A运行 --> A发出打开B的Intent --> onPause(A失去焦点)-->B可见-->onStop此时,会打开B,B同样会经历一个完整的Activity生命周期。等B结束,A再度可见的时候,A会经历:onRestart-->onStart-->onResume注意:B这个Activity是在A的onPause执行后才变成可见状态的,所以为了不影响B的显示,最好不要在onPause里执行一些耗时操作,可以考虑将这些操作放到onStop里,这时B已经可见了。
异常情况生命周期
情况1.资源相关的系统配置发生改变
资源相关的系统配置发生改变,举个例子。当前Activity处于竖屏状态的时候突然转成横屏,系统配置发生了改变,Activity就会销毁并且重建,其onPause, onStop, onDestory均会被调用。因为实在异常情况下终止的,所以系统会调用 onSaveInstanceState来保存当前Activity状态。这个方法是在onStop之前,与onPause没有固定的时序关系。当Activity重建的时候系统会把onSaveInstanceState所保存的Bundle作为对象传递给onRestoreInstanceState和onCreate方法。情况2:资源内存不足导致低优先级Activity被杀死
Activity优先级
前台Activity——正在和用户交互的Activity,优先级最高
可见但非前台Activity——Activity中弹出的对话框导致Activity可见但无法交互
后台Activity——已经被暂停的Activity,优先级最低
系统内存不足是,会按照以上顺序杀死Activity,并通过onSaveInstanceState和onRestoreInstanceState这两个方法来存储和恢复数据。
activity的启动模式
四种启动模式分别是standard(标准模式)、singleTop(栈顶复用模式)、singleTask(栈内复用模式)、singleInstance(单实例模式 - 加强的singleTask模式)
standard
- 系统默认启动模式
- 不论存在与否,都会重新创建一个新的实例
- 多实例实现,谁启动了这个Activity、那么这个Activity就运行在启动它那个Activity所在栈
singleTop
- 判断需要启动的Activity是否为任务栈栈顶 ,如果是,则不会重新创建,如果不是,则会重新创建
- 不重新创建时候,该Activity的 onNewIntent(Intent intent) 方法会被回调,通过该方法的参数,可以取出当前请求的信息;
- 系统可能会杀死该Activity,杀死之后,启动情况与第一次启动相同,所以有必要在onCreate与onNewIntent方法中调用同一个处理数据的方法
运用场景:常运用于通知栏弹出Notification,点击Notification跳转到指定的Activity,设置singleTop模式
singleTask
- 判断Activity所需任务栈内是否已经存在,如果存在,就把该Activity切换到栈顶(会导致在它之上的都会出栈)
- 如果所需任务栈都不存在,就会先创建任务栈再创建该Activity
- 可以理解为 顶置Activity+singleTop 的模式
运用场景:可用来退出整个应用。主界面activity设为singleTas模式,要退出应用时转到主activity,从而将主activity之上的activity都清除,然后重写主activity的onNewIntent()方法,在里面加上finish(),即可退出所有activity。这种模式还适用于做浏览器、微博之类的应用
singleInstance
- 拥有singleTask的所有特性之外,此模式Activity只能单独地位于一个新的任务栈中
- 也就是,Activity启动之后,就会独自在一个新的任务栈中,下次肯定不会重新创建该Activity,除非被系统杀死
运用场景:这种模式常运用于需要与程序分离的界面,如在SetupWizard(安装向导)中调用紧急呼叫就是适用这种模式
Intent和Intent-filter的匹配规则
1、Intent和Intent Filter的介绍
Intent是抽象的数据结构,包含了一系列描述某个操作的数据,使得程序在运行时可以在程序中不同组件间通信或启动不同的应用程序。
可以通过startActivity(Intent)启动一个Activity,sendBroadcast(Intent))发送广播发送给感兴趣的BroadcastReceiver组件,startService(android.content.Intent))启动service,bindService()绑定服务。
Intent Filter顾名思义就是Intent的过滤器,组件通过定义Intent Filter可以决定哪些隐式Intent可以和该组件进行通讯
Intent分为隐式(implicit)Intent和显式(explicit)Intent。
显式Intent通常用于在程序内部组件间通信,已经明确的定义目标组件的信息,所以不需要系统决策哪个目标组件处理Intent,如下
Intent intent =new Intent(CRListDemo.this, GoogleMapDemo.class); startActivity(intent);
其中CRListDemo和GoogleMapDemo都是用户自定义的组件,
隐式Intent不指明目标组件的class,只定义希望的Action及Data等相关信息,由系统决定使用哪个目标组件。如发送短信2.Intent和Intent-filter的匹配规则
Android系统通过对Intent和目标组件在AndroidManifest文件中定义的(也可以在程序中定义Intent Filter)进行匹配决定和哪个目标组件通讯。如果某组件未定义则只能通过显式的Intent进行通信。Intent的三个属性用于对目标组件选取的决策,分别是Action、Data(Uri和Data Type)、Category。匹配规则如下
- action匹配规则:要求intent中的action 存在 且 必须和过滤规则中的其中一个相同 区分大小写;
- category匹配规则:系统会默认加上一个android.intent.category.DEAFAULT,所以intent中可以不存在category,但如果存在就必须匹配其中一个;
- data匹配规则:data由两部分组成,mimeType和URI,要求和action相似。如果没有指定URI,URI但默认值为content和file(schema)
3.利用Intent调用其他常见程序
a. 发送短信
Uri uri = Uri.parse("smsto:15800000000"); Intent i=newIntent(Intent.ACTION_SENDTO, uri); i.putExtra("sms_body", "The SMS text"); startActivity(i);
b. 打电话
Uri dial = Uri.parse("tel:15800000000"); Intent i=newIntent(Intent.ACTION_DIAL, dial); startActivity(i);
c. 发送邮件
Uri email = Uri.parse("mailto:abc@126.com;def@126.com"); Intent i=newIntent(Intent.ACTION_SENDTO, email); startActivity(i);
d. 拍照
Intent i =newIntent(MediaStore.ACTION_IMAGE_CAPTURE); String folderPath= Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "AndroidDemo" +File.separator; String filePath= folderPath + System.currentTimeMillis() + ".jpg";newFile(folderPath).mkdirs(); File camerFile=newFile(filePath); i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(camerFile)); startActivityForResult(i,1);
e. 浏览网页
Uri web = Uri.parse("http://www.google.com"); Intent i=newIntent(Intent.ACTION_VIEW, web); startActivity(i);
f. 查看联系人
Intent i =newIntent(); i.setAction(Intent.ACTION_GET_CONTENT); i.setType("vnd.android.cursor.item/phone"); startActivityForResult(i,1);
-
onCreate Activity 创建时的初始化工作 如设置页面的ContentView、接收参数等.
-
onRestart 在Activity的onStop后重新启动时,回调onRestart
-
onStart 正在启动,即将开始,没有出现在前台,还无法和用户交互,可以理解为已经初始化完成,但是处于后台我们暂时没法看见。
-
onResume 可见了并且处于激活态,处于前台,和onStart最大的不同就是onStart是在后台已经初始化完,但是无法交互。
-
onPause 失去焦点不可以交互、处于后台。
-
onStop 即将停止,做一些稍微重量级回收类的工作
-
onDestory Activity即将被销毁,需要们做一些回收和资源释放类的工作。