透过实例看java默认方法和静态方法
2023-04-02 17:46:08
Java SE8对接口引入了两个重要的增强功能:java默认法和静态法。这些增强功能都有特殊的用途,与此同时使接口更像类,让我们一些应用程序可以基于接口而不是类。
默认方法是在接口及其方法头前缀和定义的具体实例方法default关键词。Java标准类库默认方法有java.util.Comparatordefault Comparator reversed()方法。 为假设已经创建了理解基于接口默认方法的用途下面的根据基本操作,Drivable接口描述了任何类型的驱动对象。
声明一个Drivable接口:
public interface Drivable
{
public void drive(int numUnits);
public void start();
public void stop();
public void turnLeft();
public void turnRight();
}
声明Drivable接口之后,其他开发人员可以在其应用程序中广泛使用该界面。例如,下面的例子它介绍了一个简单的应用程序类Drivable和Car实现的DMDemo演示类。
在Drivable在Car类中实现:
class Car implements Drivable
{
@Override
public void drive(int numUnits)
{
System.out.printf("Driving car %d kilometers%n", numUnits);
}
@Override
public void start()
{
System.out.println("Starting car");
}
@Override
public void stop()
{
System.out.println("Stopping car");
}
@Override
public void turnLeft()
{
System.out.println("Turning car left");
}
@Override
public void turnRight()
{
System.out.println("Turning car right");
}
}
public class DMDemo
{
public static void main(String[] args)
{
Car car = new Car();
car.start();
car.drive(20);
car.turnLeft();
car.drive(10);
car.turnRight();
car.drive(8);
car.stop();
}
}
@Override是一个注释(元数据),它告诉编译器确保超类实际上声明了一个注释方当情况不正确时,法律覆盖方法报告错误。
编译以上两个例子(javac DMDemo.java),然后操作应用程序(java DMDemo)。我们得到以下输出:
Starting car
Driving car 20 kilometers
Turning car left
Driving car 10 kilometers
Turning car right
Driving car 8 kilometers
Stopping car
添加到接口的方法会破坏二进制的兼容性,因此Drivable必须改变每个实现类别,同时实现demo()。为了避免这种情况加剧,可以将demo()添加到drivable作为默认方法,如下例所示。
使用默认方法声明Drivable接口:
public interface Drivable
{
public void drive(int numUnits);
public void start();
public void stop();
public void turnLeft();
public void turnRight();
public default void demo()
{
start();
drive(20);
turnLeft();
drive(10);
turnRight();
drive(8);
stop();
}
}
demo()作为默认实现的实例方法存在。由于Drivable不需要通过实现类实现,旧代码在使用此接口的二进制版本执行时不会中断。
Java 引入默认方法开发Java Collections Framework,因此,它可以在不破坏向后兼容性的情况下支持新的Streams API。新的default添加到接口中 Stream parallelStream()和default Stream stream()方法,java.util.Collection在Collections和Streams之间建立了桥梁。默认方法也可以用来更好地组织图书馆。比如现在default, void sort(Comparator c)Java已被添加.util.List,myListtt可以自然使用.sort(null);代替Collections代替collections.sort(myList);。
要掌握默认方法,首先要掌握一些使用技巧。必要时可覆盖默认方法。因为默认方法是隐藏的public,因此,在重写默认方法时,不要分配较弱的访问权限。否则,编译器就会出错。下一个例子显示了如何重写demo()。
class Car implements Drivable
{
@Override
public void demo()
{
start();
drive(20);
stop();
}
@Override
public void drive(int numUnits)
{
System.out.printf("Driving car %d kilometers%n", numUnits);
}
@Override
public void start()
{
System.out.println("Starting car");
}
@Override
public void stop()
{
System.out.println("Stopping car");
}
@Override
public void turnLeft()
{
System.out.println("Turning car left");
}
@Override
public void turnRight()
{
System.out.println("Turning car right");
}
}
其次,我们可以调用该方法的默认实现,由于不同接口中的默认实现存在冲突而被覆盖或不可用。因此,它可以在关键字的前面Super加上包含默认方法的界面名称,如下所示。
使用关键字访问默认方法 super:
interface A
{
default void method()
{
System.out.println("A.method() invoked");
}
}
public class DMDemo implements A
{
@Override
public void method()
{
System.out.println("DMDemo.method() invoked");
A.super.method();
}
public static void main(String[] args)
{
DMDemo dmdemo = new DMDemo();
dmdemo.method();
}
}
然后操作应用程序(java DMDemo),获取以下输出:
DMDemo.method() invoked
A.method() invoked
我们什么都做不了Public非final法作为Object界面的默认方法。
静态方法是一种与其定义的类相关的方法。每个对象共享其他静态方法。Java 也允许在接口中定义静态方法。Java标准类库的一个例子是Java.lang.invoke.Methodhandleinfostatic String referenceKindToString(int referenceKind)方法。
要了解基于界面的静态方法的有用性,首先要考虑的是drawable接口,draw()方法的int参数包含绘图颜色。将这种颜色表示为红色,绿色和蓝色的重量非常方便,因此添加了rgb()将这些重量转换为静态方法int。
使用静态方法声明Drawable接口:
public interface Drawable
{
public void draw(int color);
public static int rgb(int r, int g, int b)
{
return r << 16 | g << 8 | b;
}
}
然后创建一个包含一个应用程序的应用程序Circle类,通过基于整数的中心坐标和半径描述一个圆,实现Drawable绘制一个圆。同时,创建一个SMDemo类,这种Main()方法操作应用程序。
访问Drawable的静态方法:
class Circle implements Drawable
{
private int x, y, r;
Circle(int x, int y, int r)
{
this.x = x;
this.y = y;
this.r = r;
}
@Override
public void draw(int color)
{
System.out.printf("Drawing circle(%d, %d, %d) in color %x%n", x, y, r,
color);
}
}
public class SMDemo
{
public static void main(String[] args)
{
Circle circle = new Circle(10, 20, 5);
circle.draw(Drawable.rgb(0x80, 0x60, 0x40));
}
}
SMDemomain()方法实例化Circle,然后调用对象的draw()方法绘制,rgb()该静态方法的接口在调用该方法之前添加了前缀。接口实现类的前缀不能添加到该方法的前面(因为Circle.rgb(0x80, 0x60, 0x40),因为静态方法属于接口。
编译上述两个程序代码,然后运行应用程序(java SMDemo)。得到输出:
Drawing circle(10, 20, 5) in color 806040
Java 8引入了基于接口的静态方法,因为将实用程序方法与接口相关,而不是与实用程序相关通常非常方便。这可以使源代码更可读,并且不会破坏二进制的兼容性。
这篇文章只是抛砖引玉,想了解更多Java中默认和静态方法的实例和用法可以观看本站的最新用法java视频课程,名师讲解让你学习java快人一步!