抽象类和接口
抽象类
使用abstract关键字声明的类为抽象类
抽象类自己并不能实例化,它存在的意义就是为了让子类继承。对于一个父类,它的某个方法在父类中实现没有任何意义,必需在子类中根据具体情况实现,那么这个方法可以声明为abstract抽象方法,此时这个父类也成了abstract抽象类。
很多具有相同特征和行为的对象可以抽象为一个类,很多具有相同特征和行为的类可以为一个抽象类
抽象类规则:
抽象类可以没有抽象方法,有抽象方法的类必须是抽象类
非抽象类继承抽象类必须实现所有有抽象方法
抽象类可以有方法实现和属性
抽象类不能被实例化
抽象类不能声明为final
抽象类可以有普通方法
抽象类的语法格式
public abstract class Wonmen{
private String name;
public abstract void say();
}
声明抽象方法会造成以下两个结果:
如果一个类包含抽象方法,那么该类必须是抽象类
任何子类必须重写父类的抽象方法,或者声明自身为抽象类
在其他方面,抽象类和普通类并无区别。最后,再来个例子:
public abstract class Animal { //抽象类中可以有非抽象方法,也可以有成员变量
private int a = 10;
public abstract void bark(); //如果没有此抽象方法,但是class前有absract修饰,也是抽象类,也不能实例化
public void say() { //普通成员方法
System.out.println("我是抽象类中的非抽象方法,此抽象类中的私有成员变量a= " + a);
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
}
public class Dog extends Animal{
public void bark() { //子类实现Animal的抽象方法
System.out.println("汪汪~汪汪~");
System.out.println("我是子类,不能直接调用父类的私有变量a :(");
System.out.println("我是子类,只有通过super.getA()调用父类的私有变量a:" + super.getA());
}
}
public class Test {
public static void main(String[] args) {
Dog dog = new Dog();
dog.say(); //子类继承调用Animal的普通成员方法
dog.bark(); //子类调用已经实现过的方法
}
}
接口
接口本质与抽象类相似,都是提供可由子类实现的一般形式,实现接口的子类可以根据自身的特点来扩展。
既然接口与抽象类可以实现相同的目的,那么我们已经学习过了抽象类,为什么还要有接口?
因为在java中所有的继承关系都是单继承关系。也就是说一个类只能有一个父类,不能一个类同时继承多个类。为了克服这种单继承关系,所以才用接口。那么也就是说接口是可以被同一个类去实现多个。
假设轿车,出租车,客车,拖拉机,摩托车他们都是机动车的子类,如果机动车是一个抽象类,这个抽象类它具有“收费”,“调节温度”这样的功能。那么作为机动车这个抽象类的子类就要去继承机动车这个抽象类,继承以后就需要重写“收费”,“调节温度”这两个抽象方法。这样做就不符合我们的逻辑习惯,拖拉机就没有“收费”,“调节温度”这样的功能,但是拖拉机继承机动车这个抽象类,那么“收费”,“调节温度”功能就要在拖拉机这个子类中实现。
因为接口只管定义功能,不用管功能的具体实现。很多时候我们把功能定义在接口,就可让很多类根据自己的需要选择需要实现的接口,以达到提供某个功能的目的。
接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念,类描述对象的属性和方法,接口则包含类要实现的方法
接口无法被实例化,但是可以被实现
一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类
定义接口的基本格式如下:
[修饰符] interface 接口名 [extends 父接口名列表]{
[public] [static] [final] 常量;
[public] [abstract] 方法;
}
接口在定义后,就可以在类中实现该接口。在类中实现接口可以使用关键字implements
[修饰符] class [extends 父类名] [implements 接口列表]{}
在类中实现接口时,方法的名字、返回值类型、参数的个数及类型必须与接口中的完全一致,并且必须实现接口中的所有方法
JAVA接口的使用规则
在类的继承中,只能做单重继承,而实现接口时,一次则可以实现多个接口
抽象类实现接口可以不实现方法
接口中的所有方法的访问权限都是public
接口中定义的属性都是常量
定义一个接口
定义一个IUSB接口
interface IUSB{
void swapDate();
}
定义一个Mouse类实现IUSB接口
class Mouse implements IUSB{
//实现接口方法
public void swapDate() {
System.out.println("Mouse...oning");
}
}
定义一个Print类实现IUSB接口
class Print implements IUSB{
//实现接口方法
public void swapDate() {
System.out.println("Print...oning");
}
}
定义一个主板类,将实现IUSB接口的类插入主板
class MotherBind{
/**
* 定义一个IUSB类型的数组,数组容量为6
*/
private static IUSB[] uss = new IUSB[6];
private static int index = 0;
/**
* 在数组的容量类可以插入IUSB设备
* @param usb
*/
public static void gets(IUSB usb) {
if(index == uss.length) {
System.out.println("已满");
return;
}
uss[index] = usb;
index++;
}
/**
* 让实现IUSB接口的类工作
*/
public static void wolk() {
for(IUSB usb : uss) {
if(usb != null) {
usb.swapDate();
}
}
}
}
测试
public class IntDemo {
public static void main(String[] args) {
/**
* 插入实现IUSB接口的设备,如果插入的数量大于6,会显示"插满"
*/
MotherBind.gets(new Mouse());
MotherBind.gets(new Print());
MotherBind.wolk();
}
}
接口与抽象类
接口与抽象类相同点:
都位于继承的顶端,用于被其他实现或继承;
都不能实例化;
都包含抽象方法,其子类都必须覆写这些抽象方法;
接口与抽象类区别:
抽象类为部分方法提供实现,避免子类重复实现这些方法,提供代码重用性;接口只能包含抽象方法;
一个类只能继承一个直接父类(可能是抽象类),却可以实现多个接口;(接口弥补了Java的单继承)
二者的选用:
优先选用接口,尽量少用抽象类,需要定义子类的行为,又要为子类提供共性功能时才选用抽象类;
作业
设计一个治疗者接口:Healer,该接口声明有方法: heal() 设计一个Support类,代表辅助英雄,继承Hero类,同时实现了Healer这个接口
public interface Healer {
void heal();
}
public class Support extends Hero implements Healer {
public void heal() {
System.out.println("治疗");
}
}
(想要了解更多的职场,职业规划方面的经验,文章第一时间发布于云图智联官网)