一、初识抽象类和抽象方法
在Java中,当一个类的方法被abstract关键字修饰时,该方法称为抽象方法。抽象方法所在的类必须定义为抽象类。
当一个方法被定义为抽象方法后,意味着该方法不会有具体的是下面,而是在抽象类的子类通过方法重写进行实现。定义抽象方法的语句格式如下:
[访问修饰符] abstract <返回类型> <方法名>([参数列表]);
abstract关键字表示该方法被定义为抽象方法。
普通方法和抽象方法相比,主要有下列两点区别:
抽象方法需要用修饰符abstract修饰,普通方法不需要。
普通方法有方法体,抽象方法没有方法体。
在Java中,当一个类被abstract关键字修饰时,该类称为抽象类。
定义抽象类的语法格式如下:
abstract class <类名>
{
方法体
}
abstract关键字表示该类被定义为抽象类。
普通类和抽象类相比,主要有下列两点区别:
抽象类需要用修饰符abstract修饰,普通类不需要。
普通类可以实例化,抽象类不能被实例化。
当一个类被定义为抽象类时,它可以包含各种类型的成员,包括属性、方法等,其中方法又可分为普通方法和抽象方法,如下面的抽象类结构实例:
public abstract class 类名称
{
修饰符 abstract 返回类型 方法名();
修饰符 返回类型 方法名()
{
方法体
}
}
有一个宠物类,宠物具体可以分为狗、企鹅等,实例化一个狗类、企鹅类是由意义的,而实例化一个宠物类则是不合理的。这里可以把宠物定义为抽象类,避免宠物类被实例化。
二、接口
Java中接口的作用和生活中的接口类似,它提供一种约定,使得实现接口的类(或结构)在形式上保持一致。
如果抽象类中所有的方法都是抽象方法,就可以使用Java提供的接口来表示。从这个角度来讲,接口可以看作是一种特殊的“抽象类”,但是采用与抽象类完全不同的语法来表示,两者的设计理念也不同。
接口是一个不能实例化的类型。接口类型的定义类似于类的定义,语法格式如下:
public interface 接口名
{
//接口成员
}
和抽象类不同,定义接口使用interface修饰符,访问修饰符只能是public,且可选。
接口成员可以是全局常量和公共的抽象方法。
与抽象类一样,使用接口也必须通过子类,子类通过implements关键字来实现接口。实现接口的语法格式如下:
public 类名 implements 接口名
{
实现方法
普通方法
}
实现就扣使用implements关键字。
实现接口的类必须实现接口中鼎会议的所有抽象方法。接口的实现类允许包含普通方法。
接口本身也可以继承接口。
接口继承的语法格式如下:
[修饰符] interface 接口名 extends 父接口1,父接口2,…
{
常量定义
方法定义
}
一个普通类只能继承一个父类,但能同时实现多个接口,也可以同时继承抽象类和实现接口。
实现多个接口的语法格式如下:
class 类名 extends 父类名 implements 接口1,接口2,…
{
类的成员
}
关于定义和实现接口,需要注意以下几个方面的内容:
接口和类、抽象类是一个层次的概念,命名规则相同。
修饰符如果是public,则该接口在整个项目中可见。如果省略修饰符,该接口只在当前包中可见。
接口中可以定义常量,不能定义变量。接口中的属性都默认用”public static final“修饰,即接口中的属性都是全局静态常量。接口中的常量必须在定义时指定初始值,举例如下:
public static final double PI=3.14;
double PI=3.14; //在接口中,这两个定义语句的效果完全相同
double PI; //错误,在接口中定义时必须指定初始值,如果在类中定义会有默认值
接口中的所有方法都是抽象方法,接口中的方法都默认为public。
和抽象类一样,接口同样不能实例化,接口中不能有构造方法。
接口之间可以通过extends实现继承关系,一个接口可以继承多个接口,但接口不能继承类。
类只能继承一个父类,但可以通过implements实现多个接口。一个类必须实现接口的全部方法,否则必须定义为抽象类。若一个类在继承父类的同时又实现了多个接口,extends必须位于implements之前。
子类继承父类,若父类的构造方法没有重载,那么子类的构造方法也不需要通过super调用父类的构造方法。一个类中如果构造方法重写了并且带了参数,那么这个类的原来系统默认的无参构造方法便消失。由此,若一个父类中只有一个带参数的构造方法,那么在写其子类的构造方法是必须先通过super调用父类的构造方法才能完成子类的构造方法而且super只能写在子类构造方法体内的第一行