43_聊聊Java8接口中的default方法和static方法

59 篇文章 2 订阅
22 篇文章 1 订阅

JDK1.8之前的接口回顾

在jdk1.8之前,我们对接口的认知是这样的:

1、方法:只能包含public和abstract的方法,即使定义为:

interface Shape {
   //获取几何图形的面积
   Double getArea(double length, double width);
}

方法前面也默认加了public abstract修饰

2、字段:只能包含常量,即public static final 修饰的变量

interface Shape {
   int length = 0;
}

即使这样写,也是默认加上了public static final修饰。

遇到的问题

现在我们有很多类实现了该接口,有三角形trangle,有圆形circle······

class Trangle implements Shape {

@Override
public Double getArea(double length, double width) {
    return length * width / 2;
}

}

class Circle implements Shape {

@Override
public Double getArea(double length, double width) {
    //调用方法时默认length传半径
    return 3.14 * length * length;
}

}

有一天,我们发现接口功能不够用了,需要增加一个计算周长的方法。

这时候,JDK1.7及其之前版本该怎么办呢?

  • 管他三七二十一,往接口里直接加个方法,强迫所有实现该几何图形的接口的实现类(正方形、圆形、三角形······)都实现最新的接口方法

  • 把接口代码移到抽象类,添加一个有默认实现的计算周长的方法,但是所有实现类都要改为继承,遇到实现类继承别的父类就行不通了(java只有单继承)

  • 添加一个新接口,新接口里加上一个计算周长的方法,让所有实现了Shape接口的类再实现新的接口,看起来很美好,接口本身也是这么使用的,但是如果这个方法让所有的实现类再实现一遍,还是挺麻烦的。

新的选择——默认方法

JDK1.8针对这种接口不易扩展的现象,在接口新增default方法,可以有效解决上述遇到的接口拓展新方法的问题。原先的实现类不用改任何代码就拥有了新的能力,有点像从接口继承了一个有实现的方法,可以直接调用。

具体实现:

package com.changan.eurekademo.onepointeight;


public class DefaultMethodTest {
    public static void main(String[] args) {
        System.out.println(new Circle().getPerimeterOfCircle(3));
    }
}

interface Shape {
    int a = 0;

	public Double getArea(double length, double width);

    /**
     * 新增默认方法,为四边形扩展计算周长
     *
     * @param length 长
     * @param width  款
     * @return java.lang.Double
     */
     default Double getPerimeterOfQuadrilateral(double length, double width) {
        return (length + width) * 2;
     }

    /**

     * 新增默认方法,为圆形计算周长
     *
     * @param redius 半径
     * @return java.lang.Double
     */
   default Double getPerimeterOfCircle(double redius) {
   	  return 3.14 * 2 * redius;
   }

}


class Trangle implements Shape {

    @Override
    public Double getArea(double length, double width) {
        return length * width / 2;
    }
}


class Circle implements Shape {

    @Override
    public Double getArea(double length, double width) {
        //调用方法时默认length传半径
        return 3.14 * length * length;
    }
}

可以看到输出结果是:

在这里插入图片描述

静态方法

​ 静态方法比较直观,类比普通类的静态方法,就是可以不实例化,直接用类名调用的方法,接口的静态方法也是一样,直接用接口名调用方法。

public class DefaultMethodTest {
    public static void main(String[] args) {
        System.out.println(new Circle().getPerimeterOfCircle(3));
        System.out.println("-------------------------------------------");
        System.out.println(Shape.describe());
    }
}

interface Shape {
    int a = 0;

	public Double getArea(double length, double width);

    /**

     * 新增默认方法,为四边形扩展计算周长
     *
     * @param length 长
     * @param width  款
     * @return java.lang.Double
     */
   default Double getPerimeterOfQuadrilateral(double length, double width) {
   		return (length + width) * 2;
   }

/**

 * 新增默认方法,为圆形计算周长
 *
 * @param redius 半径
 * @return java.lang.Double
 */
   default Double getPerimeterOfCircle(double redius) {
   		return 3.14 * 2 * redius;
   }

/**

 * 接口描述方法,描述接口用途及其他信息
 *
 * @return java.lang.String
 */
   static String describe() {
   		return "我是一个几何图形接口";
   }

}

class Trangle implements Shape {

    @Override
    public Double getArea(double length, double width) {
        return length * width / 2;
    }

}

class Circle implements Shape {

    @Override
    public Double getArea(double length, double width) {
        //调用方法时默认length传半径
        return 3.14 * length * length;
    }
}

可以惊奇地看到,用接口直接调了一个方法,这个现象可以类比匿名类。

比如JDK1.7,我们要实现一个接口有一个方法,并且不用实例化的类来调用应该这么做:

public class DefaultMethodTest {
    public static void main(String[] args) {
        System.out.println(new Shape() {
            @Override
            public Double getArea(double length, double width) {
                return null;
            }

            @Override
            public String describe() {
                return "我是一个几何图形接口";
            }
       }.describe());
    }
}

interface Shape {
    int a = 0;

    Double getArea(double length, double width);

    String describe();

}

在这里插入图片描述

但是这样做完全没有太大的意义,没有接口中定义静态方法来的优雅、简单。

抽象类VS接口静态/默认方法

​ 带默认或者静态方法的接口像是一个抽象类吗?的确有点像,但是抽象类可能包含可变状态(实例变量),而接口只能定义行为和常量。另外,一个类只能直接从一个类继承,但可以实现所需的任意数量的接口。所以,如果需要可变状态,并且确定某个类将构成一个合理的子类,则需要考虑一个抽象类。在其他情况下,使用具有默认/静态方法的接口就好了。

原文链接:https://blog.csdn.net/zab635590867/article/details/101108028

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java接口defaultstatic是两种不同类型的方法。 首先,default方法是在Java 8引入的新特性。它允许在接口定义具体的方法实现。在接口定义default方法可以为接口添加新的方法,而不会破坏已有的实现类。实现类可以选择性地覆盖接口default方法,也可以直接使用默认的实现。这为接口的演化提供了更大的灵活性,而不会导致实现类的重写。 举个例子,假设我们有一个名为Shape的接口,其定义了一个默认方法area(),用于计算形状的面积。现在,任何实现Shape接口的类可以选择是否重写area方法,如果没有重写,则默认使用接口提供的默认实现。 其次,static方法也可以在接口定义。与默认方法不同,静态方法是具有固定的实现,在接口定义无需实例化即可直接调用。静态方法通常用于提供与接口相关的实用方法,这些方法可以在不创建接口实例的情况下使用。 静态方法可以通过接口名调用,而无需创建接口的实例。这使得静态方法能够提供一些通用的工具方法,例如在接口定义一个静态方法来检查两个对象是否相等,而不需要实例化接口。 综上所述,default方法static方法都是Java接口的扩展特性,使得接口更加灵活和易用。default方法提供了接口内部的默认实现,可以为已有的实现类添加方法而不影响其实现。而static方法则提供了一种在接口定义与接口相关的实用方法的方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值