抽象类和接口的区别详解

1 篇文章 0 订阅
1 篇文章 0 订阅

一、变量

        1. 接口只能是static final 修饰的静态常量。

public interface Animals {
    
    public static final int i=0;
    
   
}

        2. 抽象类可以有任何权限修饰符修饰的成员变量,也可以有静态成员变量或者静态常量。

public abstract class AbstractFish implements Animals{

    //静态变量
    static String name= "小张";
    //普通成员变量
    int age= 18 ;
    //静态常量
    public static final String sex = "男";
    //私有成员变量
    private String address = "二仙桥";
    //受保护的成员变量
    protected String nickName= "义薄云天张大仙";

}

———————————————————————————————————————————

二、构造方法

        1.接口没有构造方法

        

        2.抽象类可以有构造方法。

public abstract class AbstractFish implements Animals{

   
    String name;
    
    
    //无参构造
    public AbstractFish(){}

    //有参构造
    public AbstractFish(String name){
        this.name=name;
    }

}

        这里其实有一个可以注意的点,那就是抽象类不能被实例化,那么给抽象类写构造方法有什么用?

        首先构造器并不是用来实例化对象的,是用来为类中的变量赋值,进行初始化。类的实例化是在初始化完成之后。

        子类继承父类,当实例化子类时,会隐形先调用父类的构造方法,正如上文所讲,调用构造方法并不代表着父类也会实例化。

        所以,尽管抽象类不能被实例化,抽象类并不能调用自己的构造方法,但是我们可以通过构造函数链,在子类中通过super调用抽象类的构造方法,为抽象类的变量进行赋值初始化。

class GrassFish extends AbstractFish{
    
    
    public GrassFish(){
        
        //一般都会隐性调用super(),在这里我们可以显性调用抽象类的构造方法,为成员变量赋值
        super("花果山水帘洞美猴王齐天大圣孙悟空");
    }

    @Override
    public void isRiverFish() {

    }

    @Override
    public void swim() {

    }

    @Override
    public void run() {

    }
}

———————————————————————————————————————————

        

三、普通方法

        1. 接口中只能有抽象方法。

 public interface Animals {

    public abstract void eat();

    public abstract void swim();

    public abstract void run();
}

       

         2. 抽象类中可以有自己定义的实现了的普通方法,也可以有没实现的抽象方法或者静态方法。

public abstract class AbstractFish implements Animals{

   

    //抽象类自己定义的未实现的抽象方法
    public abstract void isRiverFish();

    //抽象类自己定义的实现了的普通静态方法
    private static void isFood(){
        System.out.println("我是可以吃的那类鱼!");
    }

    //实现了Animals接口部分方法,并没有实现所有方法,抽象类可以只实现接口的部分方法
    @Override
    public void eat() {
        System.out.println("哈哈哈");
    }


}

        

注意:

     之前看集合容器的源代码时,我发现了Collection接口下,有一个实现了Collection接口的AbstractCollection抽象类,该类只实现了Collection接口的部分方法。然后底层又有一个AbstractList抽象类继承了AbstractCollection类,最终ArrayList继承了AbstractList抽象类。

     但是同时,又有一个List接口继承了Collection接口,AbstractList抽象类不仅继承了AbstractCollection抽象类,同时也实现了List接口,然后ArrayList也是如此。

      我的疑问就是为什么不直接用Collection接口下来的List接口就完了,还要弄一个抽象类旁支出来给实现类继承。

        解释是,AbstractCollection抽象类实现Collection接口部分方法,这一部分方法是所有Collection接口下具体实现类都可以通用的方法,如果不这样做,那么就会频繁重写方法,效率低。然后AbstractList抽象类又继承AbstractCollection,进一步实现List下可以通用的方法。

        至于最终AbstractList已经实现了List接口,ArrayList为什么还要再一次实现List接口,这和序列化相关,如果这里不实现的话,序列化不会通过。

———————————————————————————————————————————

关于访问权限

       抽象类理论上来说可以使用任何访问权限符,但是使用private的话没有意义,因为抽象类本来就是要拿给子类进行继承,设置私有化,那子类也访问不了,没有任何的意义。

补充 JDK8之后,允许接口使用default和static关键字。JDK9接口允许使用private static方法。

        

                                

       

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值