文章目录
- 一、抽象类特性
- 代码示例
- 二、抽象类注意事项
- 三、抽象类和接口的比较
刚刚学了Python的多态和抽象类,就想着跟Java的比对一下。
一、抽象类特性
- 抽象类不能被实例化:抽象类只能用作其他类的基类,不能直接创建实例。
- 子类必须实现所有抽象方法:子类必须实现抽象类中定义的所有抽象方法,否则会在编译时报错。如果子类没有实现所有抽象方法,它也会被视为抽象类。
- 抽象方法没有实现:抽象方法没有具体的实现代码,只有方法签名。
- 抽象类可以包含非抽象方法:抽象类中除了抽象方法外,还可以包含普通的方法和属性。
- 抽象类可以有构造函数:抽象类可以定义构造函数,但不能被实例化。
代码示例
// 抽象类
abstract class Animal {String name;// 构造函数public Animal(String name) {this.name = name;}// 普通方法public void eat() {System.out.println(name + " is eating.");}// 抽象方法public abstract void move();
}
// 继承抽象类
class Dog extends Animal {// 构造函数public Dog(String name) {super(name);}// 实现抽象方法@Overridepublic void move() {System.out.println(name + " is running.");}
}public class Main {public static void main(String[] args) {Dog dog = new Dog("Buddy");dog.eat(); // 输出:"Buddy is eating."dog.move(); // 输出:"Buddy is running."// 抽象类不能实例化,会报错// Animal a = new Animal();}
}
在这个例子中,我们定义了一个抽象类Animal。
- 它有一个name属性
- 两个方法:eat和move。
- eat方法有一个默认的实现(打印出name + " is eating."),
- move方法没有具体的实现,因此它是一个抽象方法,必须由子类实现。
我们还定义了一个Dog类,它继承自Animal。
Dog类必须实现Animal类中定义的抽象方法move,并提供具体的实现代码(打印出name + " is running.")。
在Main类中,我们创建了一个Dog对象,并调用它的eat和move方法。eat方法使用了抽象类中的默认实现,而move方法使用了Dog类中的具体实现。
这个例子包含了抽象类的所有特性:抽象方法、默认实现、必须实现、继承等。
它展示了如何使用抽象类来定义一个通用的类,并由子类提供具体的实现。
二、抽象类注意事项
- 抽象类的命名应该以Abstract开头,标识出它是一个抽象类。
- 由于抽象类不能被实例化,因此它的主要作用是用来继承和实现。实际上,抽象类的存在是为了更好地实现程序的复用。
- 抽象类中可以有非抽象方法,这些方法可以提供一些默认的实现,子类可以选择性地重写这些方法。
- 抽象类中可以有抽象方法,它们没有具体的实现代码,只有方法签名。这意味着子类必须实现这些方法,并提供具体的实现代码。
- 抽象类和抽象方法的存在可以提高程序的可读性和可维护性,同时也能够规范子类的行为。
总之,Java中的抽象类是一种不能被实例化的类,它定义了其他类的通用接口和行为。使用抽象类可以提供代码的规范性和灵活性,强制子类实现抽象方法,从而提高代码的可靠性和可维护性。在使用抽象类时,需要注意抽象类不能被实例化、子类必须实现所有抽象方法等事项。
三、抽象类和接口的比较
- 定义方式:
- 抽象类是使用 abstract 关键字定义的类。它可以包含抽象方法和非抽象方法。
- 接口是使用 interface 关键字定义的。它只能包含抽象方法和常量。
- 继承与实现:
- 一个类只能继承一个抽象类,而一个类可以实现多个接口。
- 抽象类通过继承来扩展现有的类,并且可以提供默认的实现。子类可以使用 extends 关键字继承抽象类。
- 接口通过实现来定义新的行为,并且不提供任何默认的实现。类可以使用 implements 关键字实现接口。
- 构造函数:
- 抽象类可以有构造函数,并且可以被子类调用。
- 接口不能有构造函数,因为它们不能被实例化。
- 成员变量:
- 抽象类可以有实例变量、静态变量和常量。
- 接口只能有静态常量。
- 方法实现:
- 抽象类可以包含具体方法的实现,子类可以直接使用或重写这些方法。
- 接口只能包含抽象方法的声明,实现接口的类必须提供方法的具体实现。
- 多态性:
- 由于Java中只支持单继承,子类只能继承一个抽象类,但可以实现多个接口。这使得接口在实现多态性方面更加灵活。
选择抽象类还是接口,取决于具体的需求。如果需要定义一些通用的行为和属性,并且希望提供默认的实现,可以使用抽象类。如果需要定义一组完全抽象的行为,并且希望不同的类以不同的方式来实现这些行为,可以使用接口。通常情况下,接口更适合用于实现多态性和松耦合的设计。