抽象类和接口和枚举详解
一、抽象类:
概念
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类,简单来说就是**没有方法主体的方法
称为抽象方法
而Java语法规定,包含抽象方法的类就是抽象类
**。
特点
- 抽象类
不能被实例化
(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象
。 抽象类中不一定包含抽象方法
,但是有抽象方法的类必定是抽象类
,使用abstract class
定义抽象类。- 抽象类中的
抽象方法只是声明,不包含方法体
,就是不给出方法的具体实现也就是方法的具体功能。 - 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
- 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。
- 一个类只能继承一个抽象类(但一个类可以实现多个接口)。
举例
/**
* 抽象类,只要有抽象方法的类就是抽象类并且此类必须使用abstract修饰,不管有没有其他类型的方法
*/
public abstract class Test {
//定义一个抽象方法(没有方法体的方法,使用abstract关键字进行修饰)
public abstract void test1();
//定义一个普通方法(抽象类中可以定义普通方法)
public static void test2(){
System.out.println("test2");
}
//创建抽象方法的构造方法
public Test() {
System.out.println("抽象类中的构造方法被调用了");
}
}
/**
* 定义一个子类继承抽象类并对抽象类中的抽象方法的功能进行补全
*/
class Test3 extends Test {
@Override
public void test1() {
System.out.println("抽象类中的test1抽象方法执行了~~~");
}
public static void main(String[] args) {
//实例化Test3,Test3没有定义构造方法会默认使用父类的构造方法
Test3 test3 = new Test3();//注意:只有抽象类的非抽象子类可以创建对象
//使用抽象类中的方法
test3.test1();
}
}
程序运行结果:
抽象类中的构造方法被调用了
抽象类中的test1抽象方法执行了~~~
二、接口:
概念
接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合
,接口通常以interface
来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
特点
一个接口可以继承多个父类
,一个实现类继承一个父类的同时实现一个或者多个接口- 一个接口可以有多个方法。
接口不能用于实例化对象。
接口没有构造方法。
接口中所有的方法必须是抽象方法,(Java8之前)
Java 8 之后 接口中可以使用 default 关键字修饰的非抽象方法,Java 9之后接口可以定义私有方法。- 接口不能包含成员变量,除了 static 和 final 变量。
- 接口不是被类继承了,而是要被类实现。
接口支持多继承。
- 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
- 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误,接口中的变量只能在接口里面使用)。
- 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
- 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
- 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
- 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
- 一个类却可以实现多个接口(一个类只能继承一个抽象类)。
举例
/**
* 定义一个接口,在接口里面定义一个抽象方法和一个非抽象方法
*/
public interface Test2 {
//[public static final] 可省略,默认接口是使用这些关键字修饰
public final Integer sum = 0;
//[public abstract] 可省略,默认接口是使用这些关键字修饰
public abstract void getsum();//定义一个抽象方法
//定义一个非抽象方法
public default void eee() {
System.out.println("sum:" + sum);
System.out.println("接口中的非抽象方法被调用了");
}
}
class Test31 implements Test2 {
@Override
public void getsum() {
System.out.println("getsum");
}
public static void main(String[] args) {
Test31 test31 = new Test31();
test31.eee();
test31.getsum();
}
}
程序运行结果:本案例使用的是Java8版本
sum:0
接口中的非抽象方法被调用了
getsum
三、枚举
概念
Java 枚举是一个特殊的类,一般表示一组常量,比如一年的 4 个季节,一个年的 12 个月份,一个星期的 7 天,方向有东南西北等。
Java 枚举类使用 enum 关键字来定义
,各个常量使用逗号 , 来分割。
特点
- 所有的枚举值都是
public static final
的
举例
例如定义一个颜色的枚举类
/**
* 定义枚举类
*/
public enum Color {
RED, GREEN, BLUE;
}
/**
* 枚举类基本使用
*/
class Test4 {
public static void main(String[] args) {
Color c1 = Color.RED;
System.out.println(c1);
}
}
/**
* 在switch中使用枚举类
*/
class MyClass {
public static void main(String[] args) {
Color myVar = Color.BLUE;
switch (myVar) {
case RED:
System.out.println("红色");
break;
case GREEN:
System.out.println("绿色");
break;
case BLUE:
System.out.println("蓝色");
break;
}
}
}
程序运行结果:
Test4:
RED
MyClass:
蓝色