温故而知新——java抽象类和接口
来源:互联网 发布:无经验淘宝客服简历 编辑:程序博客网 时间:2024/06/02 21:46
抽象类
一般我们编写一个类时,常常会为该类定义一些方法,这些方法都有具体的实现。但是在某些情况下,父类只知道子类应该包含什么方法,但是不知道子类是怎么实现这个方法的。比如几何图形类包含三角形子类,长方形子类,圆形子类,父类知道这些子类要有计算周长和面积的方法,但是却不知道各自怎么实现的(各自实现方法也是不同的)。
如何既能让父类定义计算周长和面积的方法,又不用提供具体的方法实现呢?
使用抽象方法即可满足该要求:抽象方法只有方法的声明,没有方法的具体实现。
抽象方法和抽象类
抽象方法和抽象类必须使用 abstract 修饰符来定义,有抽象方法的类只能被定义成抽象类,抽象类里可以没有抽象方法。
抽象方法和抽象类的规则如下。
①抽象类必须使用 abstract 修饰符来修饰,抽象方法也必须使用 abstract 修饰符来修饰,抽象方法不能有方法体。
②抽象类不能被实例化,无法使用new关键字来调用抽象类的构造器创建抽象类的实例。即使抽象类里不包含抽象方法,这个抽象类也不能创建实例。
③抽象类可以包含成员变量、方法〈普通方法和抽象方法都可以)、构造器、初始化块、内部类(接口、枚举)5中成分。抽象类的构造器不能用来创建实例,主要用来被其他子类调用。
④抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。
⑤如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。
抽象类可以用“有得有失”来形容:
得:抽象类可以包含抽象方法;
失:抽象类不能创建实例。
定义抽象类的方法:
在普通类上增加 abstract 修饰符即可。
定义抽象方法:
在普通方法上增加 abstract 修饰符,并把普通方法大括号中的方法体部分全部删掉,并在方法后增加分号。
通过代码来演示抽象类和抽象方法:
abstract class Shape{//抽象图形类 public abstract double getArea();//抽象方法,计算面积 public abstract double getPan();//计算周长}
class Square extends Shape{ //定义一个正方形类,继承图形抽象类 protected double len; Square(double len){ this.len = len; } public double getArea(){//抽象方法的具体实现 return len*len; } public double getPan(){//抽象方法的具体实现 return 4*len; }}
class Rectangle extends Square{//定义一个长方形类,继承图形抽象类 private double wid; Rectangle(double len,double wid){ super(len); this.wid = wid; } public double getArea(){//抽象方法的具体实现 return wid*len; } public double getPan(){//抽象方法的具体实现 return (wid+len)*2; }}
class Circle extends Shape{//定义一个圆形类,继承图形抽象类 private double r; Circle (double r){ this.r = r; } public double getArea(){//抽象方法的具体实现 return Math.PI*r*r; } public double getPan(){//抽象方法的具体实现 return Math.PI*r*2; }}
从这里可以看出,抽象类就是为了继承而存在的,如果你定义了一个抽象类,却不去继承它,那么等于白白创建了这个抽象类,因为你不能用它来做任何事情。对于一个父类,如果它的某个方法在父类中实现出来没有任何意义,必须根据子类的实际需求来进行不同的实现,那么就可以将这个方法声明为abstract方法,此时这个类也就成为abstract类了。
接口
在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类。这两者有太多相似的地方,又有太多不同的地方。
抽象类是从多个类中抽象出来的模板,如果将这种抽象进行得更彻底,则可以提取出一种更加特殊的“抽象类”——接口。
接口里不能包含普通方法(抽象类可以),接口里所有的方法都是抽象方法。
接口定义了某一些类所需要遵守的规范,接口不关心这些类的内部状态,也不关心这些类里方法的具体实现细节,它只规定类里必须提供的方法。
接口不提供任何实现,接口体现的是规范和实现分离的哲学。
接口和抽象类语法上的区别
①抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法。
②抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的。
③接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法。
④一个类只能继承一个抽象类,而一个类却可以实现多个接口。(单继承多实现)。
抽象类和接口的例子
下面看一个网上流传最广泛的例子:
门和警报的例子:门都有open( )和close( )两个动作,此时我们可以通过抽象类和接口来定义这个抽象概念。
abstract class Door {//抽象类 public abstract void open(); public abstract void close();}
interface Door {//接口 public abstract void open(); public abstract void close();}
现在如果我们需要门具有报警alarm( )的功能,那么该如何实现?下面提供两种思路:
①将这三个功能都放在抽象类里面,但是这样一来所有继承于这个抽象类的子类都具备了报警功能,但是有的门并不一定具备报警功能。
②将这三个功能都放在接口里面,需要用到报警功能的类就必须实现这个接口中的所有抽象方法,包括open( )和close( ),但是很可能这个类根本就不具备open( )和close( )这两个功能,比如火灾报警器。
从这里可以看出, Door的open() 、close()和alarm()根本就属于两个不同范畴内的行为,open()和close()属于门本身固有的行为特性,而alarm()属于延伸的附加行为。
因此最好的解决办法是单独将报警设计为一个接口,包含alarm()行为,Door设计为单独的一个抽象类,包含open和close两种行为。再设计一个报警门继承Door类和实现Alarm接口。
interface Alram {//单独定义一个警报接口,谁需要谁实现它 void alarm();//接口中方法和属性的修饰符都是可以省略的,为防止写错,直接不写就行}abstract class Door {//定义门的抽象类 void open();//这里没有abstract,是抽象类中的普通方法 void close();}class AlarmDoor extends Door implements Alarm { void oepn() { //.... } void close() { //.... } void alarm() { //.... }}
- 温故而知新——java抽象类和接口
- java温故而知新之接口与抽象类
- C#温故而知新学习系列之面向对象编程—接口和抽象类的区别是什么?(十八)
- Java——接口和抽象类
- Java——抽象类和接口
- JAVA——抽象类和接口
- 抽象类和接口——Java
- Java基础——Java的抽象机制,抽象方法抽象类和接口
- Java 抽象类,抽象方法和接口
- Java抽象类和抽象方法、接口
- java基础——抽象类和接口
- Java基础——抽象类和接口的关系
- 【Java笔记】——抽象类和接口
- 核心java系列——接口和抽象类
- Java基础(六)——接口和抽象类
- java基础学习总结——接口和抽象类
- java学习笔记8——抽象类和接口
- 【Java基础】——接口和抽象类
- adb 连接不上
- DPDK中文-DPDK的reorder
- 使用PostMan模拟请求
- 函数指针 & 函数对象
- JAVA求圆的面积
- 温故而知新——java抽象类和接口
- [VB.net][WinForm]Panel控件移动\鼠标拖动
- Height Half Values
- Vue2.0 事件发射与接收
- 一道简单的趣味编程
- 个人学习安卓基础的案例逻辑-数据存储
- php-fpm多用户运行的两种方式
- Java的反射机制
- iOS中属性@property中的关键字的使用说明