首页 > 图灵资讯 > 技术篇>正文

透过实例看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快人一步!

上一篇 最全的spring session面试题(附答案)
下一篇 新一代公链RCP

文章素材均来源于网络,如有侵权,请联系管理员删除。