普通类, 抽象类 和 接口

普通类和抽象类

平时使用的哪些是普通类?

  类本身是一种抽象的数据类型,是对某一事物的整体描述和定义, 我们平时new出来的对象, 就是通过在普通类的模版上产生的对象.

  类中包含静态的属性(属性)和动态的行为(方法)

  抽象类是在普通类的基础上又抽象了一些.

  那么,

抽象类是什么?

  抽象类: 如果类中包含抽象方法(使用abstract修饰的方法),那么这个类就是抽象类, 必须在类前面加上abstract修饰符;
  但如果类中没有抽象方法, 类的前面还是加了abstract, 那这也是一个抽象类, 是一个挺蛋疼的抽象类

  抽象方法: 只有方法的声明, 没有方法的实现, 具体的实现交给子类.

  抽象类是不可以通过new的方法构造的, 但是抽象类可以有构造器
  抽象类作为某个继承者的父类, 当实例化子类时,父类就会初始化.
  继承了抽象类的子类通过super()或者super(参数…)来调用抽象类中的构造方法

  抽象类不能直接实例化, 内部的抽象方法又没有具体的实现,那,

抽象类的意义何在?

最主要的作用就是方便维护和重用

  1. 可以把类与类之间 相同的属性和方法进行抽象, 或者对子类进行一些约束, 这样方便代码和程序的维护

  举一个栗子, 学校招新生, 有"小学部"和"初中部"两个类, 这两个对象都是从"学校部门"这个类继承而来的, 每个类有公有的属性(学生数量, 年级数量, 教师数量等),这些相同的属性在抽象类"学校部门"中定义.
  如果想修改公有属性,只需要在抽象类中修改就好了,不需要分别对子类进行修改
  如果想在"学校部门"中修改某个信息, 会受到父类的限制, 这样也会对一些东西进行统一的限制.

  1. 当一个相似的类产生时,只要实现该抽象类,就可以获得抽象类的属性和方法

  这是学校新开了一个"高中部", 如果没有"学校部门"这个抽象类,就需要将所有的属性和方法重新写一遍; 但是如果有抽象类,就可以直接继承这个抽象类, 使用个公有的属性, 仅需对自己独有的属性和方法进行补充就可以了.

抽象类怎么使用?

  子类和父类 有一种 == “is a” == 的继承关系, 使用抽象类, 需要有一个相对没那么抽象的子类继承他.
  抽象类不能使用new创建出对象, 生来是用来让子类继承的;
  继承使用extends继承,但是extends具有局限性,是单继承,无法继承多个(儿子只能有一个爸爸)
  抽象方法只有方法的声明, 没有方法的实现, 是用来让子类实现的.

接口

接口是什么

  interface, 好像SDK中的API, java中的接口是可以直接供别人调用的方法,如果说抽象类是对一类事物进行抽象的话,接口就是对行为(方法)的抽象
  接口代表一种特定的行为,不同的类可以根据各自的需要实现某个接口
  接口中可以有属性和方法,属性只能使用public static final修饰(默认如此), 方法只能使用public abstract修饰(默认如此)
  接口中所有的方法不能有具体的实现,必须全部都是抽象方法,和上面相比下来,抽象类还有写点可以实现的方法的自由,接口则代表了一种极端的抽象,我们使用里面的方法,而里面的所有方法都是抽象的.
  接口可以理解为对象之间互相通信的协议, 接口中抽象方法的实现还是要看派生类
  一个类实现了一个接口, 就相当于翻译成"如果你是… 你就必须能… ", 类是否实现接口是"有没有"的关系
  使用接口就避免了extends的问题, 一个类可以实行多个接口

抽象类和接口的区别

项目抽象类接口
方法可以存在抽象方法,也可以存在方法的实现只存在抽象方法
成员变量可以包含各种类型的成员变量(属性)只可以是public abstract类型的成员变量
能否有静态代码块√ 可以有× 不能有
-模板式设计: 更改公共内容只需要更改抽象类就好了辐射式设计: 接口变更,实现这个接口的类也必须变更

  门和警报的例子: 现在门拥有open()和close()两个方法,分别通过抽象类和接口定义门:

// 抽象类
abstract class Door {
    public abstract void open();
    public abstract void close();
}

// 接口
interface Door{
	public abstract void open();
    public abstract void close();
}

   如果取名为Door,是定义为接口好呢?还是定义为类好呢?

  门是一个事物,而不是一个行为,所以门定义为抽象类比较好,抽象类中包含两个方法, open()和close(), 也就是门的共性的固有方法

  现在, 我们想考虑一个报警功能alarm(), 应该怎么写?

  如果将alarm()放到抽象类里,是不行的,因为不是所有门都有报警功能,alarm()并不是公有的属性
  应该将alarm()重新设置成一个接口, 里面包含alarm()方法,
  不同的门继承抽象类, 具备抽象类中公有的属性, 有的门类具有报警功能, 那么就实现alarm()接口,没有的话就不实现.

interface Alram {
    void alarm();
}
 
abstract class Door {
    void open();
    void close();
}
 
class AlarmDoor extends Door implements Alarm {
    void oepn() {
      //....
    }
    void close() {
      //....
    }
    void alarm() {
      //....
    }
}

参考

https://blog.csdn.net/qdh186/article/details/79704852
https://www.cnblogs.com/dolphin0520/p/3811437.html
  

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值