Java中抽象类与接口的区别

作者: Arvin Chen 分类: Java 来源: Break易站(www.breakyizhan.com)
  •   Java 面向对象/Java 接口

    抽象: 隐藏功能的内部实现并仅向用户显示功能。即它做什么(显示),它怎么做(隐藏)。抽象类和接口都用于抽象。

    抽象类与接口

    1.语法层面上的区别

    1)抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;

    2)抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;

    3)接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;

    4)一个类只能继承一个抽象类,而一个类却可以实现多个接口。

    2.设计层面上的区别

    1)抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。举个简单的例子,飞机和鸟是不同类的事物,但是它们都有一个共性,就是都会飞。那么在设计的时候,可以将飞机设计为一个类Airplane,将鸟设计为一个类Bird,但是不能将 飞行 这个特性也设计为类,因此它只是一个行为特性,并不是对一类事物的抽象描述。此时可以将 飞行 设计为一个接口Fly,包含方法fly( ),然后Airplane和Bird分别根据自己的需要实现Fly这个接口。然后至于有不同种类的飞机,比如战斗机、民用飞机等直接继承Airplane即可,对于鸟也是类似的,不同种类的鸟直接继承Bird类即可。从这里可以看出,继承是一个 "是不是"的关系,而 接口 实现则是 "有没有"的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现则是有没有、具备不具备的关系,比如鸟是否能飞(或者是否具备飞行这个特点),能飞行则可以实现这个接口,不能飞行就不实现这个接口。

    2)设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。什么是模板式设计?最简单例子,大家都用过ppt里面的模板,如果用模板A设计了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,如果它们的公共部分需要改动,则只需要改动模板A就可以了,不需要重新对ppt B和ppt C进行改动。而辐射式设计,比如某个电梯都装了某种报警器,一旦要更新报警器,就必须全部更新。也就是说对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;而对于接口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动。

    再对比一下抽象类和方法:

    方法类型:接口只能有抽象方法。抽象类可以有抽象和非抽象的方法。从Java 8开始,它也可以有默认和静态方法。
    最终变量:在Java接口中声明的变量默认为final。抽象类可能包含非最终变量。
    变量类型:抽象类可以有最终的,非最终的,静态的和非静态的变量。接口只有静态和最终变量。
    实现:抽象类可以提供接口的实现。接口不能提供抽象类的实现。
    继承与抽象: Java接口可以使用关键字“implements”来实现,抽象类可以使用关键字“extends”来扩展。
    多重实现:一个接口只能扩展另一个Java接口,一个抽象类可以扩展另一个Java类并实现多个Java接口。
    数据成员的可访问性:默认情况下,Java接口的成员是公共的。一个Java抽象类可以拥有像private,protected等类的成员。

    // Java program to illustrate the
    // concept of abstract class
     
    import java.io.*;
     
    // abstract class
    abstract class Shape 
    {
        // declare fields
        String objectName = " ";
         
        Shape(String name)
        {
            this.objectName = name;
        }
         
        // declare non-abstract methods
        // it has default implementation
        public void moveTo(int x, int y)
        {
            System.out.println(this.objectName + " " + "has been moved to"
                                       + " x = " + x + " and y = " + y);
        }
         
        // abstract methods which will be
        // implemented by its subclass(es)
        abstract public double area();
        abstract public void draw();
    }
     
    class Rectangle extends Shape 
    {
         
        int length, width;
         
        // constructor
        Rectangle(int length, int width, String name)
        {
             
            super(name);
            this.length = length;
            this.width = width;
        }
         
        @Override
        public void draw() 
        {
            System.out.println("Rectangle has been drawn "); 
        }
         
        @Override
        public double area() 
        {
            return (double)(length*width);
        }
    } 
     
    class Circle extends Shape
    {
         
        double pi = 3.14;
        int radius;
         
        //constructor
        Circle(int radius, String name)
        {
             
            super(name);
            this.radius = radius;
        }
         
        @Override
        public void draw()
        {
             
            System.out.println("Circle has been drawn "); 
        }
         
        @Override
        public double area() 
        {
            return (double)((pi*radius*radius)/2);
        }
    }
     
    class GFG
    {
        public static void main (String[] args) 
        {
         
            // creating the Object of Rectangle class
            // and using shape class reference.
            Shape rect = new Rectangle(2,3, "Rectangle");
            System.out.println("Area of rectangle: " + rect.area());
            rect.moveTo(1,2);
             
            System.out.println(" ");
             
            // creating the Objects of circle class
            Shape circle = new Circle(2, "Cicle");
            System.out.println("Area of circle: " + circle.area());
            circle.moveTo(2,4);
         
        }
    }

    输出

    Area of rectangle: 6.0
    Rectangle has been moved to x = 1 and y = 2
     
    Area of circle: 6.28
    Cicle has been moved to x = 2 and y = 4
    在rectangle和circle之间没有任何通用代码,然后使用接口interface。
    看到这个......
    // Java program to illustrate the
    // concept of interface 
    import java.io.*;
     
    interface Shape
    {
        // abstract method
        void draw();
        double area();
    }
     
    class Rectangle implements Shape 
    {
        int length, width;
         
        // constructor
        Rectangle(int length, int width)
        {
            this.length = length;
            this.width = width;
        }
         
        @Override
        public void draw() 
        {
            System.out.println("Rectangle has been drawn "); 
        }
         
        @Override
        public double area() 
        {
            return (double)(length*width);
        }
    } 
     
    class Circle implements Shape 
    {
         
        double pi = 3.14;
        int radius;
         
        //constructor
        Circle(int radius)
        {
             
            this.radius = radius;
        }
         
        @Override
        public void draw() 
        {
            System.out.println("Circle has been drawn "); 
        }
         
        @Override
        public double area() 
        {
             
            return (double)((pi*radius*radius)/2);
        }
         
    }
     
    class GFG 
    {
        public static void main (String[] args) 
        {
         
            // creating the Object of Rectangle class
            // and using shape interface reference.
            Shape rect = new Rectangle(2,3);
            System.out.println("Area of rectangle: " + rect.area());
     
            // creating the Objects of circle class
            Shape circle = new Circle(2);
            System.out.println("Area of circle: " + circle.area());
        }
    }

    输出

    Area of rectangle: 6.0
    Area of circle: 6.28

    何时使用什么抽象类,接口?

    如果以下任何一种语句适用于您的情况,请考虑使用抽象类:

    • 在java应用程序中,有一些相关的类需要共享一些代码行,然后你可以把这些代码行放在抽象类中,这个抽象类应该被所有这些相关的类扩展。
    • 您可以在抽象类中定义非静态或非最终字段,以便通过一种方法可以访问和修改它们所属的对象的状态。
    • 您可以期望扩展抽象类的类具有许多常用的方法或字段,或者需要除公共之外的访问修饰符(例如protected和private)。

    如果以下任何一种语句适用于您的情况,请考虑使用接口:

    • 它是完全抽象的,接口中声明的所有方法必须由实现此接口的类实现。
    • 一个类可以实现多个接口。它被称为多重继承。
    • 您想要指定特定数据类型的行为,但不关心谁实现其行为。
  •   Java 面向对象/Java 接口
  •   本文标题:Java中抽象类与接口的区别 - Break易站
    转载请保留页面地址:https://www.breakyizhan.com/java/3754.html
      微信返利机器人
      免费:淘宝,京东,拼多多优惠券
      腾讯,爱奇艺,优酷的VIP视频免费解析,免费看
      即刻扫描二维码,添加微信机器人!

    发表笔记

    电子邮件地址不会被公开。 必填项已用*标注