深入解析Java抽象类
05-14 17:161164浏览
在继承中,我们已经了解了子父类的关系以及如何对子父类进行设计,如果已经存在多个实体类,再去定义父类其实是不断的抽取公共重合部分的过程,如果有需要将会产生多重继承关系。在抽取整理的过程中,除了属性可以复用,有很多方法一样也可以复用,假如以图形举例:矩形、圆形,都可以具有周长和面积两个方法,但是计算的方式完全不同,矩形和圆形之间肯定不能构成子父类关系,那么只能是同时去继承一个父类,那么问题就来了,这两个类都有什么共同点?
除了都是图形好像并没有什么共同点,矩形有两组边长,圆形是通过半径来描述,如果非要往一起联系的话。难道说是都可以计算出周长和面积?细细想来,也是能说出一番道理的,但是这好抽象啊!如果真的是这样,也只能有一个模糊的思路,既然描述图形的属性不能够共用那就分别放在两个子类中吧,那么计算周长和面积的方法要怎么搞?如果在父类中定义相应的方法,那参数列表怎么写?方法体怎么填?这个坑好像有点大,接下来,我们就要华丽地将这个坑填平。
1. 抽象与抽象类
在上面的例子中,我们遇到了一个情况,有两个在逻辑上看似相关的类,我们想要把他们联系起来,因为这样做可以提高效率,但是在实施的过程中发现这个共同点有点太过模糊,难以用代码描述,甚至于还不如分开用来的方便,这时就要引出抽象的概念,对应的关键词为:abstract。
- abstract可以修饰方法,修饰后被称为抽象方法
- abstract可以修饰类,修饰后被称为抽象类
- abstract不能与static修饰符同时使用
- abstract不能与final修饰符同时使用
那么使用了abstract又能如何呢?这代表指定的方法和类很难表述,那么。。。就不用表述了!对于矩形类(Rectangle)与圆形类(Circle)的父类:图形类(Figure),我们只能总结出他具有计算周长和面积的方法,而具体的实现方法我们无法给出,只有明确了图形之后,才能给出具体的实现,于是我们使用抽象来描述这两个方法,被abstract修饰的方法不需要有方法体,且不能为private,由于抽象方法没有方法体,那么如果被代码调用到了怎么办呢?以下两个限制规则可以杜绝这个问题:
- 抽象方法只能存在于抽象类中(接口在另外的文章中讨论)
- 抽象类无法被直接实例化(匿名内部类的用法暂不做讨论)
既然抽象类不能被实例化,那么自然也就不会调用到没有方法体的那些方法了,那这些方法该怎么被调用呢?我们需要一步一步的来梳理,至少目前我们已经能够清晰的得到如下的关系图了:
2. 抽象类的特点
抽象类的本质依然是一个类(class),所以具备着一个普通类的所有功能,包括构造方法等的定义,总结一下,抽象类具有以下的几个特点:
- 抽象类由abstract修饰
- 抽象类中允许出现抽象方法
- 抽象类不能通过构造器直接实例化
- 可以在抽象类中定义普通方法供子类继承
现在,我们已经可以将抽象父类用代码描述出来:
// 定义抽象类:图形类
public abstract class Figure{
// 定义计算周长的抽象方法:getC()
public abstract double getC();
// 定义计算面积的抽象方法:getS()
public abstract double getS();
// 定义描述图形的非抽象方法:print()
public void print(){
System.out.println("这是一个图形");
}
}
3. 天生的父类:抽象类
现在我们已经有了一个抽象类,其中也定义了抽象方法,抽象类不能被直接实例化保证了抽象方法不会被直接调用到。回忆一下我们的出发点,费劲巴力的弄出个抽象类就是为了提取出两个类比较抽象的共同点,那么下一步自然是继承了。
- 抽象类不能直接实例化,是天生的抽象类
- 如果一个类继承了抽象类,那么必须重写父类中的抽象方法
- 如果抽象类中定义了构造方法,可以被子类调用或在实例化子类对象时执行
- 如果抽象类的子类依然是抽象类,可以不重写抽象方法,将重写操作留给下一级子类
以上就是动力节点在线的免费视频课程中讲解的Java抽象类,想深入学习的小伙伴可以去自己观看剩下的视频课程自己学习哦。
{{item.create_time}}