概述
Defining an Interface
An interface declaration consists of modifiers, the keyword interface
, the interface name, a comma-separated list of parent interfaces (if any), and the interface body. For example:
public interface GroupedInterface extends Interface1, Interface2, Interface3 {
// constant declarations
// base of natural logarithms
double E = 2.718282;
// method signatures
void doSomething (int i, double x);
int doSomethingElse(String s);
}
The public
access specifier indicates that the interface can be used by any class in any package. If you do not specify that the interface is public, then your interface is accessible only to classes defined in the same package as the interface.
An interface can extend other interfaces, just as a class subclass or extend another class. However, whereas a class can extend only one other class, an interface can extend any number of interfaces. The interface declaration includes a comma-separated list of all the interfaces that it extends.
The Interface Body(接口主体,重点看下面的说明,如果不太懂,请使用百度翻译)
The interface body can contain abstract methods, default methods, and static methods. An abstract method within an interface is followed by a semicolon, but no braces (an abstract method does not contain an implementation). Default methods are defined with the default
modifier, and static methods with the static
keyword. All abstract, default, and static methods in an interface are implicitly public
, so you can omit the public
modifier.
In addition, an interface can contain constant declarations. All constant values defined in an interface are implicitly public
, static
, and final
. Once again, you can omit these modifiers.
Evolving Interfaces(如何扩充接口)
Consider an interface that you have developed called DoIt
:
public interface DoIt {
void doSomething(int i, double x);
int doSomethingElse(String s);
}
Suppose that, at a later time, you want to add a third method to DoIt
, so that the interface now becomes:
public interface DoIt {
void doSomething(int i, double x);
int doSomethingElse(String s);
boolean didItWork(int i, double x, String s);
}
If you make this change, then all classes that implement the old DoIt
interface will break because they no longer implement the old interface. Programmers relying on this interface will protest loudly.
Try to anticipate all uses for your interface and specify it completely from the beginning. If you want to add additional methods to an interface, you have several options. You could create a DoItPlus
interface that extends DoIt
:
public interface DoItPlus extends DoIt {
boolean didItWork(int i, double x, String s);
}
Now users of your code can choose to continue to use the old interface or to upgrade to the new interface.
Alternatively, you can define your new methods as default methods. The following example defines a default method named didItWork
:
public interface DoIt {
void doSomething(int i, double x);
int doSomethingElse(String s);
default boolean didItWork(int i, double x, String s) {
// Method body
}
}
Note that you must provide an implementation for default methods. You could also define new static methods to existing interfaces. Users who have classes that implement interfaces enhanced with new default or static methods do not have to modify or recompile them to accommodate the additional methods.
Default Methods(重点了解)
The section Interfaces describes an example that involves manufacturers of computer-controlled cars who publish industry-standard interfaces that describe which methods can be invoked to operate their cars. What if those computer-controlled car manufacturers add new functionality, such as flight, to their cars? These manufacturers would need to specify new methods to enable other companies (such as electronic guidance instrument manufacturers) to adapt their software to flying cars. Where would these car manufacturers declare these new flight-related methods? If they add them to their original interfaces, then programmers who have implemented those interfaces would have to rewrite their implementations. If they add them as static methods, then programmers would regard them as utility methods, not as essential, core methods.
Default methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces.
Consider the following interface, TimeClient
, as described in Answers to Questions and Exercises: Interfaces:
import java.time.*;
public interface TimeClient {
void setTime(int hour, int minute, int second);
void setDate(int day, int month, int year);
void setDateAndTime(int day, int month, int year,
int hour, int minute, int second);
LocalDateTime getLocalDateTime();
}
The following class, SimpleTimeClient
, implements TimeClient
:
package defaultmethods;
import java.time.*;
import java.lang.*;
import java.util.*;
public class SimpleTimeClient implements TimeClient {
private LocalDateTime dateAndTime;
public SimpleTimeClient() {
dateAndTime = LocalDateTime.now();
}
public void setTime(int hour, int minute, int second) {
LocalDate currentDate = LocalDate.from(dateAndTime);
LocalTime timeToSet = LocalTime.of(hour, minute, second);
dateAndTime = LocalDateTime.of(currentDate, timeToSet);
}
public void setDate(int day, int month, int year) {
LocalDate dateToSet = LocalDate.of(day, month, year);
LocalTime currentTime = LocalTime.from(dateAndTime);
dateAndTime = LocalDateTime.of(dateToSet, currentTime);
}
public void setDateAndTime(int day, int month, int year,
int hour, int minute, int second) {
LocalDate dateToSet = LocalDate.of(day, month, year);
LocalTime timeToSet = LocalTime.of(hour, minute, second);
dateAndTime = LocalDateTime.of(dateToSet, timeToSet);
}
public LocalDateTime getLocalDateTime() {
return dateAndTime;
}
public String toString() {
return dateAndTime.toString();
}
public static void main(String... args) {
TimeClient myTimeClient = new SimpleTimeClient();
System.out.println(myTimeClient.toString());
}
}
Suppose that you want to add new functionality to the TimeClient
interface, such as the ability to specify a time zone through a ZonedDateTime
object (which is like a LocalDateTime
object except that it stores time zone information):
public interface TimeClient {
void setTime(int hour, int minute, int second);
void setDate(int day, int month, int year);
void setDateAndTime(int day, int month, int year,
int hour, int minute, int second);
LocalDateTime getLocalDateTime();
ZonedDateTime getZonedDateTime(String zoneString);
}
Following this modification to the TimeClient
interface, you would also have to modify the class SimpleTimeClient
and implement the method getZonedDateTime
. However, rather than leaving getZonedDateTime
as abstract
(as in the previous example), you can instead define a default implementation. (Remember that an abstract method is a method declared without an implementation.)
package defaultmethods;
import java.time.*;
public interface TimeClient {
void setTime(int hour, int minute, int second);
void setDate(int day, int month, int year);
void setDateAndTime(int day, int month, int year,
int hour, int minute, int second);
LocalDateTime getLocalDateTime();
static ZoneId getZoneId (String zoneString) {
try {
return ZoneId.of(zoneString);
} catch (DateTimeException e) {
System.err.println("Invalid time zone: " + zoneString +
"; using default time zone instead.");
return ZoneId.systemDefault();
}
}
default ZonedDateTime getZonedDateTime(String zoneString) {
return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
}
}
You specify that a method definition in an interface is a default method with the default
keyword at the beginning of the method signature. All method declarations in an interface, including default methods, are implicitly public
, so you can omit the public
modifier.
With this interface, you do not have to modify the class SimpleTimeClient
, and this class (and any class that implements the interface TimeClient
), will have the method getZonedDateTime
already defined. The following example,TestSimpleTimeClient
, invokes the method getZonedDateTime
from an instance of SimpleTimeClient
:
package defaultmethods;
import java.time.*;
import java.lang.*;
import java.util.*;
public class TestSimpleTimeClient {
public static void main(String... args) {
TimeClient myTimeClient = new SimpleTimeClient();
System.out.println("Current time: " + myTimeClient.toString());
System.out.println("Time in California: " +
myTimeClient.getZonedDateTime("Blah blah").toString());
}
}
最后
以上就是内向棉花糖为你收集整理的重温Java经典教程(The Java™ Tutorials)第三篇-Java语言-第二章-2.3接口Defining an InterfaceEvolving Interfaces(如何扩充接口)Default Methods(重点了解)的全部内容,希望文章能够帮你解决重温Java经典教程(The Java™ Tutorials)第三篇-Java语言-第二章-2.3接口Defining an InterfaceEvolving Interfaces(如何扩充接口)Default Methods(重点了解)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复