第七章:复用类

复用类

和java中的所有事物一样,问题解决一般围绕类进行通过创建新类复用代码,不需要从头写。有两种方法达到这个目的。其中第一种是只需要在新的类中产生现有类的对象,由于新的类是由现有类的对象所组成,因此该方法称为组合。该方法只是复用现有程序代码的功能而非形式。第二种是按照现有类的类型创建新类,无需改变现有类的形式,采用现有类的形式并在其中添加新的代码,该方法称为继承。

组合

对于非基本类型的对象,必须将其引用置于新类中,可以直接定义基本类型数据。
在这里插入图片描述在这里插入图片描述以上两个类所定义的方法中,有一个很特殊:toString(),每个非基本类型的对象都有一个toString(),当编译器需要一个String而只有一个对象,该方法会被调用。类中域为基本类型时能够自动被初始化为零,但是对象引用被初始化null。
编译器并不简单的为每个引用都创建默认对象,如果想初始化这些引用,可以在代码的以下位置进行:
1.在定义对象的地方。
2.在类的构造器中。
3.在正要使用这些对象之前。
4.使用实例初始化。
以下是该四种方法例子:
在这里插入图片描述
在这里插入图片描述

继承

在继承过程中,需要先声明新类和旧类相似。这样做会自动得到基类中所有的域和方法。
在这里插入图片描述
在这里插入图片描述
在继承过程中,并不一定费的使用基类的方法,也可以在导出类中添加新方法。

  • 初始化基类
    当创建一个导出类的对象时,该对象包含一个基类的子对象。这个子对象与你使用基类直接创建的对象一样,二者区别是后者来自于外部,基类子对象被包含在导出类对象的内部。对于基类子对象的正确初始化很重要。在构造器中调用基类构造器执行初始化。java自动在导出类的构造器中插入对基类的构造器的调用。如下例子所示:
    在这里插入图片描述
    从该例子可以看出,构造过程是从基类 向外扩,因此基类 在导出类构造器可以访问他之前就已经完成初始化。
    带参构造器:
    如果没有默认的基类构造器,或者想调用一个带参数的基类构造器,就必须用关键字super显式的写调用基类构造器的语句,并且配适当的参数列表:
    在这里插入图片描述
    调用基类构造器必须是在导出类构造器中要做的第一件事。

代理

这是继承与组合之间的,因为将一个成员对象置于所要构造的类中(如同组合),但与此同时在新类中暴露该成员对象的所有方法(如同继承)。如下例子:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看出,以上例子中方法是如何传递给底层的controls对象,其接口由此就与使用继承得到的接口相同了。

结合使用组合和继承

在这里插入图片描述
在这里插入图片描述

  • 确保正确清理
    析构函数是一种在对象被销毁时被自动调用的函数。如果想要某个类清理东西,必须显示的编写一个特殊的方法来做这件事,并且确保客户端程序员知道他们必须调用这一方法。

  • 名称屏蔽
    如果一个基类拥有某个已被多次重载的方法名,则在导出类中重新定义该方法名并不会屏蔽其在基类中的任何版本。如下实例:
    在这里插入图片描述
    使用与基类完全相同的特征签名及返回类型覆盖相同名称的方法非常正常。

在组合与继承之间选择

组合通常适用于想在新类中使用现有的类的功能而非它的接口。即在新类中嵌入某个对象,让其实现所需要的功能,但新类的用户看到的只是为新类所定义的接口,而非所嵌入的对象的接口。需要在新类中嵌入一个现有类的private对象。允许类的用户直接访问新类中的组合成分是极具意义的,将成员对象声明为public。如下例子:
在这里插入图片描述
在继承的时候,使用一个现有类,并开发一个他的特殊版本。通常这意味着在使用一个通用类,并为了莫种特殊需求将其特殊化 。

protected关键字

它指明就类用户来说,是private的,但对于任何继承于此类的导出类或其他任何位于同一包内的类来说,是可以访问的。如下例子:
在这里插入图片描述

向上转型

导出类转型成基类,由于向上转型是从一个较专用的类向通用的类转换,所以总是安全的。导出类是基类的一个超集,在向上转型的过程中,类接口中唯一可能发生的是丢失方法,而不是获取。

  • 到底是该用组合还是继承,判断方法是是否需要从新类向基类转型,如果必须向上转型则继承是必须的,但如果不需要,应当考虑是否是需要继承。

final关键字

一个是static和final的域只占据一段不能改变的存储空间。对于基本类型,final使数值恒定不变,用于对象引用,final使引用恒定不变。一旦引用被初始化指向一个对象,就无法再把它改为指向另一个对象。但是对象其自身却可以被修改,java并未提供使任何对象恒定不变的途径。如下例子:
在这里插入图片描述
在这里插入图片描述

空白final:
java允许生成“空白final”,指被声明为final但又未给定初值的域。如下例子:
在这里插入图片描述
必须在域的定义处或者每个构造器中用表达式对final进行赋值。
final参数:
java允许在参数列表中以声明的方式将参数指明为final。意味着无法在方法中更改参数引用所指向的对象。
final方法:
使用final方法的原因有两个:第一个是把方法锁定,防止任何继承类修改他的含义,第二个是效率如果将一个方法指明为final,同意编译器将针对该方法的所有调用都转换为内嵌调用。
final和private关键字:
类中所有的private方法都隐式指定为final。由于无法取用private方法,所以就无法覆盖它。可以对private方法添加final修饰词,但这并不能给该方法增加任何额外的意义。“覆盖”只有在某方法是某类的接口的一部分时才会出现。即必须能够将一个对象向上转型为它的基本类型并调用相同的方法。
final类:
将一个类整体定义为final时,表明不打算继承该类。final类的域可以根据个人的意愿选择是或不是final,不论类是否被定义为final,相同的规则适用于定义为final的域。由于final类禁止继承,所以final类中所有的方法都隐式指定为final的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值