Java core technology - interface, lambda expression and inner class

This chapter will mainly introduce:

Interface technology: It is mainly used to describe what functions the class has, but does not give the specific implementation of each function. A class can implement one or more interfaces.

lambda expression: This is a concise way of expressing a block of code that can be executed at some point in the future.

Inner class mechanism: An inner class is defined inside another class, and the methods in it can access the fields of the outer class that contains them.

Proxy: An object that implements an arbitrary interface.

1 interface

1.1 The concept of interface

Concept: An interface is not a class, but a set of requirements descriptions for classes, and these classes are defined in accordance with the unified format of interface descriptions.

"If the class conforms to a specific interface, then perform the service":

The sort method in the Arrays class promises to sort the array of objects, but requires the following prerequisites: The class to which the object belongs must implement the Comparable interface.

All methods in an interface are automatically public. Therefore, when declaring a method in an interface, it is not necessary to provide the keyword public.

Constants can be defined in interfaces, but they must not contain instance fields. After Java SE 8, simple methods can be provided in interfaces (instance fields cannot be referenced)

The task of providing instance fields and method implementations should be done by classes that implement interfaces, which can be thought of as abstract classes without instance fields.

In order for a class to implement an interface, the following steps are required:

1. Declare the class as implementing the given interface (implements keyword).

2. Define all the methods in the interface (when implementing the interface, the method must be declared as public).

Reasons for implementing the interface without providing the compareTo method directly:

Java is a strongly typed language, when calling a method, the compiler will check if the method exists. The class that implements the Compareble interface must have this method.

1.2 Characteristics of the interface

An interface is not a class, so you cannot instantiate an interface with new, however, you can declare variables of the interface, and the interface variables must refer to the class object that implements the interface.

Use instanceof to check whether an object belongs to a specific class, and use instanceof to check whether an object implements a specific interface

Constants in the interface are automatically set to public static final.

Although each class can only have one superclass, it can implement multiple interfaces. This provides a great deal of flexibility in defining the behavior of the class. (separate each implemented interface with a comma)

1.3 Interfaces and abstract classes

The difference between interface and abstract class:

Using abstract classes to represent generic properties has the problem that each class can only extend with one class, but each class can implement multiple interfaces.

1.4 Static methods

In Java SE 8, it is allowed to add static methods to interfaces.

So far, it has been common practice to put static methods in companion classes. In the standard library, you'll see pairs of interfaces and utility classes such as Collection/Collections or Path/Paths.

This companion class implements some or all of the methods of the corresponding interface.

Now as long as the static method is added when implementing the interface, there is no need to provide an additional companion class for using the utility method.

1.5 Default method

A default implementation can be provided for interface methods. Such a method must be marked with the default modifier.

Classes implementing this interface can optionally override default methods in the interface.

An important use of default methods is - interface evolution (adding default methods to the originally designed interface without recompiling all classes that implemented the interface before and these classes will call the implementation in the interface when they call the newly added method)

1.6 Resolving default method conflicts

Consider this situation: what happens if you define a method as a default method in an interface and then define the same method in a superclass or another interface? (ambiguity)

The processing rules in Java are as follows:

1. The super class takes precedence (considering the compatibility of the new default methods of the interface)

2. Interface conflict: consider three cases

1. There is a default implementation of this method in both interfaces - this method must be overridden to resolve conflicts (you can choose the default implementation provided by either of the two conflicting methods)

2. One of the two interfaces has a default implementation of this method - this method must be overridden to resolve the conflict (you can choose which of the two conflicting methods provides a default implementation)

3. There is no default implementation of this method in either interface - this method may or may not be implemented. If not implemented, the class itself is abstract


 

2 Interface example

2.1 Interface and callback

Callbacks are a common programming pattern. In this pattern, you can indicate the actions that should be taken when a certain event occurs.

ActionListener listen = new TimePrinter ();
Timer time = new Timer (10000, listen)

2.2 Comparator interface

Consider a situation like this:

A class that itself already inherits the Comparable interface has a lexicographically sorted comparaTo method. Now we want to sort this class in order of increasing length. rather than lexicographically.

To address this situation, consider taking an array and a comparator as parameters, which is an instance of a class that implements the Comparator interface.

Comparator<String> comp=new LengthComparator();
if(comp.compare(words[i],words[j])>0...

Compare this call to words[i].compareTo(words[j]). The compare method is called on the comparator object, not on the string itself.

The difference between Comparator and Comparable:

1. When using Comparator to compare, you need to create a specific instance of Comparator first

2. The Comparator call object is the comparator, and the comparable call object is the string itself

3. Use Comparator to achieve more variety of comparison methods

2.3 Object Cloning

This section discusses the Cloneable interface, which indicates that a class provides a safe clone method

Consider a situation like this:

When we make a copy of a variable that contains an object reference, both the original variable and the copy are references to the same object. This means that a change in any one variable will affect the other variable.

Employee origina=new Employee("john Public",50000);
Employee copy=original;
copy.raiseSalary(10);

If you want copy to be a new object with the same initial state as original, but then they will each have their own different states, in which case you can use the clone method.

Employee copy=original.clone();
copy.raiseSalary(10);

The default clone operation is a shallow copy , and does not clone other objects referenced in the object.

It is safe to use a shallow copy if all subobjects in the original object are immutable.

If the child object belongs to an immutable class, a deep copy is required .

For each class, determine:

1. Whether the default clone method meets the requirements;

2. Is it possible to call clone on a mutable subobject to patch the default clone method;

If either the first or the second is selected, the class must:

1. Implement the Cloneable interface;

2. Redefine the clone method and specify the public access modifier.

The clone method in Object is declared as protected, so it needs to be redefined as public in the implementation class before the clone method of the instantiated object of this implementation class can be called in other classes.

The Cloneable interface is a marker interface, and the marker interface does not contain any methods; its only function is to allow instanceof to be used in type queries

If you call clone on an object whose class does not implement the Cloneable interface, the clone method of the Object class will throw a CloneNotSupportedException.

All array types have a public clone method


 

3 lambda expressions

Define code blocks using a concise syntax

3.1 Why lambda expressions were introduced

A lambda expression is a transitive block of code that can be executed one or more times later.

Such as passing an instance of a class that implements the ActionListener interface to a timer or an instance of a class that implements the Comparator interface to the sort method.

3.2 Syntax of lambda expressions

(String first,String second)
    ->first.length()-second.length()

This is the first lambda expression you see. A lambda expression is just a block of code, and a variable specification that must be passed into the code.

Empty parentheses are still provided even if the lambda expression has no parameters

()->{for(int i=100;i>=0;i--)System.out.println(i);}

If the parameter type of a lambda expression can be deduced, its type can be ignored

Comparator<String> comp
    =(first,second)
        ->first.length()-second.length();

If the method has only one parameter, and the type of the parameter can be deduced, then the parentheses can even be omitted:

ActionListener listener=event->
    System.out.println("The time is"+new Date());

No need to specify the return type of the lambda expression

It is not legal if the lambda expression only returns a value in some branches and no value in others.

(int x)->{if(x>=0)return 1;}

3.3 Functional interface

Concept: An interface with only one abstract method is called a functional interface

Functional interfaces can be replaced with lambda expressions

For example: Comparator is an interface with only one method, so you can provide a lambda expression

Arrays.sort(words,
    (first,second)->first.length()-second.length());

Under the hood, the Arrays.sort method accepts an object of a class that implements Comparator<String> . Calling the compare method on this object executes the body of the lambda expression. (To accept a lambda expression can be passed to a functional interface)

It's best to think of a lambda expression as a function, not an object.

In fact, in Java, all you can do with a lambda expression is convert it to a functional interface.

3.4 Method references

To use the :: operator to separate a method name from an object or class name, there are three main cases:

*object::instanceMethod

*Class::staticMethod

*Class::instanceMethod

In the first two cases, a method reference is equivalent to a lambda expression that provides method parameters:

The expression System.out::println is a method reference, which is equivalent to the lambda expression x->System.out.println(x)

The expression Math::pow is a method reference, which is equivalent to the lambda expression (x,y)->Math.pow(x,y)

For the third case, the first parameter becomes the target of the method:

The expression String:;compareToIgnoreCase is a method reference, which is equivalent to (x,y)->x.compareToIgnoreCase(y)

Similar to lambda expressions, method references cannot stand on their own and are always converted to instances of functional interfaces

You can use this and super parameters in method references

this::equals is equivalent to x->this, equals(x)

3.5 Constructor references

Constructor references are similar to method references, except that the method name is new. For example, Person::new is a reference to the Person constructor. Which constructor is called depends on the context.

Constructor references can be created with array types, for example, int[]::new is a constructor reference, equivalent to the lambda expression x->new int[x]

Java has a limitation that an array of generic type T cannot be constructed. Array constructor references are useful to overcome this limitation.

3.6 Variable scope

Often, you might want to be able to access variables in enclosing methods or classes from within a lambda expression.

example:

public static void repeatMessage(String text,int delay)
{
    ActionListener listener=event->
        {
            System.out.priintln(text);
            Toolkit.getDefaultToolkit().beep();
        };
    new Timer(delay,listener).start();
}

The code for the lambda expression may run long after the repeatMessage call returns, when the parameter variable no longer exists. How to keep the text variable?

A lambda expression consists of the following three parts:

1. A code block;

2. Parameters;

3. The value of a free variable, which is a variable that is not a parameter and is not defined in the code.

In Java, lambda expressions are closures.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325163031&siteId=291194637