接口是一种抽象类型,它定义了一组方法的签名但没有实现。在Java中,接口可以包含常量、方法声明、默认方法、静态方法和嵌套类型。接口通过 interface
关键字声明。
// 定义接口
interface Shape {
double calculateArea();
double calculatePerimeter();
}
public class Main {
public static void main(String[] args) {
// 创建一个圆形对象
Circle circle = new Circle(5.0);
// 计算并打印圆形的面积和周长
System.out.println("Circle Area: " + circle.calculateArea());
System.out.println("Circle Perimeter: " + circle.calculatePerimeter());
}
}
// 实现圆形类
class Circle implements Shape {
private double radius;
// 构造方法
public Circle(double radius) {
this.radius = radius;
}
// 计算圆形的面积
@Override
public double calculateArea() {
return Math.PI * radius * radius;
}
// 计算圆形的周长
@Override
public double calculatePerimeter() {
return 2 * Math.PI * radius;
}
}
抽象类是一种不能被实例化的类,它可以包含抽象方法和非抽象方法。抽象方法是一种没有具体实现的方法,它只有方法声明,没有方法体。抽象类通过 abstract
关键字声明。
// 定义抽象类
abstract class Animal {
abstract void makeSound();
void eat() {
System.out.println("Animal is eating...");
}
}
// 定义 Dog 类继承 Animal 抽象类
class Dog extends Animal {
// 实现抽象方法
void makeSound() {
System.out.println("Dog barks...");
}
}
// 主类
public class Main {
// 主方法
public static void main(String[] args) {
// 创建 Dog 对象
Dog dog = new Dog();
dog.makeSound(); // 调用 Dog 类中的 makeSound 方法
dog.eat(); // 调用 Animal 类中的 eat 方法
}
}
public
,抽象类中的抽象方法可以有不同的访问修饰符。
在设计程序时,要根据需求和设计理念选择使用接口还是抽象类。接口用于定义类之间的协议,实现了接口的类必须实现接口中的所有方法。抽象类则用于建模类之间的通用关系,它提供了一组默认的实现,但允许子类覆盖它们。
// 定义接口
interface MyInterface {
// 接口中的方法只有声明,没有实现
void method1();
}
// 定义抽象类
abstract class MyAbstractClass {
// 抽象方法可以有实现
abstract void method2();
// 抽象类中的非抽象方法可以有实现
void method3() {
System.out.println("This is a method in abstract class.");
}
}
// 定义实现多个接口的类
class MyClass implements MyInterface {
// 实现接口中的方法
public void method1() {
System.out.println("Method 1 implemented from interface.");
}
}
// 主类
public class Main {
public static void main(String[] args) {
// 创建实现多个接口的类的对象
MyClass myClass = new MyClass();
// 调用接口中的方法
myClass.method1();
// 实例化抽象类
MyAbstractClass myAbstractClass = new MyAbstractClass() {
@Override
void method2() {
System.out.println("Method 2 implemented from abstract class.");
}
};
// 调用抽象类中的方法
myAbstractClass.method2();
myAbstractClass.method3();
}
}
这个运行结果说明了程序中的几个重要点:
MyClass
类成功实现了接口 MyInterface
中的抽象方法 method1()
。通过实现接口,MyClass
类表明它遵循了接口所定义的行为。MyAbstractClass
中的抽象方法 method2()
。匿名内部类是在实例化抽象类时直接定义的,它重写了抽象方法 method2()
,提供了具体的实现。MyAbstractClass
中的非抽象方法 method3()
被调用了。这个方法在抽象类中有具体的实现,因此可以被直接调用。抽象类在Java中只能单继承,不能多继承。这是因为Java的类继承机制决定的。每个类只能有一个直接父类,这样有利于构建简洁而有效的类层次结构。
// 定义抽象类 Animal
abstract class Animal {
abstract void makeSound();
}
// 定义抽象类 Color
abstract class Color {
abstract void showColor();
}
// 定义实现了多个抽象类的子类
class Dog extends Animal {
void makeSound() {
System.out.println("Dog barks...");
}
}
class Red extends Color {
void showColor() {
System.out.println("The color is red.");
}
}
// 主类
public class Main {
public static void main(String[] args) {
// 创建 Dog 对象
Dog dog = new Dog();
dog.makeSound(); // 调用 Dog 类中的 makeSound 方法
// 创建 Red 对象
Red red = new Red();
red.showColor(); // 调用 Red 类中的 showColor 方法
}
}
这个运行结果表明了程序成功创建了两个对象并调用了它们的方法:
Dog
对象,并调用了它的 makeSound()
方法。输出表明狗发出了叫声,这是 Dog
类中的实现。Red
对象,并调用了它的 showColor()
方法。输出表明显示的颜色是红色,这是 Red
类中的实现。抽象类常用于模板方法模式中。在模板方法模式中,抽象类定义了算法的骨架,子类可以按需求实现具体的步骤。
// 定义抽象类 Game
abstract class Game {
abstract void initialize();
abstract void startPlay();
abstract void endPlay();
// 模板方法
public final void play() {
initialize();
startPlay();
endPlay();
}
}
// 具体的游戏类
class Cricket extends Game {
@Override
void initialize() {
System.out.println("Cricket Game Initialized! Start playing.");
}
@Override
void startPlay() {
System.out.println("Cricket Game Started. Enjoy the game!");
}
@Override
void endPlay() {
System.out.println("Cricket Game Finished!");
}
}
class Football extends Game {
@Override
void initialize() {
System.out.println("Football Game Initialized! Start playing.");
}
@Override
void startPlay() {
System.out.println("Football Game Started. Enjoy the game!");
}
@Override
void endPlay() {
System.out.println("Football Game Finished!");
}
}
// 主类
public class Main {
public static void main(String[] args) {
Game cricket = new Cricket();
cricket.play();
System.out.println();
Game football = new Football();
football.play();
}
}
这个运行结果表示了两个具体游戏类的实例在执行模板方法模式下的游戏流程:
Cricket
游戏被初始化,输出 “Cricket Game Initialized! Start playing.”。Football
游戏被初始化,输出 “Football Game Initialized! Start playing.”。这个运行结果说明了模板方法模式的核心思想:抽象类定义了算法的骨架,其中包括了具体步骤的调用顺序,而具体的步骤实现由子类来完成。在这里,Game
类定义了一个通用的游戏流程模板,而 Cricket
和 Football
类则提供了特定游戏的具体实现。
抽象类经常被用于设计框架。框架提供了一组基础功能,但允许用户根据自己的需求扩展或定制功能。
// 定义抽象类 Framework
abstract class Framework {
// 框架提供的基础功能
void basicFunctionality() {
System.out.println("Framework: Providing basic functionality...");
}
// 抽象方法,允许用户根据需要扩展功能
abstract void extendedFunctionality();
}
// 用户自定义的类,继承框架类,扩展功能
class MyFramework extends Framework {
// 实现扩展功能
@Override
void extendedFunctionality() {
System.out.println("MyFramework: Adding extended functionality...");
}
}
// 主类
public class Main {
public static void main(String[] args) {
// 创建用户自定义的框架对象
MyFramework myFramework = new MyFramework();
// 使用框架提供的基础功能
myFramework.basicFunctionality();
// 使用用户扩展的功能
myFramework.extendedFunctionality();
}
}
这个运行结果反映了设计框架的典型模式。
basicFunctionality()
方法的执行结果。extendedFunctionality()
方法的执行结果。整个运行结果展示了抽象类在设计框架中的用法。基础功能由框架提供,而用户可以根据需要扩展功能,使框架更加灵活和适用于特定的场景。
抽象类可以在多个相关的类之间实现代码复用。它可以包含一组通用的方法和字段,减少了重复代码的编写。
// 定义抽象类 AbstractShape
abstract class AbstractShape {
// 通用方法:计算面积
abstract double calculateArea();
// 通用方法:计算周长
abstract double calculatePerimeter();
// 通用字段:形状名称
String shapeName;
// 构造方法
public AbstractShape(String shapeName) {
this.shapeName = shapeName;
}
// 通用方法:展示形状信息
void displayInfo() {
System.out.println("Shape: " + shapeName);
System.out.println("Area: " + calculateArea());
System.out.println("Perimeter: " + calculatePerimeter());
}
}
// 具体形状类:圆形
class Circle extends AbstractShape {
double radius;
// 构造方法
public Circle(double radius) {
super("Circle");
this.radius = radius;
}
// 实现抽象方法:计算面积
@Override
double calculateArea() {
return Math.PI * radius * radius;
}
// 实现抽象方法:计算周长
@Override
double calculatePerimeter() {
return 2 * Math.PI * radius;
}
}
// 具体形状类:矩形
class Rectangle extends AbstractShape {
double width;
double height;
// 构造方法
public Rectangle(double width, double height) {
super("Rectangle");
this.width = width;
this.height = height;
}
// 实现抽象方法:计算面积
@Override
double calculateArea() {
return width * height;
}
// 实现抽象方法:计算周长
@Override
double calculatePerimeter() {
return 2 * (width + height);
}
}
// 主类
public class Main {
public static void main(String[] args) {
// 创建圆形对象并展示信息
Circle circle = new Circle(5);
circle.displayInfo();
System.out.println();
// 创建矩形对象并展示信息
Rectangle rectangle = new Rectangle(4, 6);
rectangle.displayInfo();
}
}
这段代码展示了使用抽象类和具体类来表示不同形状(圆形和矩形)的面积和周长。
这个代码展示了如何利用抽象类 AbstractShape
和具体类 Circle
和 Rectangle
来表示不同形状的特性(面积和周长),并通过调用相应的方法展示了这些形状的具体信息。这种设计模式使得代码更加模块化和可扩展,同时提高了代码的可读性和维护性。