前言
抽象类、抽象方法以及接口,这三个知识点是每个程序员必备的基础,无论是在实际编程的时候,还是在面试的时候,都会出现这类问题,面试官很可能就会问你,interface和abstract的区别,希望看完这篇博客文章各位都能从容地回答…
1、抽象类和抽象方法都必须用
abstract
修饰符来修饰,抽象方法不能有方法体
2、抽象类有构造器,但不能直接被实例化,要创建对象涉及向上转型,主要是用于被其子类调用
3、抽象类中可以没有抽象方法,但是有抽象方法的类必定是抽象类
4、抽象类中可以包含静态方法
5、抽象类不能用final
修饰
6、抽象类不能用private
修饰
7、抽象类也是类,一样是用来继承的,接口与类才是实现关系
8、外部抽象类不能用Static
修饰,但内部的抽象类可以使用static
声明
9、 抽象类可以继承抽象类,抽象派生类可以覆盖基类的抽象方法,也可以不覆盖。如果不覆盖,则其具体非抽象派生类必须覆盖它们
10、 抽象类可以实现接口,可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法
以上小结中的专业名词涉及到多方面知识,比如向上转型涉及多态知识。派生类、基类超类涉及继承基础知识,不理解的小白童鞋可以阅读如下文章【高手可直接略过】
【java基础之多态】理解多态的向上向下转型从“妈妈我想吃烤山药”讲起
【java基础】java继承从“我爸是李刚”讲起
概述抽象类之前我觉得很有必要先来从普通类下手。普通类可以包含构造方法、普通方法、static方法、常量和变量等内容。而抽象类也是类,而且是一个特别的类,抽象类是指在普通类的结构里面选择性的增加抽象方法并以abstract关键字将该类修饰,是的,每个抽象类不管有没有抽象方法在其类结构中,abstract关键字非加不可。
抽象类能够包含成分的代码
package com.gx.abstractdemo;
/**
* Animal 动物抽象类 抽象类不能创建实例,只能当成父类来被继承。
* 1、抽象类必须使用abstract修饰符来修饰,
* 抽象方法也必须使用abstract修饰符来修饰,
* 抽象方法不能有方法体。
* 2、抽象类不能被实例化,
* 无法使用new关键字来调用抽象类的构造器创建抽象类的实例。
* 3、抽象类可以包含成员变量、
* 方法(普通方法和抽象方法都可以)、
* 构造器、初始化块、
* 内部类(接 口、枚举)5种成分。
* 4、抽象类的构造器不能用于创建实例,主要是用于被其子类调用。
* 5、抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类
* 6、abstract static不能同时修饰一个方法 (abstract方法没有方法体不能直接调用,static方法可以直接调用,冲突)
*/
public abstract class Animal {
// 成员变量
protected int weight = 0;
static {
System.out.println("static初始化块");
}
{
System.out.println("初始化块");
}
// 构造器
public Animal() {
System.out.println("Animal 的无参构造器");
}
public Animal(int weight) {
this.weight = weight;
System.out.println("Animal 的有参构造器");
}
// 定义一个普通方法 休息
public void sleep() {
System.out.println("休息");
}
//抽象方法没有方法体
public abstract void running();
public abstract String say(String str);
}
不能与抽象类(abstract)共存的关键字主要有三个,分别是final、private、static
final:抽象类不能用final
修饰。因为抽象类一定要被abstract修饰,而且抽象类一定要被继承否则该抽象类无意义。而被final修饰的类不能被继承,也就是说不能有子类,所以二者冲突不能同时使用!
private: 抽象类不能用private
修饰,只能用public或protected。首先要明确一点:被abstract修饰的类是为了让非抽象子类看到并强制重写。如果抽象类中有私有的抽象方法,那么该抽象方法不被子类所知,就无法被复写。 而抽象方法出现的就是需要被复写。
关于static我觉得还是很有必要说下
static:如果static可以修饰抽象方法,那么连对象都省了,直接类名调用就可以了。众所周知,抽象方法是没有方法体的,可见运行也就没意义了。但是有种情况还是值得谈一谈,可能面试的时候会特别加分!那就是虽然外部抽象类不能用Static
修饰,但内部的抽象类却可以使用static
声明,如下
//定义一个抽象类A
abstract class A{
//定义一个内部抽象类B
static abstract class B{ //static定义的内部类属于外部类
public abstract void saoMethod();
}
}
class C extends A.B{
public void saoMethod(){
System.out.println("======saoMethod方法执行了======");
}
}
public class StaticDemo {
public static void main(String[] args) {
A.B ab = new C();//向上转型
ab.saoMethod();
}
}
运行结果: ======saoMethod方法执行了======
有的童鞋就懵逼了, C extends A.B
是啥骚操作啊,还能这样玩?是的,当使用static
声明的内部抽象类相当于一个外部抽象类,继承的时候使用“外部类.内部类
”的形式表示类名称。这种骚操作属实是稳中带皮。
说白了抽象类的功能就是一个类定义模板的功能。
接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract
类型,接口中的成员变量类型默认为public static final
。
下面比较一下两者的语法区别:
1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以有普通成员变量,接口中没有普通成员变量
3.抽象类中可以包含非抽象的普通方法,接口中的可以有非抽象方法,比如deaflut
方法
4.抽象类中的抽象方法的访问类型可以是public
,protected
和(默认类型,虽然 eclipse
下不报错,但应该也不行),但接口中的抽象方法只能是public
类型的,并且默认即为public abstract
类型。
5.抽象类中可以包含静态方法,接口中不能包含静态方法
6.抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final
类型,并且默认即为public static final
类型。
7.一个类可以实现多个接口,但只能继承一个抽象类。
有抽象方法不一定是抽象类,也可能是接口。抽象类不一定有抽象方法,可以有非抽象的普通方法。