[Java] object oriented -- understanding of interfaces

Keywords: Java OOP

An interface is a further step of an abstract class. An abstract class can also contain non abstract methods and fields. While the methods contained in an interface are abstract methods, and fields can only contain static constants

Sometimes you must derive a subclass from several classes and inherit all their properties and methods. However, Java does not support multiple inheritance. With an interface, you can get the effect of multiple inheritance.

An interface is a collection of definitions of abstract methods and constant values.
In essence, an interface is a special abstract class. This abstract class only contains the definitions of constants and methods, without the implementation of variables and methods.

🎄 rule of grammar

In the example of printing graphics, our parent class Shape does not contain other non abstract methods, and can also be designed as an interface

interface IShape { 
 void draw(); 
} 
class Cycle implements IShape { 
 @Override 
 public void draw() { 
 System.out.println("○"); 
 } 
} 
public class Test { 
 public static void main(String[] args) { 
 IShape shape = new Rect(); 
 shape.draw(); 
 } 
} 

Code interpretation:

  • Define an interface using interface
  • The methods in the interface must be abstract methods, so abstract can be omitted
  • The methods in the interface must be public, so public can be omitted
  • Cycle uses implements to inherit the interface. At this time, the meaning expressed is no longer "extension", but "implementation"
  • When calling, you can also create an interface reference corresponding to an instance of a subclass
  • Interfaces cannot be instantiated alone

Extensions vs. implementations
Extension refers to the further expansion of functions when certain functions already exist
Implementation means that there is nothing at present and needs to be constructed from scratch

The interface can only contain abstract methods. For fields, the interface can only contain final static

interface IShape { 
 void draw(); 
 public static final int num = 10; 
}

The public, static and final keywords can be omitted. The omitted num still represents the public static constant

Tips:

  1. When we create an interface, the name of the interface usually starts with the capital letter I
  2. Interface naming generally uses the word of "adjective"
  3. Ali coding specification stipulates that methods and attributes in the interface should not be decorated with any symbols to keep the code concise

An incorrect code

interface IShape { 
abstract void draw() ; // Even if you do not write public, it is also public 
} 
class Rect implements IShape { 
void draw() { 
System.out.println("□") ; //Permissions are more stringent, so they cannot be overridden.
} 
}

Tip: public, static and final keywords in the interface can be omitted

  • The methods in the interface must be abstract methods, so abstract can be omitted
  • The methods in the interface must be public, so public can be omitted
  • The interface can only contain abstract methods. For fields, the interface can only contain final static

🎄 Implement multiple interfaces

  • Sometimes we need to make a class inherit from multiple parent classes at the same time. This is realized by multiple inheritance in some programming languages
  • However, only single inheritance is supported in Java, and a class can only extend one parent class. However, multiple interfaces can be implemented at the same time, and the similar effect of multiple inheritance can be achieved

Now we represent a group of animals by classes

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

In addition, we provide another set of interfaces, which respectively mean "can fly", "can run" and "can swim"

interface IFlying { 
 void fly(); 
} 
interface IRunning { 
 void run(); 
} 
interface ISwimming { 
 void swim(); 
}

Next, we create several specific animals

Cats can run

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

Fish can swim

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

Frogs can run and swim (amphibians)

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

Swan can fly, run and swim (tripteryx)

class Swan extends Animal implements IRunning, ISwimming, IFlying { 
 public Swan(String name) { 
 super(name); 
 } 
 @Override 
 public void fly() { 
 System.out.println(this.name + "Can fly"); 
 } 
 @Override 
 public void run() { 
 System.out.println(this.name + "Can run"); 
 } 
 @Override 
 public void swim() { 
 System.out.println(this.name + "Can swim"); 
 } 
} 

The operation results are as follows:

The above code shows the most common usage in Java object-oriented programming: a class inherits a parent class and implements multiple interfaces (can run, swim and fly)

The meaning of inheritance expression is is - a semantics, while the meaning of interface expression is xxx

A cat is an animal that can run
Frog is also an animal. It can run and swim
Swan is also an animal. It can run, swim and fly

[what are the benefits of this design?]
Always keep the benefits of polymorphism in mind and let the program forget the type. With an interface, the user of a class does not have to focus on the specific type, but only on whether a class has some ability

🎄 Interface usage instance

Instance: sorting an array of objects

Give a student class first

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 "[" + this.name + ":" + this.score + "]"; 
 } 
}

Give a student object array and sort the elements in the object array (in descending order of scores)

Student[] students = new Student[] { 
 new Student("Zhang San", 95), 
 new Student("Li Si", 96), 
 new Student("Wang Wu", 97), 
 new Student("Zhao Liu", 92), 
}; 

According to our previous understanding, we have a ready-made sort method for arrays. Can we use this method directly?

Arrays.sort(students); 
System.out.println(Arrays.toString(students)); 
// Run error, throw exception 
Exception in thread "main" java.lang.ClassCastException: Student cannot be cast to 
java.lang.Comparable 

After careful thinking, it is not difficult to find that, unlike ordinary integers, two integers can be directly compared, and the size relationship is clear. How to determine the size relationship of two student objects?

At this time, we need to specify additional
Let our Student class implement the Comparable interface and the compareTo method

public class Student implements Comparable{

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

        @Override
        public String toString() {
            return "[" + this.name + ":" + this.score + "]";
        }

        @Override//Rewrite the compare To method in the Comparable interface
        public int compareTo(Object o) {
            Student s = (Student)o;
            if (this.score > s.score) {
                return -1;
            } else if (this.score < s.score) {
                return 1;
            } else {
                return 0;
            }
        }
}

The compareTo method will be called automatically in the sort method (for specific reasons, you can ctrl + left click the sort method to view the source code, which will not be described here). The parameter of compareTo is Object, which is actually an Object of Student type

Then customize the rules for comparing the size relationship between the current object and the parameter object (calculated by score)

  • If the current object should be placed before the parameter object, a number less than 0 is returned;
  • If the current object should be placed after the parameter object, a number greater than 0 is returned;
  • If the current object and the parameter object are in no order, return 0;

Execute the program again and the result will be as expected

matters needing attention:
For the sort method, each object of the array to be passed in is "comparable" and needs the ability of compareTo. By overriding the compareTo method, you can define the comparison rules

The interface is equivalent to having certain capabilities. Here, the Comparable interface means having "Comparable capabilities". The Student class adds (implements) this interface to have Comparable capabilities and can use the sort method to sort

🎄 Inheritance between interfaces

Interfaces can inherit an interface to achieve the effect of reuse. Use the extends keyword

interface IRunning { 
 void run(); 
} 
interface ISwimming { 
 void swim(); 
} 
// Amphibians can run and swim
interface IAmphibious extends IRunning, ISwimming { 
} 
class Frog implements IAmphibious { 
 ... 
}

Create a new interface through interface inheritance. IAmphibious means "amphibious". At this time, to implement the Frog class created by the interface, continue to implement the run method and swim method by rewriting in the Frog class

Inheritance between interfaces is equivalent to merging multiple interfaces together

🎄 Clonable interface and deep and shallow copy

Some useful interfaces are built in Java, and Clonable is one of them

There is a clone method in the Object class. Calling this method can create a "copy" of the Object

However, if you want to call the clone method legally, you must implement the Clonable interface first, otherwise you will throw a clonnotsupportedexception exception

Implement the Clonable interface for the Player class

public class Player implements Cloneable{
    protected String name;
    int []age=new int[1];
    
    public Player(String name, int age) {
        this.name = name;
        this.age[0] = age;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

Create a player1 object and clone a player1
Here we need to focus on understanding deep copy and shallow copy. The clone method defaults to shallow copy! The operation results can prove that

public class Interface test {
    public static void main(String[] args)throws CloneNotSupportedException {
        Player player1 = new Player("kobe",18);

        Player player2 = (Player) player1.clone();//Clone player1

        System.out.println("clone player1");
        System.out.println(player1);
        System.out.println(player2);
        System.out.println();
        System.out.println("player1 Your name and age:"+player1.name+player1.age[0]);
        System.out.println("player2 Your name and age:"+player2.name+player2.age[0]);
        System.out.println("player1 and player2 Are your names the same: " + (player2.name==player1.name));
        System.out.println("player1 and player2 Are they the same age: " + (player2.age[0]==player1.age[0]));
        System.out.println();

        System.out.println("take player2 Change your name to O'Neill and your age to 20");
        player2.name ="O'Neill";//Modify the name of player2
        player2.age[0] =20;//Modify the age of player2
        System.out.println("player1 Your name and age:"+player1.name+player1.age[0]);
        System.out.println("player2 Your name and age:"+player2.name+player2.age[0]);
    }
}

The operation results are as follows

The code may not be easy to understand. It doesn't matter. Please see the figure below

Then change the name and age of player 2


You will find a problem. The age of player 2 is modified, and the age of player 1 will also change, because their age references point to the same place

However, the name is modified. Why is the name of player 1 still the original kobe instead of the O'Neill of player 2? This is because the string constant cannot be modified, but the string reference can be modified. Therefore, a new string "O'Neill" will be created in the string constant pool, and then the new string will be referenced

in summary

What is shallow copy?

  • ① The shallow copy here means that the reference type variable inside the copied object and the reference type variable inside the original object are the same reference (pointing to the same object). As shown in the figure above
  • ② However, the copied object and the new object are not the same object.
  • ③ In short, the new (generated by copying) and old (original) objects are different, but if there are internal variables of reference type, the new and old objects refer to the same reference.

What is deep copy?

  • Deep copy: copy all the contents of the original object, including the reference type of memory

🎄 summary

  • Abstract classes and interfaces are common ways to use polymorphism in Java. Both need to be mastered. At the same time, we should recognize the difference between the two (important!!!)

  • Core difference: abstract classes can contain ordinary methods and fields. Such ordinary methods and fields can be directly used by subclasses (without rewriting), while interfaces cannot contain ordinary methods. Subclasses must override all abstract methods

🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙
        ❤ Originality is not easy. If there is any error, please leave a message in the comment area. Thank you very much ❤
        ❤                 If you think the content is good, it's not too much to give a three company~        ❤
        ❤                              I'll pay a return visit when I see it~                                      ❤
🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙

Posted by pinxue on Sat, 20 Nov 2021 22:32:38 -0800