前情提要:
此前我们学习过类的定义及其应用,这篇博客重点介绍抽象类的概念以及应用。在认识抽象类之后的重头戏就是接口。
认识抽象类
概念:
一个类中没有足够的信息来描述对象,那么这个类就是抽象类。
例如:
图形是一个类,图形有分多个类别,而在shape父类中并不能具体的描述出对象的特征
(好比:三角形是一个图形,长方形也是一个图形,但你在对图形描述的时候并不能明确的说出:图形就是三角形,图形就是长方形。)
语法 :
关键字:abstract
在Java中被abstract修饰的类叫抽象类,被abstract修饰的方法叫抽象方法。
抽象类不能创建具体的实例化对象,抽象方法没有具体的方法体。
抽象类也是类,可以添加普通的方法和属性。
public abstract class Shape {
// 抽象方法:被abstract修饰的方法,没有方法体
abstract public void draw();
abstract void calcArea();
// 抽象类也是类,也可以增加普通方法和属性
public double getArea(){
return area;
}
protected double area; // 面积
}
特性:
1、抽象类不能进行实例化
一但实例化就会报错
2、抽象方法不能被private修饰
同样会有报错,abstract和private是一对非法的修饰符组合
3、抽象方法不能被static和final修饰
同样也会报错
那么为什么会报错?
抽象类作为父类,抽象类中抽象方法没有具体的方法体,抽象方法要交由子类继承后进行重写对其细节将进行加工,被final修饰的方法体不能对其进行任何操作(包括重写、重载)
4、抽象类必须被继承,子类必须对抽象类中的抽象方法进行重写,否则子类也是抽象类
在学习过继承之后,我们知道了子类会继承父类中所有的成员方法和成员变量。而抽象类也是如此,如果我们在进行继承之后不在子类中对抽象方法进行重写,那子类就是和父类一样是个抽象类。
5、抽象类中不一定包含抽象方法,但是包含抽象方法的类一定是抽象类
6、抽象类可以有构造方法,但是子类必须对父类的构造方法和成员变量进行初始化
作用:
由于抽象类不能进行实例化,所以要引用抽象类只能创建其子类并且在子类中重写抽象类中的抽象方法。
普通的类也可以进行继承,为什么不用普通的类还要用抽象类呢?
话虽如此,但是使用抽象类其实可以相当于给代码多一层校验,因为有一些实际工作不是交由父类去完成,而是交给子类去具体实现,所以为了防止在引用的时候用到父类就可以将父类写成一个抽象类。
认识接口
概念:
接口就像是电脑上的USB口,只要符合USB协议的都可以接上使用,例如耳机、键盘、鼠标、U盘等等。
在java中可以认为是多个类的公共规范,是一种引用的数据类型。
语法:
public interface 接口名{ //接口中的方法都为抽象方法
public void methodA();
abstract void methodB();
void methodC(); //这种写法最为简洁
}
我们在给接口命名的时候最好就是以大写字母为首的Interface+形容词,这样后续在调用接口的时候方便找。
使用:
接口不能直接使用,而是通过实现类来实现对应的接口,通过实现类来具体实现接口中的方法。
不同于子类继承,在调用接口的时候是用关键字implements
public class 类名称 implements 接口名称{
// ...
}
如果调用接口的类是子类的话其语法是:
public class Childname extends Parentname implements interface{
//....
}
//调用接口的类不可以是抽象类
看代码实例:
模拟实现一个USB的功能接口
public interface USB {
void Opendevice();
void Closedevice();
}
创建类“鼠标”去调用接口USB
public class Mouse implements USB {
@Override
public void Opendevice() {
System.out.println("USB接口进行鼠标连接....");
}
@Override
public void Closedevice() {
System.out.println("USB接口断开鼠标连接....");
}
public void click()
{
System.out.println("鼠标点击....");
}
}
创建类“键盘”去调用接口USB
public class Keyboard implements USB{
@Override
public void Opendevice() {
System.out.println("USB接口进行键盘连接....");
}
@Override
public void Closedevice() {
System.out.println("USB接口断开键盘连接....");
}
public void press(){
System.out.println("敲键盘....");
}
}
创建类“电脑” 整合“鼠标”和“键盘”的引用
public class Computer {
public void PowerOn() {
System.out.println("打开电脑....");
}
public void PowerOff() {
System.out.println("关闭电脑....");
}
public void opendevice(USB usb)
{
if(usb instanceof Mouse)
{
Mouse mouse = (Mouse)usb;
mouse.click();
}
else if(usb instanceof Keyboard)
{
Keyboard keyboard = (Keyboard) usb;
keyboard.press();
}
}
}
创建测试类进行实例化
public class test {
public static void main(String[] args) {
Computer c1 = new Computer(); //实例化计算机
c1.PowerOn();
//打开电脑
c1.opendevice(new Mouse());
//使用鼠标
c1.opendevice(new Keyboard());
//使用键盘
c1.PowerOff();
//关闭电脑
}
}
实例化对象之后,对接口进行调用,执行结果如下
特性:
1、接口是一种引用类型,不能直接实例化
public class test {
public static void main(String[] args) {
USB usb = new USB();
}
}
//Errow,不存在这种实例化方式
2、接口中的方法都是被public修饰的抽象方法,所有的方法都被public abstract修饰,使用其他的修饰符会报错
3、重写接口中的方法时不能用默认的访问权限,不然会报错
抽象类中默认方法访问权限是public,而且在抽象中为了代码简洁性一般采取隐式写法,当你在子类中进行重写的时候就得自己为方法设置访问限定符,否则就会报错
4、接口中的方法不能有方法体
接口中的方法都是抽象方法,具体细节交由实现子类重写方法时进行实现(因为抽象,所以不能具体)
5、接口中可以有变量,变量会被隐式指定为public static变量
6、接口中不能有静态化代码和构造方法
7、如果类没有将接口中的所有的抽象方法进行实现,那么该类要设置为抽象类
8、接口虽然不是类,但是文件后缀也是.class
9、java中一个类不能继承多个父类,但是一个类可以实现多个接口(以特点7为前提条件)
10、类与类之间并不支持多继承,但是接口与接口之前支持多继承
interface IRunning {
void run();
}
interface ISwimming {
void swim();
}
// 两栖的动物, 既能跑, 也能游
interface IAmphibious extends IRunning, ISwimming {
}
class Frog implements IAmphibious {
...
}
抽象类和接口的区别
本期博客到此为止啦!请不要吝啬您的点赞!!