浅谈JAVA抽象类及接口

浅谈JAVA抽象类及接口

​ 作为面向对象语言,JAVA同样具有封装、继承和多态的基本特征,其中抽象类和接口很好地体现了这一点,因为结构相似但又有实际的不同,所以这里放在一起说。

​ 假如我们要写一个Zoo的project,有多种动物的类Dog, Cat, Parrot等,它们都有eat()的方法,我们会自然想到建造一个Animal的类作为父类存放这些动物共有的方法及属性,如下:

public class Animal {
    public void eat(String food) {
        System.out.println("I am eating " + food);
    }
}

public class Dog extends Animal {

}
----------------------------------------------------
  应用时:
  Animal Snoopy=new Dog();
  Snoopy.eat("Cookies");

我们发现即使不用抽象类也可以很好地完成任务,那么为什么要用抽象类而不用普通类呢?

先从抽象方法讲起:


抽象方法

抽象方法指用“abstract” 修饰的方法,该方法只有声明,没有实现的方法体,它的具体实现交给子类来确定,可以看出抽象方法是生而为“继承”的,例如在Animal中只指定eat()方法,具体怎么吃让小狗小猫去决定:

abstract void eat(String food);

使用抽象方法有三点要求:

  • 如果一个类包含抽象方法,那么该类必须是抽象类。
  • 任何子类必须重写父类的抽象方法,或者声明自身为抽象类
  • 构造方法及静态方法(类方法,用static修饰)不能声明为抽象方法。

那么问题的答案很明了了,当Animal中有抽象方法时,那么使用普通类就不行了,必须使用抽象类,那么类里没有抽象方法,可不可以声明为抽象类呢?有何作用?


抽象类

抽象类是对对象(类)的抽象,和抽象方法一样,声明抽象类时只需要使用修饰符“abstract” 就可以:

public abstract class Animal {

    abstract void eat(String food);

}
  1. 抽象方法必须包含在抽象类里,但抽象类里不一定要有抽象方法

    先回答前一个小问题,没有抽象方法,类一样可以声明为抽象类,和普通类除了修饰符其余写法一样

  2. 抽象类只能被继承,不可以实例化

    很好理解,抽象类作为抽象出来的“模具”存在,自然不能“实例化”,只有抽象类的非抽象子类可以创建对象。第二个小问题答案也就有了,没有抽象方法的抽象类的作用是:强制子类去继承该类,并强制不允许被实例化。基于此,人们通常在设计阶段决定要不要设计抽象类。

  3. 抽象类可以有无数子类,但一个子类只能继承一个抽象类

    这个和普通类相同,子类只允许有一个父类。注意区分接口:子类可以实现多个接口。

  4. 抽象类可以继承别的抽象类,可以实现别的接口

  5. 抽象类可以有构造函数,只是是为子类提供的

    抽象类内构造函数是要求子函数必须实现的,所以在子类的构造函数中必须加一句

    super();

    public class Dog extends Animal {
    
       public Dog() {
           super();
       }
    
       @Override
       public void eat(String food) {
           //do something
       }
    }

我们了解到还有一种不能实例化也没有方法具体实现的机制,接口,那和抽象类有什么区别?


接口

接口是对对象行为的抽象,通常以interface来声明,是抽象方法的集合。接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。

public interface Movable {

    /*public static final*/ String name = null; //这里省略public static final,因为接口里变量
                                            //默认都是常量,而且不能private

    /*public abstract*/ void walk(); //这里省略public abstract,因为接口里方法默认都是抽象的,符合

    void run();                    //抽象方法的一切特点


}
  1. 如上图所示,接口内只能声明public常量和抽象方法

    public static final 和 public abstract 可以省略

  2. 接口内没有构造函数

    因为接口不能实例化,而且接口不是类,只是一类动作的集合,所以不存在“构造”的概念

  3. 接口不是被类继承(extends)了,而是要被类实现(implements)。

    准确地说,接口不是类,所以不能被继承,它是方法的集合,可以被实现。(用法相似,称呼不同)

  4. 子类可以实现个接口

    这一点是与其他类最明显的差异,普通类及抽象类都只能单一继承

  5. 接口可以继承别的接口,但不能继承


抽象类与接口的区别

  1. 抽象类是对对象的抽象;接口是对行为的抽象

    虽然两者在使用的相似,甚至可以互换而不出现bug,但两者设计的初衷是不同的

    1. 抽象类是一类事物,像Animal对Dog;
    2. 接口是一类动作,像Move对walk();
  2. 抽象类单一继承;接口可以多“继承”(准确地应该是实现

  3. 抽象类可以像普通类一样声明各类字段,各类方法;接口只能声明常量和抽象方法

    1. 抽象类可以实现包括抽象方法的其他任意方法;
    2. 接口只有常量和抽象方法在最新的JAVA8中情况有所改变,本篇只点不讲
    3. 接口内不能有构造函数而抽象类可以有;
  4. 基本区别就是这些,可以在日后的实践中慢慢掌握,目前来说必须掌握的是1.2.两条。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值