一文彻底搞懂抽象类和接口!

简介: 一文彻底搞懂抽象类和接口!

1.写在前面的话


      最近一些刚入门JAVA的读者朋友让我来写一篇有关于抽象类和接口的文章,我当即就答应了,因为抽象类和接口确实是两个很重要但是一时半会又无法完全理解的东西,这篇文章我主要先介绍抽象类、抽象方法、接口以及它两者的应用。所以废话不多说!Let's go !


2. 抽象类和抽象方法


      抽象类,它是普通类和接口之间的一种中庸之道。可能大家看了这句话也有点懵,其实简单点说就是抽象类既有普通类的特征又有接口的特征

   

  我首先给大家上一段代码,然后咱们来细细地谈一谈:


Animal.java


public abstract class Animal {    public abstract void say();    public abstract void eat();}


Dog.java



public class Dog extends Animal{
  @Override  public void say() {     System.out.println("汪汪汪!");  }
  @Override  public void eat() {    System.out.println("骨头真好吃!");  }    }


Cat.java


public class Cat extends Animal{
  @Override  public void say() {        System.out.println("喵喵喵!");  }
  @Override  public void eat() {    System.out.println("鱼真好吃!");  }}

 

  上面就是一个很简单的抽象类的实例了,抽象类Animal,我们可以看到它里面的内容,第一感觉是---这有啥用?感觉并没有什么用。那么为什么JAVA要引用抽象类这个概念呢?其实我们观察下面两块代码,这两个类都继承自Animal抽象类,并且我们都去重写了抽象类里面的方法,这个时候我们也许知道它的一丝用意,其实简单粗俗一点讲就是提供给了我们一个模板,我们直接按照那个模板来做就行了,官方一点讲呢,就是不同的子类可以用不同方式表示这个接口,这个就是所谓的抽象类。


      我们来思考一下,如果我们只有Animal这一个抽象类那可咋办(没有子类),还能咋办,就是这个类的对象没有什么意义了,我们也无需去管它了,因为没有人想去用它的模板。


      抽象类也被大家称作不能被初始化的类,编译器是不会允许你有这种操作的,也就是说你创建了抽象类,你就只能通过子类去继承它的这种方式来利用这个抽象类,而不能是我们通常的new初始化。总的来说抽象类除了被继承过之外,是没有用途、没有值、没有目的的。



public abstract class Animal {    public abstract void say();    public abstract void eat();}

     

 我把上面的代码搬了下来,目的是为了介绍一下抽象方法,简单点说,抽象方法仅仅只有声明而没有方法体。包含有抽象方法的类一定是抽象类。当我们的子类继承了抽象类之后,编译器会强制我们实现所有抽象类中的抽象方法的方法体。


3. 接口这个东东


      interface这个关键字让抽象类的概念更向前迈进了一步,粗俗的讲接口就是比抽象类还要抽象的东西。interface这个关键字产生的是一个完全抽象的类,它根本就没有提供任何的具体实现。它允许创建者去确定它的方法名、参数列表、返回类型,但是没有任何的方法体。接口它仅仅只是提供一个形式,而未提供任何具体实现。

 

     当我们去使用接口时,我们会发现实现该接口的类看起来都是一个样,所以接口可以当做类和类之间的一个协议。创建一个接口只需要把class关键字换成interface关键字就行了。实现接口就通过implements关键字。


      咱们还是来看看代码:


AnimalImpl.java:


public interface AnimalImpl {     void say();     void eat();}


CatImpl.java:



public class CatImpl implements AnimalImpl{
  @Override  public void say() {        System.out.println("喵喵喵!");  }
  @Override  public void eat() {    System.out.println("鱼真好吃!");  }}


DogImpl.java:



public class DogImpl implements AnimalImpl{
  @Override  public void say() {       System.out.println("汪汪汪!");  }
  @Override  public void eat() {    System.out.println("骨头真好吃!");  }}


     看起来这个和上面的抽象类差不多,但是这里面还是有很多的知识点。我们可以在接口中显式地将方法声明为public的,但是即使你不这么做,它们也是public的因此,我们要实现一个接口时,在接口中被定义的方法必须被定义为是public的;否则,它们将只是得到默认的包访问权限,这样在方法被继承的过程中,其可访问权限就被降低了,这样就会报错。


4. 两者的区别有哪些?



  1. 接口是抽象类的变体,接口比抽象类更加抽象,接口中所有的方
    法都是抽象的。


  1. 每个类只能继承一个抽象类,但是可以实现多个接口


  1. 抽象类中不一定都是抽象方法,抽象的而抽象类可以实现部分方法。但是接口中方法必须为public修饰的、抽象的不能实现具体的法。


  1. 接口中基本数据类型为static 而抽象类不是的。


  1. 抽象类中不一定都是抽象的方法,也可以有具体实现的方法,这样就可以把大家公用的方法提升到抽象类中,然后具体的方法可以留给子类自己实现(此处经典的应用,模板方法设计模式)。所以抽象类可以更好的实现代码的复用


JAVA中,一个类只能继承一个类(抽象类)(正如人不可能同时是生物和非生物),但是可以实现多个接口(吃饭接口、走路接口)。


当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。

相关文章
|
6月前
|
设计模式 算法 Java
后端面试题:接口和抽象类的区别?抽象类可以多继承吗?
字节后端面试题:接口和抽象类的区别?抽象类可以多继承吗?
62 0
|
2月前
|
Java
接口和抽象类【Java面向对象知识回顾②】
本文讨论了Java中抽象类和接口的概念与区别。抽象类是不能被实例化的类,可以包含抽象和非抽象方法,常用作其他类的基类。接口是一种纯抽象类型,只包含抽象方法和常量,不能被实例化,且实现接口的类必须实现接口中定义的所有方法。文章还比较了抽象类和接口在实现方式、方法类型、成员变量、构造方法和访问修饰符等方面的不同,并探讨了它们的使用场景。
接口和抽象类【Java面向对象知识回顾②】
|
5月前
|
Java
Java编程不再难:一文看懂抽象类与接口的区别和联系!
【6月更文挑战第17天】在Java OOP中,抽象类与接口助你构建复杂应用。以图书管理系统为例,抽象类`Book`作为基类提供共享属性和方法,不直接实例化。接口如`HasChapters`和`HasIssues`定义特殊行为。抽象类支持部分实现,单继承,适合共享行为;接口仅含常量和抽象方法,多实现,强调行为规范。通过继承和实现,实现代码复用和系统扩展性。理解两者异同,是提升Java编程能力的关键。
41 0
|
6月前
|
Java
Java面向对象程序设计5接口与抽象类
Java面向对象程序设计5接口与抽象类
63 0
|
6月前
|
存储 Java
【面试问题】接口和抽象类有什么区别?
【1月更文挑战第27天】【面试问题】接口和抽象类有什么区别?
|
6月前
|
Java
抽象类和接口的区别(小白版)
抽象类和接口的区别(小白版)
62 0
|
Java API
每日一道面试题之接口和抽象类有什么区别?
每日一道面试题之接口和抽象类有什么区别?
|
Java
Java面向对象—抽象类和接口
Java面向对象—抽象类和接口
105 0
|
Java
Java面向对象之抽象类与接口
抽象类的使用原则如下: (1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),默认为public; (2)抽象类也有构造器 (3)抽象类不能直接实例化,需要依靠子类采用向上转型的方式处理; (4)外部抽象类不允许使用static声明,而内部的抽象类运行使用static声明。使用static声明的内部抽象类相当于一个外部抽象类,继承的时候使用“外部类.内部类”的形式表示类名称 (5)有时候由于抽象类中只需要一个特定的系统子类操作,所以可以忽略掉外部子类。这样的设计在系统类库中会比较常见,目的是对用户隐藏不需要知道的子类
93 0