接口和抽象类相关面试题
20.接口和抽象类相关.
原始定义:
抽象类,java中可定义一些不含方法体的方法,它的实现交给该类的子类根据自己的情况去实现,这样的方法就是抽象方法,包含抽象方法的类叫做抽象类.必须用abstract来修饰.只需声明,不需要实现.含有抽象方法的类必须被声明为抽象类.
抽象类的子类必须覆盖所有的抽象方法后才能被实例化,否则这个子类还是抽象类.
抽象类中的方法不全是抽象的,但有抽象方法的肯定是抽象类.
接口:如果一个抽象类中所有的方法都是抽象的,那么就可以用接口来定义.也就是接口.
接口是抽象方法和常量值的定义的集合.
本质上,接口是一种特殊的抽象类.这种抽象类只包含常量和方法的定义,而没有变量和方法的实现.
1. 接口中的成员都是public.,接口中的变量标识为:public static final.
2. A接口可以用extends去继承B接口.
3. 用implements关键字去实现一个接口中定义的部分方法.
4. 一个类可以继承一个父类的同时,实现一个或者多个接口.extends必须位于implements之前.
面试题:
接口是否可以继承接口? 接口可以继承接口.
抽象类是否可以实现接口? 抽象类可以实现(implements)接口,
抽象类是否可以继承具体类? 可以.
抽象类中是否可以有静态的main方法? 可以.
备注:
只要记住,抽象类与普通类的唯一区别就是不能创建实例对象和允许有abstrct方法!
21.写clone()方法,通常都有一行代码,为什么?
Clone有缺省行为,super.clone();因为首先要把父类中的成员复制到位,然后才是复制自己的成员.
Object类有一个clone方法,用来创建并返回此对象的一个副本,这个方法是protected的,我们自已的类要使用clone方法,就必须扩大访问权限为public,如:
public Object clone () throwsCloneNotSupportedException {super.clone(); }
22.abstractclass和interface有什么区别?
1.抽象类可以有构造方法,接口不可以.
2.抽象类中可以有普通的成员变量,普通的非抽象方法.接口不可以.
3.抽象类中的抽象方法的访问类型可以说public,protected和默认类型,,但接口的抽象方法只能是public,默认即为public abstract类型.
4.抽象方法可以包含静态方法,但接口不可以.
5.抽象类和接口中都可以包含静态成员变量.抽象类中静态成员变量的访问类型可以任意.但接口只能是public static final类型(默认)
6.一个类可以实现多个接口,但只能继承一个抽象类.
.两者在应用上的区别如下:
接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约.
而抽象类在代码实现方面发挥作用,可以实现代码的重用.例如,模块设计模式是抽象类的一个典型应用,假设某个羡慕的所有Servlet类都要用相同的方式进行权限判断,记录访问日志和处理异常,那么就可以定义一个抽象的基类,让所有的Servlet都继承这个抽象基类,在抽象基类的service方法中完成权限判断,记录访问日志和处理异常的代码,让各个子类中只是完成各自的业务逻辑代码,伪代码如下:
- public abstract class BaseServlet extendsHttpServlet
- {
- publicfinal void service(HttpServletRequest request, HttpServletResponse response)throws IOExcetion,ServletException
- {
- //记录访问日志
- //进行权限判断
- if(具有权限)
- {
- try
- {
- doService(request,response);
- }
- catch(Excetpione)
- {
- //记录异常信息
- }
- }
- }
- protectedabstract void doService(HttpServletRequest request, HttpServletResponseresponse) throws IOExcetion,ServletException;
- //注意访问权限定义成protected,显得既专业,又严谨,因为它是专门给子类用的
- }
- public class MyServlet1 extends BaseServlet
- {
- protected voiddoService(HttpServletRequest request, HttpServletResponse response) throwsIOExcetion,ServletException
- {
- //本Servlet只处理的具体业务逻辑代码
- }
- }
public abstract class BaseServlet extendsHttpServlet { publicfinal void service(HttpServletRequest request, HttpServletResponse response)throws IOExcetion,ServletException { //记录访问日志 //进行权限判断 if(具有权限) { try { doService(request,response); } catch(Excetpione) { //记录异常信息 } } } protectedabstract void doService(HttpServletRequest request, HttpServletResponseresponse) throws IOExcetion,ServletException; //注意访问权限定义成protected,显得既专业,又严谨,因为它是专门给子类用的 } public class MyServlet1 extends BaseServlet { protected voiddoService(HttpServletRequest request, HttpServletResponse response) throwsIOExcetion,ServletException { //本Servlet只处理的具体业务逻辑代码 } }
父类方法中间的某段代码不确定,留给子类干,就用模板方法设计模式。
23. abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?
貌似都不行
abstract的method 不可以是static的,因为抽象的方法是要被子类实现的,而static与子类扯不上关系!
native方法表示该方法要用另外一种依赖平台的编程语言实现的,不存在着被子类实现的问题,所以,它也不能是抽象的,不能与abstract混用。例如,FileOutputSteam类要硬件打交道,底层的实现用的是操作系统相关的api实现,例如,在windows用c语言实现的,所以,查看jdk 的源代码,可以发现FileOutputStream的open方法的定义如下:
private native void open(String name)throws FileNotFoundException;
如果我们要用java调用别人写的c语言函数,我们是无法直接调用的,我们需要按照java的要求写一个c语言的函数,又我们的这个c语言函数去调用别人的c语言函数。由于我们的c语言函数是按java的要求来写的,我们这个c语言函数就可以与java对接上,java那边的对接方式就是定义出与我们这个c函数相对应的方法,java中对应的方法不需要写具体的代码,但需要在前面声明native。
关于synchronized与abstract合用的问题,我觉得也不行,因为在我几年的学习和开发中,从来没见到过这种情况,并且我觉得synchronized应该是作用在一个具体的方法上才有意义。而且,方法上的synchronized同步所使用的同步锁对象是this,而抽象方法上无法确定this是什么。