zoukankan      html  css  js  c++  java
  • Java中抽象类和接口的区别

            在看Java基础的时候,经常会遇到关于接口和抽象类的相关描述与问题,然后我在百度上搜了很多相关答案,都很凌乱,都直接介绍2者的区别,没有介绍2着的原因,且很多资料一模一样;如果长时间没有接触基础知识,看起来很难理解;今天兴起,写写两者的区别吧

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    1.抽象类

    1.1.抽象类的产生

           当编写一个类时,我们往往会为该类定义一些方法,这些方法是用来描述该类的行为方式,那么这些方法都有具体的方法体。但是有的时候,某个父类只是知道子类应该包含怎么样的方法,但是无法准确知道子类如何实现这些方法。比如一个图形类应该有一个求周长的方法,但是不同的图形求周长的算法不一样。那该怎么办呢?

          分析事物时,发现了共性内容,就出现向上抽取。会有这样一种特殊情况,就是功能声明相同,但功能主体不同。那么这时也可以抽取,但只抽取方法声明,不抽取方法主体。那么此方法就是一个抽象方法。

          描述狗:行为:吼叫。

          描述狼:行为:吼叫。

          狗和狼之间有共性,可以进行向上抽取。抽取它们的所属共性类型:犬科。由于狗和狼都具有吼叫功能,但是他们具体怎么吼叫却不一样。这时在描述犬科时,发现了有些功能(吼叫)不具体,这些不具体的功能,需要在类中标识出来,通过java中的关键字abstract(抽象)。

          当定义了抽象函数的类也必须被abstract关键字修饰,被abstract关键字修饰的类是抽象类。

     1 abstract class 犬科 
     2 {
     3     abstract void 吼叫();//抽象函数。需要abstract修饰,并分号;结束
     4 }
     5 class Dog extends 犬科
     6 {
     7     void 吼叫()
     8     {
     9         System.out.println("汪汪汪汪");
    10     }
    11 }
    12 class Wolf extends 犬科
    13 {
    14     void 吼叫()
    15     {
    16         System.out.println("嗷嗷嗷嗷");
    17     }
    18 }

    1.2.抽象类的特点

      1、抽象类和抽象方法都需要被abstract修饰。抽象方法一定要定义在抽象类中。

      2、抽象类不可以创建实例,原因:调用抽象方法没有意义。

      3、只有覆盖了抽象类中所有的抽象方法后,其子类才可以实例化。否则该子类还是一个抽象类。

      之所以继承,更多的是在思想,是面对共性类型操作会更简单。

    1.3.抽象类的细节问题

      1、抽象类一定是个父类? 

                    是的,因为不断抽取而来的。

      2、抽象类是否有构造函数?

                    有,虽然不能给自己的对象初始化,但是可以给自己的子类对象初始化。

                    抽象类和一般类的异同点:

                    相同:

                            1、它们都是用来描述事物的。

                            2、它们之中都可以定义属性和行为。

                    不同:

                            1、一般类可以具体的描述事物。抽象类描述事物的信息不具体

                            2、抽象类中可以多定义一个成员:抽象函数。

                            3、一般类可以创建对象,而抽象类不能创建对象。

      3、抽象类中是否可以不定义抽象方法。

      是可以的,那这个抽象类的存在到底有什么意义呢?仅仅是不让该类创建对象。

      4、抽象关键字abstract不可以和哪些关键字共存?      

    • final:fianl修饰的类是无法被继承的,而abstract修饰的类一定要有子类。    final修饰的方法无法被覆盖,但是abstract修饰的方法必须要被子类去实现的。
    • static:静态修饰的方法属于类的,它存在与静态区中,和对象就没关系了。而抽象方法没有方法体,使用类名调用它没有任何意义。
    • private:私有的方法子类是无法继承到的,也不存在覆盖,而abstract和private一起使用修饰方法,abstract既要子类去实现这个方法,而private修饰子类根本无法得到父类这个方法。互相矛盾。

    2.接口

    2.1.接口的定义与实现

      当一个抽象类中的所有方法都是抽象方法时,那么这个抽象类就可以使用另外一种接口这种机制来体现。

      接口怎么定义呢?定义普通的类或者抽象类可以使用class关键字,定义接口必须interface关键字完成。

    interface class Demo
    {
        abstract void show1();
        abstract void show2();
    }

      接口中成员的特点:

      1、接口中可以定义变量,但是变量必须有固定的修饰符修饰,public static final 所以接口中的变量也称之为常量。

      2、接口中可以定义方法,方法也有固定的修饰符,public abstract

      3、接口中的成员都是公共的。

      4、接口不可以创建对象。

      5、子类必须覆盖掉接口中所有的抽象方法后,子类才可以实例化。否则子类是一个抽象类。

    interface Demo//定义一个名称为Demo的接口。
    {
        public static final int NUM = 3;
        public abstract void show1();
        public abstract void show2();
    }
    //定义子类去覆盖接口中的方法。子类必须和接口产生关系,类与类的关系是继承,类与接口之间的关系是 实现。通过 关键字 implements
    class DemoImpl implements Demo//子类实现Demo接口。
    {
        //重写接口中的方法。
        public void show1(){}
        public void show2(){}
    }

    2.2.接口的多实现

      了解了接口的特点后,那么想想为什么要定义接口,使用抽象类描述也没有问题,接口到底有啥用呢?

      接口最重要的体现:解决多继承的弊端。将多继承这种机制在java中通过多实现完成了。

    interface A
    {
        void show1();
    }
    interface B
    {
        void show2();
    }
    class C implements A,B// 多实现。同时实现多个接口。
    {
        public void show1(){}
        public void show2(){}
    }

      怎么解决多继承的弊端呢?()

      弊端:多继承时,当多个父类中有相同功能时,子类调用会产生不确定性。

      其实核心原因就是在于多继承父类中功能有主体,而导致调用运行时,不确定运行哪个主体内容。

      为什么多实现就解决了呢?

      因为接口中的功能都没有方法体,由子类来明确。

    2.3.类继承类同时实现接口

      接口和类之间可以通过实现产生关系,同时也学习了类与类之间可以通过继承产生关系。当在描述事物时,如果这个事物已经是整个事物体系中的一种,它又需要扩展额外的功能,这时接口就派上用场了。

      子类通过继承父类扩展功能,通过继承扩展的功能都是子类应该具备的基础功能。如果子类想要继续扩展其他类中的功能呢?这时通过实现接口来完成。

    class Fu
    {
        public void show(){}
    }
    interface Inter
    {
        pulbic void show1();
    }
    class Zi extends Fu implements Inter
    {
        public void show1()
        {
            
        }
    }

      接口的出现避免了单继承的局限性。父类中定义的事物的基本功能。接口中定义的事物的扩展功能。

    2.4.接口的多继承

      学习类的时候,知道类与类之间可以通过继承产生关系,接口和类之间可以通过实现产生关系,那么接口与接口之间会有什么关系。

      多个接口之间可以使用extends进行继承。

    interface A{
        void show();
    }
    interface B{
        void show1();
    }
    interface C{
        void show2();
    }
    
    interface D extends A,B,C{
        void show3();
    }

      在开发中如果多个接口中存在相同方法,这时若有个类实现了这些接口,那么就要实现接口中的方法,由于接口中的方法是抽象方法,子类实现后也不会发生调用的不确定性。

    2.5.接口的思想

      举例:我们都知道电脑上留有很多个插口,而这些插口可以插入相应的设备,这些设备为什么能插在上面呢?主要原因是这些设备在生产的时候符合了这个插口的使用规则,否则将无法插入接口中,更无法使用。发现这个插口的出现让我们使用更多的设备。

      总结:接口在开发中的它好处

      1、接口的出现扩展了功能。

      2、接口其实就是暴漏出来的规则。

      3、接口的出现降低了耦合性,即设备与设备之间实现了解耦。

      接口的出现方便后期使用和维护,一方是在使用接口(如电脑),一方在实现接口(插在插口上的设备)。例如:笔记本使用这个规则(接口),电脑外围设备实现这个规则(接口)。

    3.接口和抽象类的区别

      明白了接口思想和接口的用法后,接口和抽象类的区别是什么呢?接口在生活体现也基本掌握,那在程序中接口是如何体现的呢?

      通过实例进行分析和代码演示抽象类和接口的用法。

      1、举例:

      犬:

        行为:

          吼叫;

          吃饭;

      缉毒犬:

        行为:

          吼叫;

          吃饭;

          缉毒;

      2、思考:

      由于犬分为很多种类,他们吼叫和吃饭的方式不一样,在描述的时候不能具体化,也就是吼叫和吃饭的行为不能明确,描述行为时,行为的具体动作不能明确,可以将这个行为写为抽象行为,那么这个类也就是抽象类。可是当犬有其他额外功能时,而这个功能并不在这个事物的体系中。这时可以让犬具备犬科自身特点的同时也有其他额外功能,可以将这个额外功能定义接口中。

    interface 缉毒{
        void 缉毒();
    }
    //定义犬科的这个提取的共性功能
    abstract class 犬科{
        abstract void 吃饭();
        abstract void 吼叫();
    }
    // 缉毒犬属于犬科一种,让其继承犬科,获取的犬科的特性,
    //由于缉毒犬具有缉毒功能,那么它只要实现缉毒接口即可,这样即保证缉毒犬具备犬科的特性,也拥有了缉毒的功能
    class 缉毒犬 extends 犬科 implements 缉毒{
    
        public void 缉毒() {
        }
    
        void 吃饭() {
            
        }
    
        void 吼叫() {
        }
        
    }
    class 缉毒猪 implements 缉毒{
        public void 缉毒() {
        }
    }

    3、通过上面的例子总结接口和抽象类的区别:★★★★★

      相同点:

        都位于继承的顶端,用于被其他实现或继承;

        都不能实例化;

        都包含抽象方法,其子类都必须覆写这些抽象方法;

      区别:

        抽象类为部分方法提供实现,避免子类重复实现这些方法,提供代码重用性;接口只能包含抽象方法;

        一个类只能继承一个直接父类(可能是抽象类),却可以实现多个接口;(接口弥补了Java的单继承)

      二者的选用:

        优先选用接口,尽量少用抽象类;

        既要定义子类的行为,又要为子类提供共性功能时才选用抽象类;

  • 相关阅读:
    VS远程调试亲历
    IIS7.5 配置虚拟目录的经历
    IE 兼容一问题一小记
    寻找 IBatisNet 批量插入(批量复制) 的心路历程
    Linq 多连接及 left join 实例 记录
    easyui treegrid idField 所在属性中值有花括号(如Guid)当有鼠标事件时会报错,行记录一下
    HDU1754
    HDU1166
    线段树模板
    HDU1599(Floyd最小环)
  • 原文地址:https://www.cnblogs.com/dz-boss/p/8427347.html
Copyright © 2011-2022 走看看