Java の an article that takes you through the interface

one 🤖 previously on

With the arrival of the interface, the final outcome of JavaSE learning notes is coming. In recent blogs, encapsulation, inheritance, polymorphism, abstract classes, etc. are all introduced step by step. If it is difficult to understand the interface, it is recommended to improve the previous knowledge
👉Java encapsulation
👉Static member
👉Code block
👉Inner class
👉inherit
👉polymorphic
👉abstract class

The code word is not easy. There are many dry goods in this blog. It is recommended to collect and eat them
Then we will formally enter the introduction of the interface

two 🍚 Interface

A graph flow

two point one 🍟 Concept of interface and summary of some knowledge points

Interface (English: Interface) is an abstract type and a collection of abstract methods in JAVA programming language. Interfaces are usually declared as interfaces. A class inherits the abstract methods of the interface by inheriting the interface.
Interfaces are not classes. The way to write interfaces is very similar to that of classes, but they belong to different concepts. Class describes the properties and methods of an object. Interface contains the methods to be implemented by the class.
Unless the class that implements the interface is an abstract class, the class should define all methods in the interface.
An interface cannot be instantiated, but it can be implemented. A class that implements an interface must implement all the methods described in the interface, or it must be declared as an abstract class. In addition, in Java, interface types can be used to declare a variable. They can become a null pointer or be bound to an object implemented by this interface.

2.1.1 🍣 The same place between interface and class

  • One interface can have multiple
  • Interface files are saved in In the file ending in Java, the file name uses the interface name
  • The bytecode file of the interface is saved in class
  • The bytecode file corresponding to the interface must be in the directory structure matching the package name

2.1.2 🍜 Differences between interfaces and classes

  • Interface cannot be used to instantiate an object
  • Interface has no constructor
  • All methods in the interface must be abstract methods. After Java8, non abstract methods can be modified with the default keyword in the interface
  • An interface cannot contain member variables except static and final variables
  • The concept that interfaces are inherited by classes is not accurate. To be exact, they should be implemented by classes
  • Interfaces can implement what we call multiple inheritance

2.1.3 🍔 Some features of the interface

  • Each method in the interface is also implicitly abstract, so the method in the interface will be implicitly specified as public abstract (it can only be public abstract, and other modifiers will report errors)
  • The interface contains variables, but the variables in the interface will be implicitly specified as public static final variables (and they can only be public. If they are decorated with private, compilation errors will be reported)
  • The methods in the interface cannot be implemented in the interface. The methods in the interface can only be implemented by the classes that implement the interface

2.1.4 🍛 Differences between abstract classes and interfaces

Before JDK1.8, they had the following differences 👇

  • Methods in abstract classes can have specific executable statements, that is, method bodies, which can implement specific functions of methods, but methods in interfaces cannot (for example: System.out.println("I'm super corn!!");)
  • Member variables in abstract classes can be of various types, while member variables in interfaces can only be of public static final type
  • Interfaces cannot contain static code blocks and the use of static methods (Methods decorated with static), while abstract classes can have static code blocks and static methods
  • A class can only inherit one abstract class, while a class can implement multiple interfaces

Here we should pay attention to:
After JDK1.8, interfaces are allowed to contain static methods, method bodies, and concrete implementation methods. This method is called "default method", which is decorated with the default keyword
After JDK1.9, methods can be defined as private, so that some reused code will not expose methods
The significance of abstract classes is to enable the compiler to better verify. Generally, we do not use abstract classes directly, but use their subclasses. If we accidentally create objects through abstract classes, the compiler will remind us in time.

be careful 🍙: You can browse the above contents roughly. It doesn't matter if you don't understand them. I will explain them one by one for you, and then look back at these knowledge points. You will have a feeling of waking up from a dream

So what is an interface in real life? It can be the USB port and power socket on the notebook


These interfaces are also different in implementation and use standards

  • On the USB port of the computer, you can insert: U disk, mouse, keyboard... All devices that conform to the USB protocol
  • On the power socket, you can plug in: computers, televisions, rice cookers... All devices that meet the specifications

From the above examples, we can see that an interface is a public code of conduct. When implementing it, as long as it conforms to the standard, it can be used universally. In Java, an interface can be regarded as a public specification of multiple classes and a reference data type

two point two 🍱 rule of grammar

The definition format of the interface is basically the same as that of the definition class. Replacing the class keyword with the interface keyword defines an interface.

public interface Interface name{
    //Abstract method
    public abstract void method1();
    //public abstract is a fixed collocation and can be left blank
    public void method2();
    abstract void method3();
    void method4();
    
    //Note: the above methods in the interface are abstract methods, so method4 is cleaner to write code in this way
}

Tips 🍙 :

  1. When creating an interface, the name of the interface generally begins with the capital letter I (read ai)
  2. The naming of interfaces generally uses adjective part of speech words
  3. Alibaba code specification stipulates that methods and attributes in the interface should not be modified to keep the code clean

two point three 🍕 Use of interfaces

The interface cannot be instantiated directly. There must be a class to implement it and implement all the abstract methods in the interface

public class Class name implements Interface name{
    //...
}

be careful 🍙 : The child class and parent class are inherited by extensions, and the class and interface are implemented by implements.

USB mouse, USB keyboard class and interface are used in notebook computer to realize functions

  1. USB interface: including the functions of opening and closing the device
  2. Notebook class: including on-off function and USB device function
  3. Mouse class: USB interface and click function
  4. Keyboard: USB interface and input function
//USB interface
public interface USB{
    void openDevice();
    void closeDevice();
}

//Mouse class, realizing USB interface
public class Mouse implements USB{
    @Override
    public void openDevice(){
        System.out.println("Open mouse");
    }
    
    @Override
    public void closeDevice(){
        System.out.println("Turn off the mouse");
    }
    public void click(){
        System.out.println("Mouse click");
    }
}

//Keyboard class, realizing USB interface
public class KeyBoard implements USB {
    @Override
    public void openDevice(){
        System.out.println("Open keyboard");
    }
    
    @Override
    public void closeDevice(){
        System.out.println("turn off keyboard");
    }
    
    public void inPut(){
        System.out.println("keyboard entry");
    }
}

//Notebook: use USB device
public class Computer {
    public void powerOn(){
        System.out.println("Turn on the laptop");
    }
    
    public void powerOff(){
        System.out.println("Turn off the laptop");
    }
    public void useDevice(USB usb){
        usb.openDevice();
        if(USB instanceof Mouse){
            Mouse mouse = (Mouse)usb;
            mouse.click();
        }else if(usb instanceof KeyBoard){
            KeyBoard keyBoard = (KeyBoard)usb;
            keyBoard.inPut();
        }
        usb.closeDevice();
    }
}

//Test class:
public class TestUSB{
    public static void main(String[] args){
        Computer computer = new Computer();
        computer.powerOn();
   
    //Using mouse devices
    computer.useDevice(new Mouse());
    
    //Using keyboard devices
    computer.useDevice(new KeyBoard());
    
    computer.powerOff();
    }
}

Output: 👇

two point four 🌭 Interface characteristics

  1. The interface type is a reference type, but cannot directly new the object of the interface
public class TestUSB {
    public static void main(String[] args){
        USB usb = new USB();
    }
}

//Compilation error: USB is abstract and cannot be instantiated

  1. Each method in the interface is a public abstract method, that is, the method in the interface will be implicitly specified as public abstract (it can only be public abstract, and other modifiers will report errors)
public interface USB {
    //Compilation error: modifier private is not allowed here
    //Or java: missing method body, or declaring abstraction
    private void openDevice();
    void closeDevice();
    //The compiler standards of different JDK versions are different, and the error reports are also different
}
  1. The methods in the interface cannot be implemented in the interface, and can only be implemented by the classes that implement the interface
public interface USB {
    void openDevice();
    
    //Compilation failed: because the method in the interface is an abstract method by default
    //Error: an interface abstract method cannot have a body
}


But if we add a default here, we can implement the method body.

  1. When overriding a method in an interface, you cannot use default as an access right modifier
public interface USB {
void openDevice();//Default to public
void closeDevice();//Default to public
}
public class Mouse implements USB {
    @Override
    void openDevice(){
        System.out.println("Open mouse");
    }
    
    //...
}
//An error will be reported when compiling here. When rewriting the openDevice method in USB, the default modifier cannot be used


To implement this interface, the scope of access qualification modifiers of methods that override this interface is larger than those in the interface

  1. The interface can contain variables, but the variables in the interface will be automatically and implicitly specified as public static final variables by the compiler
public interface USB {
    double brand = 3.0;//Default: final public static decoration
    void openDevice();
    void closeDevice();
}

public class TestUSB {
    public static void main(String[] args){
        System.out.println(USB.brand);
        //It can be accessed directly through the interface name, indicating that the variable is static
        
        //The following writing method will report an error Java: the final variable brand cannot be assigned a value
        USB.brand = 2.0;
        //Description brand has final attribute
    }
}

  1. Interface cannot have static code block and constructor
public interface USB {
    public USB(){
    
    }//Compilation failed
    
    {
    
    }//Compilation failed
    
    void openDevice();
    void closeDevice();
}

  1. Although the interface is not a class, the suffix format of bytecode file after interface compilation is also the same class
  2. If the class does not implement all the abstract methods in the interface, the class must be set as an abstract class
  3. JDK8 specifies that the above default method can be included in the interface

two point five 🍤 Implement multiple interfaces

In Java, there is single inheritance between classes. A class can only have one parent class, that is, multiple inheritance is not supported in Java, but a class can implement multiple interfaces. The following code is used to demonstrate

public class Animal {
    protected String name;
    
    public Animal(String name){
        this.name = name;
    }
}

Then we write a group of interfaces to represent "those who can fly", "those who can run" and "those who can swim"

public interface IFlying {
    void fly();
}

public interface IRunning {
    void run();
}

public interface ISwimming {
    void swim();
}


Next, we will create several concrete animal classes to accept and implement these interfaces
For example, cats can run 👇

public class Cat extends Animal implements IRunning{
    public Cat(String name) {
        super(name);
    }
    
    @Override
    public void run() {
        System.out.println("kitten"+this.name+"Running");
    }
}

Fish can swim 👇

public class Fish extends Animal implements ISwimming{
    public Fish(String name){
     super(name);   
    }
    
    @Override
    public void swim() {
        System.out.println("Small fish"+this.name+"Swimming");
    }
}

And frogs can both run and swim

public class Frog extends Animal implements IRunning,ISwimming{
    public Frog(String name){
        super(name);
    }
    
    @Override
    public void run() {
        System.out.println("frog"+this.name+"Running");
    }

    @Override
    public void swim() {
        System.out.println("frog"+this.name+"Swimming");
    }
}

🍙 Note: when a class implements multiple interfaces, the abstract methods in each interface must be implemented, unless the class is decorated with abstract and is an abstract class

Tips 👉 Using ctrl + i in IDEA can quickly implement interfaces

There is also an animal that thrives on water, land and air. It is a big white goose

public class Goose extends Animal implements IRunning,ISwimming,IFlying{
    public Goose(String name) {
        super(name);
    }

    @Override
    public void fly() {
        System.out.println(this.name+"Flying");
    }

    @Override
    public void run() {
        System.out.println(this.name+"Running");
    }

    @Override
    public void swim() {
        System.out.println(this.name+"Floating on the water");
    }
}

This code shows the most common usage in Java object-oriented programming: a class inherits a parent class and then implements multiple interfaces at the same time
The meaning of inheritance expression is is-a, while the meaning of interface expression is xxx

A cat is an animal that can run
A frog is an animal that can run and be useful
The big white goose is also an animal. It can run, swim and fly

After having an interface, the user of a class does not need to pay attention to whether the attributes of a specific class are consistent, but only to whether a class has a certain feature / function. If so, the corresponding interface can be implemented
So we now implement a walking method

public class TestDemo1 {
    public static void walk(IRunning iRunning){
        System.out.println("I took my little friend for a walk");
        iRunning.run();
    }

    public static void main(String[] args) {
        Cat cat = new Cat("kitten");
        walk(cat);
        
        Frog frog = new Frog("Little frog");
        walk(frog);
    }
}

Output results 👇

As long as they can run, those with the attribute of running can accept the corresponding objects

public class Robot implements IRunning{
    private String name;
    public Robot(String name){
        this.name = name;
    }
    @Override
    public void run() {
        System.out.println(this.name+"Running on wheels");
    }

    public static void main(String[] args) {
        Robot robot = new Robot("robot");
        walk(robot);
    }
}



So the output result is 👇

two point six 🧋 Inheritance between interfaces

In Java, there is single inheritance between classes. A class can implement multiple interfaces, and interfaces can inherit from each other.
That is, multiple inheritance can be achieved by using interfaces
Interfaces can inherit an interface to achieve the effect of reuse. The extends keyword is used here

interface IRunning {
    void run();
}

interface ISwimming {
    void swim();
}

//Amphibious animals can both run and swim
interface IAmphibious extends IRunning ISwimming {

}

class Frog implements IAmphibious {
    ...
}

Create a new interface through interface inheritance. IAmphibious means "amphibious".
The Frog class created implements this amphibious interface

Inheritance between interfaces is equivalent to merging multiple interfaces together

two point seven 🥘 Examples of interface usage

We explained sorting arrays in the previous array, so how do we sort object arrays?
First, we define a Student class, and then rewrite the String method

public class Student {
    private String name;
    private int score;
    public Student(String name,int score){
        this.name = name;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", score=" + score +
                '}';
    }
}

We also give an array of student objects and sort them according to the elements in the array
Here we sort in descending order of scores

public class Student {
    private String name;
    private int score;
    public Student(String name,int score){
        this.name = name;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", score=" + score +
                '}';
    }

    public static void main(String[] args) {
        Student[] students = new Student[]{
                new Student("A",95),
                new Student("B",96), 
                new Student("C",97),
                new Student("D",98),
        };
    }
}

According to our previous understanding, there is a sort method in the array that we can use. Can we use it directly?

Arrays.sort(students);
System.out.println(students);

//Operation results:
Exception in thread "main" java.lang.ClassCastException: class ClassArray.Student cannot be cast to class java.lang.Comparable (ClassArray.Student is in unnamed module of loader 'app'; java.lang.Comparable is in module java.base of loader 'bootstrap')
	at java.base/java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:320)
	at java.base/java.util.ComparableTimSort.sort(ComparableTimSort.java:188)
	at java.base/java.util.Arrays.sort(Arrays.java:1041)
	at ClassArray.Student.main(Student.java:36)


We can see that the program reports an error, which means that the Student does not implement the compatible interface
So the sort here is to compare ordinary numbers, and the size relationship is clear. What we specify is the reference variable of two student objects. This size relationship is wrong. We need to specify the comparison elements in the object artificially
So how?

We can use the Student class to implement the Comparable interface and the compareTo method

public class Student implements Comparable<Student>{
    private String name;
    private int score;

    public Student(String name,int score){
        this.name = name;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", score=" + score +
                '}';
    }

    @Override
    public int compareTo(Student o) {
        if (this.score>o.score){
            return -1;
//      Returns a number less than 0 if the current object should precede the parameter object
        } else if(this.score<o.score){
            return 1;
//      Returns a number greater than 0 if the current object should rank after the parameter object
        } else{
            return 0;
//      Returns 0 if the current object and the parameter object are in no order      
        }
        
    }
}

So here we rewrite the compareTo method and define our own comparison rules. Then we write a sort method and call the compareTo method to sort the object array in a real sense
We use bubble sorting

    public static void sort(Comparable[] array){
//        Note that although an interface cannot instantiate an object,
//        However, the reference variable of an interface type can point to its implementation class object
//        The implementation class object here is the object that implements this interface
//        For example, Comparable[] comparable = new Student[3];
//        So the parameters here can be received with a Comparable[] array
        for (int bound = 0;bound<array.length;bound++){
            for (int cur = array.length-1;cur>bound;cur--){
                if (array[cur-1].compareTo(array[cur])>0){
                    //This shows that the sequence does not meet the requirements. Exchange the positions of two variables
                    Comparable tmp = array[cur-1];
                    array[cur-1] = array[cur];
                    array[cur] = tmp;
                }
            }
    }
}

The sort method is written. Let's write a main function to test it

    public static void main(String[] args) {
        Student[] students = new Student[]{
                new Student("A",95),
                new Student("B",91),
                new Student("C",97),
                new Student("D",95),
        };
        System.out.println("sort front:"+Arrays.toString(students));
        sort(students);
        System.out.println("sort After:"+Arrays.toString(students));
    }

Running results 👇

E:\develop\Java\jdk-11\bin\java.exe "-javaagent:E:\IDEA\IntelliJ IDEA Community Edition 2021.3.2\lib\idea_rt.jar=65257:E:\IDEA\IntelliJ IDEA Community Edition 2021.3.2\bin" -Dfile.encoding=UTF-8 -classpath E:\JAVAcode\gyljava\Interface\out\production\Interface ClassArray.Student
sort front:[Student{name='A', score=95}, Student{name='B', score=91}, Student{name='C', score=97}, Student{name='D', score=95}]
sort After:[Student{name='C', score=97}, Student{name='A', score=95}, Student{name='D', score=95}, Student{name='B', score=91}]

So what if we want to sort by name? It's ok

import java.util.Arrays;
import java.util.Comparator;
/**
 * Created with IntelliJ IDEA.
 * Description: Hello,I would appreciate your comments~
 * User:Gremmie
 * Date: -04-13
 * Destination:Using the interface of Comparable to realize the selective sorting of object array
 */
class Student implements Comparable<Student>{
    public String name;
    public int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public int compareTo(Student o) {
        return this.name.compareTo(o.name);
    }
}

class AgeComparator implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.age-o2.age;
    }
}

class NameComparator implements Comparator<Student> {

    @Override
    public int compare(Student o1, Student o2) {
        return o1.name.compareTo(o2.name);
    }
}

public class TestDemo {

    public static void main(String[] args) {
        Student[] students = new Student[3];
        students[0] = new Student("zhangsan",19);
        students[1] = new Student("lisi",8);
        students[2] = new Student("abc",78);
        AgeComparator ageComparator = new AgeComparator();
        NameComparator nameComparator = new NameComparator();
        
        
        //The method sort here is self-contained in the Array, which is very convenient,
        //Just pass the comparator we wrote
        System.out.println("Before sorting:"+Arrays.toString(students));
        Arrays.sort(students,nameComparator);
        System.out.println("After sorting:"+Arrays.toString(students));
        Comparable<Student>[] studentComparable =students;
    }

    public static void main2(String[] args) {
        /*Student students1 = new Student("zhangsan",19);
        Student students2 = new Student("abc",78);
        if(students2.compareTo(students1) > 0) {
            System.out.println("fafaa");
        }*/


    }
    public static void main1(String[] args) {
        Student[] students = new Student[3];
        students[0] = new Student("zhangsan",19);
        students[1] = new Student("lisi",8);
        students[2] = new Student("abc",78);
        System.out.println("Before sorting:"+Arrays.toString(students));
        Arrays.sort(students);
        System.out.println("After sorting:"+Arrays.toString(students));
    }
}

two point eight 🤯 Clonable interface and deep copy

Its function, as its name suggests, is to clone. Clonable is a very useful interface.
There is a clone method in the Object class. Calling this method can create an Object and implement "copy".
However, if we want to legally call the clone method, we must first implement the Clonable interface,
Otherwise, CloneNotSupportedException will be thrown

/**
 * Created with IntelliJ IDEA.
 * Description: Hello,I would appreciate your comments~
 * User:Gremmie
 * Date: -04-13
 * Destination:Clone method is implemented by using Clonable interface to clone objects containing objects
 */
class Money implements Cloneable{
    public double money = 19.9;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Person implements Cloneable{
    public int id = 1234;
    public Money m = new Money();

    @Override
    public String toString() {
        return "Person{" +
                "id='" + id + '\'' +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person tmp = (Person) super.clone();
        tmp.m = (Money) this.m.clone();
        return tmp;
        //return super.clone();
    }

}
public class TestDemo {

    public static void main(String[] args) {
        Object o = new Person();

        Object o2 = new Money();


    }

    public static void main1(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person();
        Person person2 = (Person)person1.clone();
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
        System.out.println("=========================");
        person2.m.money = 99.99;
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
    }
}

If we only use the clone, we only copy the object of Person. However, we do not copy the money object in Person, but simply copy an address. Here, we need to make a deep copy. The money class also accepts the Clonable interface. In this way, money will also be cloned when calling the clone method

That's all for the interface. If the article is not perfect, please point it out in the comment area 😊
Hope to help you.
Thanks for reading~

Tags: Java IDEA

Posted by ArneR on Thu, 02 Jun 2022 04:31:54 +0530