Java Basics--Abstract Classes and Interfaces

Table of contents

abstract class

The definition format of an abstract method:

Notice

interface

declaration of the interface 

use of interface

interface inheritance

marker interface

When to use abstract classes and interfaces

Use an abstract class:

Use the interface:


abstract class

When defining a class, it is often necessary to define some member methods to describe the behavior characteristics of the class, but sometimes the implementation of these methods cannot be determined. For example, when defining the Animal class earlier, the shout() method is used to describe the animal's cry, but for different animals, the cry is also different, so the animal's cry cannot be accurately described in the shout() method.

For the situation described above, Java provides abstract methods to meet this demand. An abstract method is a member method decorated with the abstract keyword, and the abstract method does not need to implement the method body when it is defined.

The definition format of an abstract method:

修饰符 abstract void 方法名(参数列表);

An abstract method can be included in an abstract class or interface, which is used to define a behavior specification, and the specific implementation is completed by a subclass. An abstract method has no method body, only a method declaration, terminated with a semicolon (;).

Notice

There are a few things to keep in mind when using abstract methods:

  1. Abstract methods can only exist in abstract classes or interfaces and cannot be defined in ordinary classes.
  2. Abstract classes cannot be instantiated (a mistake that beginners can easily make). If they are instantiated, an error will be reported and the compilation will fail. Only non-abstract subclasses of abstract classes can create objects.
  3. Abstract classes do not necessarily contain abstract methods, but classes with abstract methods must be abstract classes.
  4. The abstract method in the abstract class is just a declaration, does not contain the method body, that is, does not give the specific implementation of the method, that is, the specific function of the method.
  5. The abstract method decorated with the abstract keyword cannot be decorated with private, static, final and native, because the abstract method must be implemented by the subclass, and if they are used for declaration, the subclass cannot implement the method.
  6. When overriding an abstract method in a subclass, you need to use the @Override annotation to identify the overriding of the method.
  7. If the subclass does not fully implement all the abstract methods, then the subclass still needs to be declared as an abstract class.

Here is a simple example showing the use of abstract methods: 

// 定义一个抽象类 Shape
abstract class Shape {
    // 定义一个抽象方法 calculateArea
    public abstract double calculateArea();
}

// Circle 类继承自 Shape 抽象类
class Circle extends Shape {
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    // 实现抽象方法 calculateArea,计算圆的面积
    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }
}

// Rectangle 类继承自 Shape 抽象类
class Rectangle extends Shape {
    private double width;
    private double height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    // 实现抽象方法 calculateArea,计算矩形的面积
    @Override
    public double calculateArea() {
        return width * height;
    }
}

public class myclass {
    public static void main(String[] args) {
        // 创建一个 Circle 对象,并计算其面积
        Circle circle = new Circle(5.0);
        double circleArea = circle.calculateArea();
        System.out.println("圆的面积:" + circleArea);

        // 创建一个 Rectangle 对象,并计算其面积
        Rectangle rectangle = new Rectangle(4.0, 6.0);
        double rectangleArea = rectangle.calculateArea();
        System.out.println("矩形的面积:" + rectangleArea);
    }
}

In this example, an abstract class Shape is defined, which contains an abstract method calculateArea. Abstract classes cannot be instantiated, so concrete subclasses need to be created to implement abstract methods. The Circle class and the Rectangle class inherit from the abstract class Shape respectively, and rewrite the calculateArea method to calculate the area of ​​the circle and rectangle.

In the main function, we create a Circle object and a Rectangle object, and call their calculateArea method to calculate the area and output the result.

operation result:

圆的面积:78.53981633974483
矩形的面积:24.0

interface

If all methods of an abstract class are abstract, the class can define an interface. Interface is one of the most important concepts in Java. An interface is a special class consisting of global constants and public abstract methods, and cannot contain ordinary methods.

  • Before JDK8, the interface was composed of global constants and abstract methods, and the abstract methods in the interface were not allowed to have method bodies.
  • JDK 8 redefines the interface. In addition to the abstract method, the interface can also have default methods and static methods (also called class methods). The default method is modified by default, and the static method is modified by static . Both methods allow There is a method body. For more information, please refer to  Java 8 default methods .
  • After JDK 9, it is allowed to define the method as private , so that some reused code will not expose the method. For more information, please refer to  Java 9 Private Interface Methods .

declaration of the interface 

Interfaces are declared using the interface keyword, and the syntax is as follows:

import java.lang.*;
//引入包
 
public interface 接口名 
{
   //任何类型 final, static 字段
   //抽象方法
}

Interfaces have the following properties:

  • Interfaces are implicitly abstract: when declaring an interface, it is considered abstract by default and does not need to be decorated with the keyword abstract.
  • The methods in the interface are implicitly abstract: the methods defined in the interface are also considered abstract by default, and do not need to be decorated with the abstract keyword. The method in the interface has only the method signature, no method body, and the specific implementation is provided by the class that implements the interface.
  • The methods in the interface are public: the methods defined in the interface default to public (public) access rights, and can be publicly accessed and called by the class that implements the interface.

example

interface Animal {
   public void eat();
   public void travel();
}

use of interface

Like an abstract class, the use of an interface must be through a subclass, and the subclass implements the interface through the implements keyword, and the subclass must implement all the abstract methods in the interface. It should be noted that a class can implement multiple interfaces at the same time, and multiple interfaces need to be separated by English commas (,).

Define the implementation class of the interface, the syntax format is as follows:

修饰符 class 类名 implements 接口1,接口2,...{
    ...
}

example

// 定义一个接口 Animal
interface Animal {
    // 定义抽象方法
    void eat();
    void sleep();
}

// 实现 Animal 接口的 Cat 类
class Cat implements Animal {
    // 实现接口中的抽象方法
    @Override
    public void eat() {
        System.out.println("猫在吃东西");
    }

    @Override
    public void sleep() {
        System.out.println("猫在睡觉");
    }
}

// 实现 Animal 接口的 Dog 类
class Dog implements Animal {
    // 实现接口中的抽象方法
    @Override
    public void eat() {
        System.out.println("狗在吃东西");
    }

    @Override
    public void sleep() {
        System.out.println("狗在睡觉");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal cat = new Cat();
        cat.eat();
        cat.sleep();

        Animal dog = new Dog();
        dog.eat();
        dog.sleep();
    }
}

The result of compiling and running the above example is as follows: 

猫在吃东西
猫在睡觉
狗在吃东西
狗在睡觉

When overriding methods declared in an interface, the following rules need to be observed:

  • When a class implements an interface method, it cannot throw a wider exception type (mandatory exception) than the interface method. It can only declare that the exception is thrown in the interface or in an abstract class that inherits the interface.
  • A class must maintain the same method signature when overriding an interface method, including method name, parameter list, and return type.
  • If a class is abstract and has already implemented some methods of an interface, then it does not need to implement the methods of the interface again.

When implementing an interface, there are also some rules to be aware of:

  • A class can implement multiple interfaces at the same time, separated by commas.
  • A class can only inherit from one class (single inheritance), but can implement multiple interfaces.
  • There can also be an inheritance relationship between interfaces. An interface can inherit from another interface, using the keyword extends. In this way, the subinterface will inherit the method declaration of the parent interface.

interface inheritance

An interface can inherit another interface, which is similar to the inheritance method between classes. The inheritance of the interface uses the extends keyword , and the sub-interface inherits the methods of the parent interface.

public interface 子接口名 extends 父接口名 {
    // 子接口的其他方法和常量声明
}

Through interface inheritance, a sub-interface can have all the method declarations of the parent interface, and can define its own methods and constants in the sub-interface. It should be noted that an interface can inherit multiple interfaces, separated by commas. For example:

public interface 子接口名 extends 父接口1, 父接口2, ... {
    // 子接口的其他方法和常量声明
}

In this way, the sub-interface can inherit the method declarations of multiple parent interfaces at the same time. Interface inheritance can help organize and expand code structure, improve code reusability and maintainability.

Here is an example demonstrating inheritance of interfaces:

//定义父接口A
interface InterfaceA {
 void methodA(); // 父接口A的方法声明
}

//定义子接口B,继承自父接口A
interface InterfaceB extends InterfaceA {
 void methodB(); // 子接口B的方法声明
}

//实现子接口B的类
class MyClass implements InterfaceB {
 @Override
 public void methodA() {
     System.out.println("实现了父接口A的方法");
 }

 @Override
 public void methodB() {
     System.out.println("实现了子接口B的方法");
 }
}

//测试代码
public class My {
 public static void main(String[] args) {
     MyClass obj = new MyClass();
     obj.methodA(); // 调用父接口A的方法 ,输出结果:实现了父接口A的方法
     obj.methodB(); // 调用子接口B的方法 ,输出结果:实现了子接口B的方法
 }
}

If a subclass needs to implement the interface and inherit the abstract class during development, the subclass can be defined in the following format.

修饰符 class 子类名 extends 父类名 implements 接口1, 接口2, ... {
    // 类的成员和方法定义
}

In the above format, the subclass inherits the specified parent class using the extends keyword, and implements the specified interface using the implements keyword. It is possible to inherit an abstract class (parent class) and implement multiple interfaces at the same time.

Note: Only single inheritance is supported in Java, that is, a class can only directly inherit from one parent class. However, the effect of multiple inheritance can be achieved by implementing multiple interfaces, so that a class can have the functions of multiple interfaces.

The following is a sample code showing a case where a subclass inherits an abstract class and implements two interfaces:

abstract class AbstractClass {
    abstract void methodA();
}

interface InterfaceA {
    void methodB();
}

interface InterfaceB {
    void methodC();
}

class Subclass extends AbstractClass implements InterfaceA, InterfaceB {
    @Override
    void methodA() {
       System.out.println("实现了抽象类中的方法");
    }

    @Override
    public void methodB() {
        System.out.println("实现了接口A中的方法");
    }

    @Override
    public void methodC() {
        System.out.println("实现了接口B中的方法");
    }
}

public class Main {
    public static void main(String[] args) {
        Subclass obj = new Subclass();
        obj.methodA(); // 调用抽象类中的方法 ,输出结果:实现了抽象类中的方法
        obj.methodB(); // 调用接口A中的方法 ,输出结果:实现了接口A中的方法
        obj.methodC(); // 调用接口B中的方法 ,输出结果:实现了接口B中的方法
    }
}

marker interface

The most common inherited interface is one that contains no methods.

A marker interface is an interface without any methods and properties, it is only used to mark a class as belonging to a specific type or having certain privileges. A marker interface adds data typing to a class by turning the class into an interface type.

The role of the marker interface can be summarized into the following two aspects:

  1. Establish a public parent interface: Marker interfaces can be used as a public parent interface to be inherited by other interfaces. For example, an interface in the Java API java.util.EventListeneris a marker interface from which many other interfaces indirectly inherit. By inheriting the marker interface, the unified constraint and specification of a set of interfaces can be realized.
  2. Add a data type to a class: By implementing a marker interface, a class can obtain a specific type of identity, which can be judged and processed in the program. Through polymorphism, the class that implements the marker interface is converted into the interface type, and specific types of operations can be performed or specific permissions can be assigned. This allows for easy classification, organization, and processing of classes.

Common examples:

  • java.io.Serializable: Classes that do not implement this interface cannot serialize and deserialize objects. To ensure consistency across different Java compiler implementations, serializer classes must declare an explicit serialVersionUID value.
    import java.io.Serializable;
    
    public class MyClass implements Serializable {
        // 类的实现...
    }
    
  • java.lang.Cloneable: Indicates that the Object.clone() method can legally copy instances of this class by field. Classes implementing this interface should override Object.clone() with a public method (it is protected). If the clone() method of Object is called on an instance that does not implement the Cloneable interface, a CloneNotSupportedException will be thrown.
    public class MyClass implements Cloneable {
        @Override
        public Object clone() throws CloneNotSupportedException {
            // 对象的复制逻辑...
        }
    }
    
  • java.util.RandomAccess: Used to identify that it supports fast (usually constant-time) random access. By implementing this interface, the general algorithm can change its behavior to provide better performance when applied to random or sequential access lists.
    import java.util.ArrayList;
    import java.util.List;
    import java.util.RandomAccess;
    
    public class MyClass {
        public static void main(String[] args) {
            List<Integer> list = new ArrayList<>();
            
            if (list instanceof RandomAccess) {
                // 列表支持快速随机访问的处理逻辑...
            }
        }
    }
    
  • java.rmi.Remote: The Remote interface is used to identify the interface whose methods can be called from non-local virtual machines. Any remote object must directly or indirectly implement this interface, and only methods specified in interfaces extending java.rmi.Remote will be available remotely.
    import java.rmi.Remote;
    import java.rmi.RemoteException;
    
    public interface MyRemoteInterface extends Remote {
        void performRemoteAction() throws RemoteException;
    }
    

These identification interfaces are mainly for type query and processing in the code, as well as identification and processing in a specific runtime environment or container.

It should be noted that although the marker interface does not define any methods, by implementing the interface, the class indicates that it has specific characteristics or properties. Common application scenarios of marker interfaces include event monitoring, serialization identification, permission identification, etc.

In short, the marker interface is a lightweight behavior marking mechanism, which can be classified and processed in the program by simply implementing the interface to mark the class with a specific mark.

When to use abstract classes and interfaces

  • Use an abstract class:

  1. Abstract classes are used when you have a group of related classes with common properties and methods, and you want some of these methods to have default implementations. An abstract class can define concretely implemented methods and abstract methods, and subclasses can directly use the concretely implemented methods after inheriting the abstract class, and rewrite the abstract methods as needed.
  2. Abstract classes are suitable for situations where the basic functions are relatively stable. If the basic functions change frequently, all subclasses that implement the abstract class need to be modified.
  • Use the interface:

  1. Interfaces can be used when you want to implement multiple inheritance or when you need to comply with a unified specification between multiple classes. An interface defines a set of methods that need to be implemented, and a class can achieve the purpose of complying with the specification by implementing the interface.
  2. Interfaces are suitable for situations where different classes need to share behaviors but have no inheritance relationship. A class can implement multiple interfaces to achieve the effect of multiple inheritance.
  3. If the basic functions need to change frequently, using the interface will be more flexible, because only the class that implements the interface needs to be modified, and no other classes need to be modified.

To sum up, the choice of abstract class or interface should be judged according to the specific situation. If there is a default implementation, the basic functions are relatively stable, and multiple inheritance is not required, you can choose an abstract class. If multiple inheritance is required or a unified specification needs to be followed between multiple classes, or the basic functions need to be changed frequently, then it is more appropriate to choose an interface.

Guess you like

Origin blog.csdn.net/m0_74293254/article/details/132307260