2022-07-26 第4组 蒋萍 面向对象(6) 抽象类和接口
面向对象(6)抽象类和接口
- 抽象类不能直接实例化,可以通过多态的向上转型
可以把它(该抽象类)当一个类型使用,通过创建一个引用变量,类型为抽象类,指向非抽象的子类实例。
1、抽象类和抽象方法的使用:
-
抽象类中可以没有抽象方法,但包含有抽象方法的类一定是抽象类;
-
如果子类没有实现父类所有的抽象方法,子类必须定义为抽象类;(父类方法必须在子类实现)
“ 要么和我一样,要么实现我的所有抽象方法 ”
-
没有抽象构造方法,也没有抽象静态方法;
构造方法作用是对象初始化,在创建对象时用到,与abstract(无方法体)矛盾;
静态方法,与类相关,可直接调用的(一定有方法体),与abstract 矛盾,
4. 抽象类中可以有非抽象的构造方法,创建子类对象时可能调用;
// 父类(abstract)
public abstract class Father{
public Father(){
System.out.println("父类非抽象无参构造方法")
}
}
// 同一页面里只能出现一个 public 类
class Son extends Father{
public Son(){
System.out.println("子类无参构造方法")
}
}
//测试类
Father f = new Son(); // 父类引用指向子类对象
// 先执行父类无参构造,再走子类无参构造
/*
父类非抽象无参构造方法
子类无参构造方法
*/
关于继承的一点补充
-
当子类中有有参构造时,会先执行子类有参构造,再执行父类无参构造;
-
父类的无参构造方法总是先于子类无参构造方法执行;
-
子类和父类构造器在形式上要保持一致;
2、接口
- 接口中可以定义:
2.1 为什么要使用接口
可解决需要多重继承的问题:
*例如 *:要求实现防盗门(可开门关门, 开锁关锁)的功能,
分析 :
1、将防盗门定义为两个抽象类(门类和锁类)
让防盗门既具有门的功能又有锁的功能,可想到继承,但继承只能是单根继承,防盗门不可能既继承门又继承锁,于是,有了另外的一种定义:接口
2、防盗门继承门,实现锁的接口!
2.2 什么是接口 (interface)
- 系统对外提供的所有的服务,或者说接口就是一种能力(体现在实现接口方法上),
public interface MyInterface{
public void food();
//其他方法
}
注意: 接口里面所有方法都默认是:public abstract
接口中的变量都是静态常量——public static final(写不写明都是默认的)!!!
-
类描述对象的属性和方法。
-
接口则包含类要实现的方法。
-
类是类型,接口是能力,同一类型可以有不同的能力;
- 一个类只能继承一个类,但是一个类可以同时能实现多个接口。
- 一个接口能继承另一个接口,可以多重继承
2.3 接口的几个特性:
-
接口中的结构必须是
public
-
接口不可以直接拿被实例化;(常作为类型使用)
-
**实现类 **必须实现接口的所有方法,(除非实现类是抽象类);
接口里的方法都是抽象的。
-
实现类 可以实现多个接口;(弥补了单根继承的缺点)
- implements 、 多个接口使用逗号隔开。
-
在接口中的抽象方法默认是
public abstract
( 推荐省略不写 );接口中的常量默认是public abstract final
( 推荐省略不写 )
2.3.1 其他要记住的
JDK7之前:接口中只能定义抽象方法,不能有属性,不能有方法(也可以放静态常量和静态方法)
JDK8 之后:接口中只能定义抽象方法,不能有属性,可以有默认方法和静态方法、静态常量
JDK7~JDK8:默认方法(有方法体)、静态方法(有方法体)
public default void info(){} // 默认方法
public static final String NAME = "姓名"; // 静态常量
抽象方法只能在抽象类里
2.4 实现接口(implements)
需求:实现防盗门功能
门继承(is-a关系),锁为接口(has-a关系),
分析:
定义1、父门类(abstract),2、子门类去继承,3、锁类为接口实现开关锁功能;4、测试类
// 防盗门
public class TheftDoor extends Door implements DoorLock {
// Door类和DoorLock 类里的方法重写实现功能
}
注意:多接口的实现
// 防盗门
public class TheftDoor extends Door implements DoorLock,接口2,接口3,…… {
// 类里的方法重写实现功能
}
3、接口使用
3.1 接口中的成员变量
默认都是 public static final
的,必须显式初始化。
3.2 接口中的方法
- 默认都是 public abstract 的;
- 除了成员变量和方法且都是abstract的(其一也可),不能包含其他。
- 接口没有构造方法,不能被实例化;
- 一个接口不能实现另外的接口(只有类能实现接口),但可以继承多个其他接口;
- 一个类必须实现接口抽象方法(
implements
),除非这个类也是抽象类;
4、接口是一种约定
有些接口只有名称
5、面向接口编程
程序设计时面向接口的约定而不考虑具体实现
6、抽象类 vs 接口
抽象方法只能在抽象类里
6.1 相同点:
- 代表系统的抽象层;
- 都不能被实例化,(接口和抽象类不可直接创建对象);
- 都能包含抽象的方法,用于描述系统提供的服务,不必提供具体实现
6.2 不同点
- 在抽象类中可以为部分方法提供默认实现(普通方法),而接口中只能包含抽象方法,(接口一旦公布,不可随意更改);
- 一个类只能继承一个直接父类,但可以实现多个接口;
- 已存在的继承树,可以方便地抽取接口,但抽取抽象类不容易;
6.3 使用原则
- 接口做系统与外界交互地窗口
- 接口提供服务
- 接口本身一旦制定,不允许随意修改
- 抽象类可完成部分功能实现,还有部分功能可作为系统地扩展点
7、补充
-
当一个抽象类里没有抽象方法,是为了不让该类造对象,因为无意义
-
不想重写抽象类的方法怎么办??把抽象方法变成默认的(default)
它可以有方法体;实现类的对象可以调用接口里的默认修饰的方法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY