java基础-接口-抽象类

一.抽象类

抽象类的定义:当一个类被abstract关键字修饰的时候,则称这个类为抽象类。

抽象类的特点:

1.包含一个或多个抽象方法的类称为抽象类。类名必须用abstract修饰;当某类中有抽象方法时,编译器强制要求此类必须是抽象类,必须用abstract关键字修饰类名。

2.一个类中没有任何抽象方法时,也可以定义其为抽象类。此时这么做的主要意义是就是阻止产生这个类的任何对象。

3.无法创建抽象类的实例对象,不管类中有没有定义抽象方法。如果尝试这么做的话,编译器就会报错。

4.抽象类不能被final关键字修饰,final类是不允许被继承的,这与定义抽象类的初衷相违背。同理,被final修饰的类一定不是抽象类。

5.抽象类中并不是只能定义抽象方法,除了可以定义抽象方法外,它与普通类中定义成员与普通方法没有什么不同。

6.java中的继承为单继承模式,即一个类只能继承一个基类。对于抽象类来说也是如此,一个抽象类只能继承一个基类,并且,这个基类也必须是抽象类,然而这个抽象类也可以被其它类所继承,并且不限定其它类的个数。

创建抽象类的意义:使类的抽象性明确起来(不能创建抽象类的对象),并指明了该如何使用它(如果想使用抽象类中的抽象方法,那么就必须继承它,然后覆盖掉类中的抽象方法)。同时它也是一种很有用的重构工具,可以很容易的确定动态绑定方法在继承层次中的运转流程。

抽象方法:

1.只有方法的声明,没有方法体的方法称为抽象方法。

2.抽象方法必须使用abstract关键字修饰(在抽象类中必须显示使用abstract,在接口中不必显示使用,但它必定是抽象的)。

3.抽象方法与生俱来的意义就是为了被覆盖(重写)。所以抽象方法必须具有动态绑定的特性,即它不能是类中的private,final或static方法。

 

看下面的测试例子:

图中的编译器报错均验证了注释里的内容。

测试一个例子:创建一个基类,让他包含抽象方法printValue()方法,并在它的导出类中覆盖该方法,覆盖后的方法版本可以打印导出类中定义的某个整形变量的值。在定义该变量之处,赋予它非零值。在基类的构造器中调用这个方法。现在在main()方法中,创建一个导出类对象,然后调用它的printValue()方法,请解释发生的情形。

在代码中测试一下这个例子:

输出结果:

这个例子与前面的多态章节里的构造器中调用绑定方法具有多态性的模型完全一样,不同的只是基类成了抽象类,基类方法成了抽象方法,其它的内容完全一致。然而输出结果也是一致的。在多态中的那个例子输出这样的结果的原因是:因为在创建导出类对象时,会先去创建它的基类子对象。基类子对象的创建过程中会调用基类的构造器,然后因为构造器中调用了被导出类覆盖的方法,由于该方法具有多态性,所以实质上是调用的导出类中的覆盖方法版本,从而输出第一次i的值,I的值为0而不是定义处的5,是因为在创建导出类对象之前会先去创建基类的子对象,此时导出类中所有非静态成员的值都是在在创建导出类对象之前给它的对象分配的内存中的二进制0值。基类子对象构造完成后,再返回导出类构造器中执行构造器主体内容,在执行导出类构造器的主体内容之前,会先对导出类的成员变量进行定义处的初始化动作。然后i的值被初始化为5。导出类对象构造完成之后,调用printValue()方法,输出第二次i的值,为5.

然而,这里的基类是抽象的,不是不能创建它的对象吗?既然不能创建它的对象,在创建导出类对象时,通过导出类对象的构造器调用基类中的构造器时,不就会产生基类的对象了吗?构造器的作用不就是创建类的对象吗?这里有点理解不通,先MARK一下,等后面掌握jvm对类的加载原理后再回到这里来解析。*********

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值