Java methods refer to beginners'introductory notes

Posted by menios on Thu, 23 Sep 2021 21:25:18 +0200

Interface Composition

With the updating of java, the composition of the interface has introduced some new content as follows.

Composition of the interface

  • Constant: public static final (this default modifier can be omitted)
  • Abstract method: public abstract (this default modifier can also be omitted)
  • Default method (Java8 started)
  • Static methods (Java8 started)
  • Interface methods (introduced in Java9)

Default method of interface

A simple example to introduce

public class MyInterfaceDemo {
    public static void main(String[] args) {
        MyInterface my=new MyInterfaceImplOne();
        my.show1();
        my.show2();
        
    }
}
public interface MyInterface {
    void show1();
    void show2();
}
public class MyInterfaceImplOne implements MyInterface{
    @Override
    public void show1() {
        System.out.println("One show 1");
    }

    @Override
    public void show2() {
        System.out.println("One show 2");

    }
}
public class MyInterfaceImplTwo implements MyInterface{

    @Override
    public void show1() {
        System.out.println("Two show 1");
    }

    @Override
    public void show2() {
        System.out.println("Two show 2");

    }
}

However, once the interface is upgraded, such as adding a show3() method to the interface, the following will occur.

The interface has been upgraded, but the abstract method has not been overridden in the implementation class.
In this case, you need to override the abstract method, which is not a good design. Imagine upgrading an interface so that you can manually implement all the implementation classes once the new abstract class method is added to the interface, which is as painful as the implementation engineer I'm working on now.

Improvement

You can do this by defining a new interface, MyInterfaceSon, to inherit the MyInterface interface. Add a new abstract method, show3(), to MyInterfaceSon. Let the previous method implement the new interface, MyInterfaceSon. The following:

public class MyInterfaceDemo {
    public static void main(String[] args) {
        MyInterfaceSon my=new MyInterfaceImplOne();
        my.show1();
        my.show2();
        my.show3();

        MyInterface my1=new MyInterfaceImplTwo();
        my1.show1();
        my1.show2();

    }
}
public interface MyInterface {
    void show1();
    void show2();
}
public interface MyInterfaceSon extends MyInterface{
    void show3();
}

public class MyInterfaceImplOne implements MyInterfaceSon{
    @Override
    public void show1() {
        System.out.println("One show 1");
    }

    @Override
    public void show2() {
        System.out.println("One show 2");

    }

    @Override
    public void show3() {
        System.out.println("One Show 3");
    }
}
public class MyInterfaceImplTwo implements MyInterface{

    @Override
    public void show1() {
        System.out.println("Two show 1");
    }

    @Override
    public void show2() {
        System.out.println("Two show 2");

    }

But to tell the truth, it's still not good. We need to change a lot.

Re-improvement

In fact, there is an appropriate method after Java 8, the default method. Here's how.

Introduction to default methods in interfaces

Define Format

public default return value type method name (parameter list) {}

Example: public default void show3(){}

Default method improvements for the examples introduced above

public class MyInterfaceDemo {
    public static void main(String[] args) {
        MyInterface my=new MyInterfaceImplOne();
        my.show1();
        my.show2();
        my.show3();

        MyInterface my1=new MyInterfaceImplTwo();
        my1.show1();
        my1.show2();
        my1.show3();

    }
public interface MyInterface {
    void show1();
    void show2();

    public default void show3() {
        System.out.println("Default Method show3");

    }
}
public class MyInterfaceImplOne implements MyInterface{
    @Override
    public void show1() {
        System.out.println("One show 1");
    }

    @Override
    public void show2() {
        System.out.println("One show 2");

    }


}
public class MyInterfaceImplTwo implements MyInterface{

    @Override
    public void show1() {
        System.out.println("Two show 1");
    }

    @Override
    public void show2() {
        System.out.println("Two show 2");

    }


}

This is still very concise.

Be careful

  • Default methods are not abstract, so they are not forced to be overridden. When overriding, be careful to remove the default keyword.
  • public can be omitted, but default cannot be omitted.

Static methods in interfaces

format

public static return value type method name (parameter list) {}

Example: public static void show3(){}

case

public class InterDemo {
    public static void main(String[] args) {
        Inter i=new InterImpl();
        i.show();
        i.method();

        Inter.test();
    }
}
public interface Inter {
    void show();

    default void method() {
        System.out.println("Inter Default method in");
    }

    public static void test(){
        System.out.println("Inter The static method in");
    }

}
public class InterImpl implements Inter{

    @Override
    public void show() {
        System.out.println("show Method Executed");
    }
}

Be careful

  • Static methods can only be called by interface names, not by class or object names
  • public can be omitted, but static cannot be omitted.

It is not understandable to call by class name. If a class implements two interfaces and both interfaces have static method test(), which one is called by class name or object name?

Private methods in interfaces

Private methods with method bodies have been added to Java9. Default and static methods are referenced in java8. When both methods contain the same piece of code, the program must consider abstracting the implementation code of the two methods into a common method, which does not need to be used by others and is therefore hidden from the public.
Perhaps the above "program must be considered" may be confusing, but in a nutshell it is.
The code below contains the same three middle lines of some methods that can be extracted and placed in one method.

public interface Inter {
    default void show1() {
        System.out.println("show1 Start execution");
        System.out.println("111111");
        System.out.println("222222");
        System.out.println("333333");
        System.out.println("show1 End Execution");
    }

    default void show2(){
        System.out.println("show2 Start execution");
        System.out.println("111111");
        System.out.println("222222");
        System.out.println("333333");
        System.out.println("show2 End Execution");
    }
    static void method1(){
        System.out.println("method1 Start execution");
        System.out.println("111111");
        System.out.println("222222");
        System.out.println("333333");
        System.out.println("method1 End Execution");
    }
    static void method2(){
        System.out.println("method2 Start execution");
        System.out.println("111111");
        System.out.println("222222");
        System.out.println("333333");
        System.out.println("method2 End Execution");
    }
}

Definition format for private methods in interfaces

  • Format 1: private return value type method name (parameter list) {}
  • Format 2: private static return value type method name (parameter list) {}

Example

public class InterDemo {
    public static void main(String[] args) {
        Inter i=new InterImpl();
        i.show1();
        i.show2();

        Inter.method1();
        Inter.method2();

    }
}
public class InterImpl implements Inter{
}
public interface Inter {

    private void show(){
        System.out.println("111111");
        System.out.println("222222");
        System.out.println("333333");
    }

    private static void method(){
        System.out.println("111111");
        System.out.println("222222");
        System.out.println("333333");
    }
    default void show1() {
        System.out.println("show1 Start execution");
        show();
        System.out.println("show1 End Execution");
    }

    default void show2(){
        System.out.println("show2 Start execution");
        show();
        System.out.println("show2 End Execution");
    }
    static void method1(){
        System.out.println("method1 Start execution");
        method();
        System.out.println("method1 End Execution");
    }
    static void method2(){
        System.out.println("method2 Start execution");
        method();
        System.out.println("method2 End Execution");
    }
}

Be careful

  • The default method can call private static and non-static methods
  • Static methods can only call static private methods.

Method Reference

Method Reference First Experience

When using lambda expressions, the code passed in is actually a solution. A solution that takes parameters and operates on them.
When the same solution already exists and you don't want to override it, you can use method references to use the existing solution.

Example

public class PrintableDemo {
    public static void main(String[] args) {
        usePrintable((String s)->{
            System.out.println(s);
        });

        usePrintable(System.out::println);

    }

    private static void usePrintable(Printable p){
        p.PrintString("It's too hard to run until the end of the month");
    }
}
public interface Printable {
    void PrintString(String s);
}

Method References

  • :: For a method reference, the expression it is in becomes a method reference

Derivation and Omitting

  • If lambda is used, they will be automatically deduced without specifying parameter types or overload forms according to the principle of "deductible is omitted"
  • If a method reference is used, it can also be deduced from the context
  • Method reference is lambda's twin brother

Example

public class PrintableDemo {
    public static void main(String[] args) {
        usePrintable(i-> System.out.println(i));

        usePrintable(System.out::println);
    }


    private static void usePrintable(Printable p){
        p.printInt(666);
    }
}
public interface Printable {
    void printInt(int i);
}

Method reference indicated by Lambda expression

  • Reference Class Method
  • Instance method of reference object
  • Instance method of reference class
  • Reference Constructor

Reference Class Method

It's simply a static method of referencing a class

  • Format: Class name:: Static method
    Example: Interger::parseInt
    Interger class method: public static int parseInt(String s) converts this String to int type data

Practice

public class ConverterDemo {
    public static void main(String[] args) {
        useConverter((String s)->{
            return Integer.parseInt(s);
        });

        useConverter(s->Integer.parseInt(s));

        useConverter(Integer::parseInt);

    }
    private static void useConverter(Converter c){
        int number=c.Convert("666");
        System.out.println(number);
    }
}

public interface Converter {
    int Convert(String s);
}

Instance method of reference object

An instance method of a reference object is actually a member method of a reference class.

  • Format: Object: Member Method
    Example:'HelloWorld':'toUpperCase'
    This is the method in the String class above
    Public String to Upper (String s): Turn characters in this String to uppercase

Practice

public class PrinterDemo {
    public static void main(String[] args) {
        usePrinter((String s)->{
            String result=s.toUpperCase();
            System.out.println(result);
        });

        PrintString ps=new PrintString();
        usePrinter(ps::printUpper);

    }

    private static void usePrinter(Printer p){
        p.printUpperCase("HelloWorld");
    }
}
public class PrintString {
    public void printUpper(String s){
        String result=s.toUpperCase();
        System.out.println(result);
    }
}
public interface Printer {
    void printUpperCase(String s);

}

Instance method of reference class

An instance method of a reference class is essentially a member method of a reference class.

  • Format: Class name: Member method
    Example: String::subString
    public String substring(int beginIndex,int endIndex)

Practice

public class MyStringDemo {
    public static void main(String[] args) {
        useMyString((String s,int x,int y)->{
            return s.substring(x,y);
        });

        useMyString(String::substring);

    }
    private static void useMyString(MyString ms){
        String s=ms.mySubString("HelloWorld",2,4);
        System.out.println(s);
    }
}
public interface MyString {
    String mySubString(String s,int x,int y);
}

Reference Constructor

A reference constructor is actually a reference construction method.

  • Format: Class name::new
    Example: Student

Practice

public class StudentDemo {
    public static void main(String[] args) {
        useStudentBuilder((name,age)->{
            Student s=new Student(name,age);
            return s;
        });
        useStudentBuilder(Student::new);

    }

    private static void useStudentBuilder(StudentBuilder sb){
        Student s=sb.build("Miao Xiao Orange",22);
        System.out.println(s.getName()+","+s.getAge());
    }
}
public interface StudentBuilder {
    Student build(String name,int age);
}
public class Student {
    private String name;
    private int age;

    public Student(){}

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

Topics: Java