Java抽象类、接口用法总结

作者: iDaniel | 来源:发表于2017-03-05 23:20 被阅读184次

    Java的接口和抽象类都可以定义不提供具体实现的方法,功能上很相似,对多态都提供了很好的支持。下面我们就来好好认识认识这两个知识点。

    ps:因为都是一些基本概念性的东西,所以我就不写代码举例了。

    抽象类(Abstract Class)

    1. 什么是抽象类,它的作用是什么呢?

    先说下抽象类长啥样,Java里面定义抽象类很简单,用abstract修饰的类就是抽象类。抽象类是实现多态的一种机制。

    抽象类是不能实例化的,抽象类代表那一类的事物,不能实例化为具体的对象。很多人都会问为什么不能实例化?因为语法上就是这么规定的,你new一个就会报错。所以,抽象类主要是起到规范的作用,它只是声明了成员变量和方法,是要子类去实现他的所有的抽象方法的。

    2. 使用抽象类,需要注意什么?
    ① 抽象类是不能实例化的(上面已经讲过)。
    ② 要求非抽象子类必须实现基类中的抽象方法。
    ③ 只要类中存在抽象方法,要求该类必须是抽象类。
    ④ 抽象类内可以全都是抽象方法,也可以没有抽象方法。
    ⑤ 基类内不能写静态的抽象方法,因为不能被重写。

    3. 一个小例子

    举个常用的抽象类“人”,两个子类“男人”、“女人”。“人”有个可继承普通方法【走路】,有个抽象方法【撒尿】。“男人”和“女人”【撒尿】方式是不一样的,声明为抽象方法最好。而【走路】都是一样的,可以在父类实现好,子类继承就可以了。

    这就是抽象类的好处,把子类的共性逻辑上提抽象出来,共有的可以继承,有区别的在子类中自己去实现。这就提高了程序的扩展、移植、复用。

    接口(Interface)

    1. 什么是接口,有什么用呢?

    接口是抽像类的变体。定义一个接口使用interface关键字,实现一个接口使用implements关键字,接口它起到规范的作用,降低了各模块的耦合性,提高了扩展性。

    2. 使用接口,需要注意些什么,它有什么特点?

    ① 在接口中,所有方法都是抽象的(跟抽象类不同),没有方法体。
    ② 接口只可以定义static final成员变量(跟抽象类不同)。
    ③ 接口可以继承接口,切可以多继承,可用逗号隔开。
    ④ 接口里的常量public static final 都可以不写,方法中的public abstract 也可以不写,编译器默认会帮我们添加。但是推荐写上,写上增加代码的可读性。
    ⑤ 假如两个接口中有一样的抽象方法,但是它没有实现部分,所以也就没有菱形缺陷,相当于对多继承的优化方案。
    ⑥ 抽象类实现某个接口,可以不实现所有接口的方法,可以由它的子类实现。而普通类即非抽象类则必须实现接口里的全部方法。

    关于第五点,感觉还是写下例子比较好。

    public interface InterfaceA {
    
        public static final double PI = 3.14;
    
        public abstract void foo();
        public abstract void foo1();
        public abstract void foo2();
    
        public abstract void fooA();// A里面有B的抽象方法
    
    }
    
    public interface InterfaceB {
    
        public abstract void fooA();
        public abstract void fooB();
        public abstract void fooC();
    }
    
    //接口多继承
    public interface InterfaceC extends InterfaceA, InterfaceB{
    
        public abstract void foo3();
    }
    
    public class Demo implements InterfaceA, InterfaceB{
    // 可以看到虽然两个接口都有public abstract void fooA()这个方法,但是在实现里,只重写一次。
        @Override
        public void foo() {
            System.out.println(InterfaceA.PI);
        }
        @Override
        public void foo1() {
        }
        @Override
        public void foo2() {
        }
    
        @Override
        public void fooA() {
    
        }
    
        @Override
        public void fooB() {
    
        }
    
        @Override
        public void fooC() {
    
        }
    }
    
    public class Demo1 implements InterfaceA, InterfaceC{
    
    // 这个也是同理。
        @Override
        public void foo3() {
    
        }
    
        @Override
        public void foo() {
    
        }
    
        @Override
        public void foo1() {
    
        }
    
        @Override
        public void foo2() {
    
        }
    
        @Override
        public void fooA() {
    
        }
    
        @Override
        public void fooB() {
    
        }
    
        @Override
        public void fooC() {
    
        }
    }
    

    Java 8 新特性:接口默认方法

    接口的一个缺陷就是,当我们修改接口的时候,需要修改全部实现该接口的实现类。对于已发布的版本,是没法在给接口添加新的方法的同时不影响已有的实现。所以在Java 8引进了默认的方法,就解决了接口的修改与已有的实现不兼容的问题。

    默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法,前面需要加default 关键词来修饰。还可以有静态方法,示例如下。

        public interface InterFaceD {
            default void foo(){
                System.out.println("默认方法可以有多个。");
            }
            // 静态方法
           static void fooA(){
                System.out.println("这是接口里面的一个静态方法");
            }
        }
    

    抽象类与接口的区别

    1. 语法用法上的区别。
      在抽象类中,抽象类可以拥有更丰富类型成员变量,同时也可以拥有自己的非抽象方法。但是在接口中,它仅能够有静态、不能修改的成员数据(即final static,但是我们一般是不会在接口中使用成员数据),同时它所有的方法都必须是抽象的。在某种程度上来说,接口是抽象类的特殊化。

    2. 抽象层次上的区别。
      抽象类是内容,是对一种事物的抽象,是整体上的抽象。比如,老师是所有教师的抽象,老师的工作是教育学生。
      接口是特征,是对一种行为的抽象,是局部抽象,比如,上课、批改作业、家访。

    3. 抽象概念上的区别。
      抽象类所体现的是一种合理的继承关系,即父类和子类在概念本质上应该是相同的。对于接口则不然,并不要求接口的实现者和接口定义在概念本质上是一致的, 仅仅是实现了接口定义的契约而已。

    抽象类和接口是java语言中两种不同的抽象概念,他们的存在对多态提供了非常好的支持,虽然他们之间存在很大的相似性。但是对于他们的选择往往反应了我们对问题的理解程度。

    Java8关于接口的另一个新特性就是函数式接口,后面会结合Lambda表达式,作进一步的介绍。

    写完喽!ㄟ(▔,▔)ㄏㄟ(▔,▔)ㄏㄟ(▔,▔)ㄏ


    知识重在总结和梳理,只有不断地去学习并运用,才能化为自己的东西。当你能为别人讲明白的时候,说明自己已经掌握了。

    欢迎转载,转载请注明出处!

    如果有错误的地方,或者有您的见解,还请不啬赐教!

    喜欢的话,麻烦点个赞!

    相关文章

      网友评论

      • 29fd967c86a5:那个撒尿的例子厉害了。
        iDaniel:这个是个比较经典的例子,我不是原创:sweat_smile:

      本文标题:Java抽象类、接口用法总结

      本文链接:https://www.haomeiwen.com/subject/kxkegttx.html