(1)知识点概述
抽象类:
接口:
(2)背景知识
java中的抽象类的概念其实是来源自早先便已经出现的c++,而c++中的类的因为存在着一个多继承的概念,导致当一个类存在多个继承类时会出现一些错误,因此在java中为了区分出来,单独拎出来一个接口的概念,而接口可以实现多继承,并且在一些内部成员,内部方法上与抽象类有着一定的区别。
(3)知识点详述
抽象类:
抽象类出现的原因其实很简单,假设存在着这么一个场景,我们有物体这个类,而我们有getVolume这个方法,而对于不同的形状的物体的求体积方式是不同的,因此无法计算。所以说getVolume这个方法是没有实际意义的,只是一个表面陈述求体积的方法。因此,对于每一个不同的形状都需要相对应的getvolume方法,而在java中就是要求需要重写getvolume方法,而这种没有实际意义的,需要在子类中强制去重写的称为抽象方法。自然有了抽象方法就需要在定义方法时区别开抽象方法与普通方法。抽象方法被用来确保派生类会实现这个方法。java中通过abstract关键字将getVolume方法修饰为抽象的。一个抽象方法只有方法头没有方法主体。格式为:访问修饰符 abstract 返回类型 方法名(参数列表);
抽象方法的出现就使得在类上出现了一定的区分,将包含抽象方法的类称为抽象类。因此在声明抽象类时也需要加上abstract关键字。格式为:public abstract class 类名;抽象类可以含零至多个普通方法,也可以含零至多个抽象方法。但是,抽象类不允许被实例化,即其只能作为父类。若父类是抽象类,且子类不想成为抽象类,则子类必须将父类中的所有抽象方法重写为带方法体的普通方法,否则子类仍必须是抽象类。
!注意:如果派生类不是抽象类并且没有重写抽象方法,编译器会报错。
!注意:重写只能对有相同签名的方法重写。否则就不是重写。
下方为一个抽象类的实例:
package abstruct;
public abstract class Shape {
public String color;
public abstract double getvolume();
}
package abstruct;
public class Ball extends Shape {
public double radius;
public double getvolume(){
return 4/3*Math.PI*radius*radius*radius;
}
}
package abstruct;
public class Cube extends Shape{
public double length;
public double getvolume(){
return length*length*length;
}
}
package abstruct;
public class ShapeDemo {
public static void main(String[] args) {
Ball ball=new Ball();
Cube cube=new Cube();
ball.radius=3;
cube.length=3;
System.out.println(ball.getvolume());
System.out.println(cube.getvolume());
}
}
而如果对于抽象类的子类不对抽象方法进行重写便会出现下面的这个错误:
接口:
接口的通用格式:public interface 接口名称 { (方法头...) }(!注意只需写出方法头即可不需要写abstract关键字)
在接口中的方法虽然没有说明是抽象方法,但默认其为public以及是抽象方法。
接口和所有方法都是抽象方法的抽象类非常类似。
(1).它不能被实例化。
(2).在接口中所列的所有方法必须在别处被重写。
区别在于:
在接口中的所有属性都为 public、final 和 static.即接口属性必须赋予初始值。(不懂final和static的意思的可以在csdn中搜索查看)
自然有了接口,便需要如何去实现:
如果一个类要实现接口,它需要在类头中使用implements 关键字。格式为:public class 子类名 extends 父类名 implements 接口名。(接口继承写在类的后面,当然也可以不继承父类,即可选择的)。
相较于类来说接口还有一个区别便是它可以实现一个类继承多个接口,而子类往往只能继承一个父类。但是,当一个类实现多个接口,它必须实现所有接口中的方法。格式为:public class MyClass implements Interface1,Interface2,Interface3。
同类一样,接口与接口之间也有着继承的关系,格式:public interface 接口名 extends 父接口1,父接口2,...{}.(!注意但是接口只能继承接口不能继承类)。
接口与多态性:前面说到接口是不可以被实例化的,但是在java中允许创建接口类型的引用变量。即:interface 物体名称=new 继承自interface的类();
区别:
从语法层面:
上述为在java中语法层面的不同,因而针对不同的场景,对于接口还是抽象类的选择其实要根据具体情况而定。
(4)小结:
抽象类的功能要远超过接口,但是,定义抽象类的代价高。因为高级语言来说(从实际设计上来说也是)每个类只能继承一个类。在这个类中,你必须继承或编写出其所有子类的所有共性。虽然接口在功能上会弱化许多,但是它只是针对一个动作的描述。而且你可以在一个类中同时实现多个接口。在设计阶段会降低难度的。