小咸儿在重新学习Java基础的时候,看到有关接口和抽象类的知识,特此总结下来。
概览
宝图
抽象类
是什么
什么是抽象类,就小咸儿的话来说,就是一般类,将特殊类中共同的部分抽象出来,并且方法不提供具体实现的类。
特点
- 使用abstract修饰符修饰,使用abstract修饰的方法,只有声明,没有具体实现。
public abstract class Shape
{
public abstract String getType();
}
有得有失
- 失:抽象类不能够被实例化,无法使用new关键字来调用构造器去创建抽象类的实例。主要用其被子类调用
- 得:抽象类可以包含成员变量、方法(普通方法和抽象方法都可以)、构造器、初始化块、内部类
抽象方法
抽象方法是只有方法签名,没有方法实现的方法。
关系
抽象方法和抽象类必须使用abstract修饰符来定义,有抽象方法的类只能被定义成抽象类,抽象类里可以没有抽象方法。
空方法
定义了方法体,只是方法体为空。
public void test() {}
abstract
在这里小咸儿对于abstract修饰符的使用多总结一点:
- final:final修饰的类不能被继承;final修饰的方法不能被重写。所以final与abstract永远不能同时使用
- private:abstract关键字修饰的方法必须被其子类重写才有意义,因此abstract方法不能定义为private访问权限。使用private修饰,表明其子类不能访问。由此可见,private与abstract不能同时使用
- static:static修饰方法时,表明这是一个类方法,即通过类就可调用。abstract修饰的方法不能满足这一要求,即在修饰方法时,static与abstract不能同时使用,但是在修饰类时可以同时使用。
接口
是什么
接口,通俗来讲,更像是一种规范。他不关心类的内部状态数据,也不关心类里面方法的实现细节。只要类中提供了规定的方法即可。
设计哲学
规范和实现分离
特点
- 使用interface关键字
public interface Output
{
// 接口里定义的成员变量只能是常量
int MAX_CACHE_LINE = 50;
// 接口里定义的普通方法只能是public的抽象方法
void out();
void getData(String msg);
// 在接口中定义默认方法,需要使用default修饰
default void print (String... msgs)
{
for (String msg : msgs)
{
System.out.println(msg);
}
}
// 在接口中定义默认方法,需要使用default修饰
default void test()
{
System.out.println("默认的test()方法");
}
// 在接口中定义类方法,需要使用static方法
static String staticTest()
{
return "接口里的类方法";
}
// 定义私有方法
private void foo()
{
System.out.println("foo私有方法");
}
}
- 接口里定义的方法只能是抽象方法、类方法、默认方法或私有方法。定义接口里面的普通方法总是使用public abstract,如果没用public abstract修饰符,系统将自动为普通方法添加。
- 接口里不能包含构造器和初始化块定义。
- 接口可以多继承,但是只能继承接口,不能继承类
用途
- 定义变量,也可用于进行强制类型转换
- 调用接口中定义的常量
- 被其他类发现
异同
相同特征
- 接口和抽象类都不能被实例化,位于继承树的顶端,换句话说,就是位于食物链的顶端。
- 接口和抽象类都可以包含抽象方法。他们的子类都必须实现这些抽象方法。
不同之处
他们的区别,主要体现在两个方面,其一是设计目的,其二是用法。
设计目的
接口体现的是一种规范,类似系统的“总纲”
抽象类体现的是一种模板设计,类似系统实现过程中的中间产品
用法
接口里只能包含抽象方法、静态方法、默认方法和私有方法,不能为普通方法提供方法实现;抽象类则完全可以包含普通方法。
接口里只能定义静态常量,不能定义普通成员变量;抽象类里两者均可。
接口里不包含构造器和初始化块。而抽象类二者均包含,需要注意的是:抽象类里的构造器是为了让子类调用这些构造器来完成属于抽象类的初始化操作。
抽象类只能有一个直接父类,但是可以直接实现多个接口。