抽象类和接口
抽象类
在java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,则该类应该被定义为抽象类,抽象类和抽象方法用abstract关键字来修饰
抽象类特点
-
抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类
-
抽象类不能实例化
-
抽象类由具体的子类进行实例化
-
子类必须对父类中的所有抽象方法进行重写
-
在抽象类中可以定义非抽象方法
-
子类如果不重写抽象中的抽象方法,则该子类为抽象类
-
抽象类中可以有构造方法,用于子类访问父类时的数据初始化
接口
主要体现抽象的行为
不能有成员变量,可以有常量,没有构造方法
也不能实例化‘
多态进行,通过实现类对象实例化
抽象类和接口的区别
-
成员区别
-
抽象类 可以有成员变量,也可以有常量,有构造方法,抽象方法,非抽象方法
-
接口中只有常量,抽象方法(但在jdk8以后,接口中是可以有默认方法和静态方法的)
-
-
关系区别
-
类与类 继承是单继承
-
类与接口 实现,单实现和多实现
-
接口与接口 继承,单继承和多继承
-
-
设计区别
-
抽象类 对类抽象,包括属性行为(对事物的抽象)
-
接口 对行为抽象,主要是行为(对行为的抽象)
-
什么时候使用抽象类?什么时候使用接口?
当我们主要关注于行为、功能的时候,我们可以去使用接口
当我们关注的是事物的本身,可以使用抽象类
比如现在有种门,一个是A门类,一个是B门类
这两种门都可以实现开门和关门,但是A门有报警的功能,而B门没有
这个时候我们就可以定义一个门的抽象类,将开门和关门定义为抽象方法,让A门和B门分别继承和重写
但是报警这个功能是A门所特有的,如果我们写进门的这个抽象类中,那么B门继承了它,肯定也要重写报警的这个抽象方法,但是B门并没有这个报警的功能,这里代码就有点冗余了,因为报警这个功能对于B门来说是多余的
所以此时为了解决这个问题,我们可以写一个报警的接口,专注于报警的这个功能,然后让A门去实现这个接口,后面如果我们要新增门,有报警的功能就实现这个接口,没有就不实现.这样就减少了类中无用的代码.
代码实现
抽象类:门
public abstract class Door {
public abstract void open();
public abstract void close();
}
接口:报警
public interface BJ {
void Bj();
}
A门类
public class A extends Door implements BJ{
@Override
public void open() {
System.out.println("A门开");
}
@Override
public void close() {
System.out.println("A门关");
}
@Override
public void Bj() {
System.out.println("A门报警");
}
}
B门类
public class B extends Door{
@Override
public void open() {
System.out.println("B门开");
}
@Override
public void close() {
System.out.println("B门关");
}
}