Java 复用类

Java中所有问题的解决都是围绕着类的展开的。可以通过创建新类来复用代码,而不必重头开始编写。可以使用别人已开发并调度好的类。

此方法的窍门在于使用类而不破坏现有程序代码。

有两种方法可以达到这个目的:

  1. 只需要在新的类中产生现有的对象。(由于新的类是由现有类的对象所组成,故称为组合)
  2. 按照现有的类的类型来创建新类。(无需改变现有类,并在其中添加新代码。称为继承)

1 组合语法

只需将对象引用置于新类中即可。

2 继承语法

当创建一个类时,总是在继承,因此,除非已明确指出要从其他类中继承,否则就是在隐式地从Java的标准根类Object进行继承。

可以将继承视作是对类的复用。

3 代理

第三种关系称为代理,Java并没有提供对它的直接支持。这是继承与组合之间的中庸之道,因为我们将一个成员对象置于所要构造的类中(就像组合),但与此同时我们在新类中暴露了该成员对象的所有方法(就像继承)。

4 结合使用组合和继承

同时使用组合和继承是很常见的事。

虽然编译器强制你去初始化基类,并且要求你要在构造器起始处就要这么做,但是它并不监督你必须将成员对象也初始化,因此在这一点上你自己必须时刻注意。

确保正确清理

Java中没有C++中析构函数的概念。析构函数是一种在对象被销毁时可以被自动调用的函数。其原因可能是因为在Java中,我们的习惯只是忘掉而不是销毁对象,并且让垃圾回收器在必要时释放其内存。

Java SE5新增加了@Override注解,它并不是关键字,但是可以把它当作关键字使用。当你想要覆写某个方法时,可以选择添加这个注解。

@Override注解可以防止你在不想重载时而意外地进行了重载。

5 在组合和继承之间选择

组合和继承都允许在新的类中放置子对象,组合是显式地这样做,而继承则是隐式地做。

组合技术通常用于想在新类中使用现有类的功能而非它的接口这种情形。

在继承的时候,使用某个现有类,并开发一个它的特殊版本。

“is-a”(是一个)的关系是用继承来表达的。

“has-a” (有一个)的关系则是用组合来表达的。

6 protected关键字

在实际项目中,经常会想要将某些事物尽可能对这个世界隐藏起来,但仍然允许导出类的成员访问它们。

关键字protected就是起这个作用的。它指明“就类用户而言,这是private的,但对于任何继承于此类的导出类或其他任何位于同一个包内的类来说,它却是可以访问的”。

尽管可以创建protected域,但是最好的方式还是将域保持为private。

7 向上转型

“为新的类提供方法”并不是继承技术中最重要的方面,其最重要的方面是用来表现新的类和基类之间的关系。这种关系可以用“新类是现有类的一种类型”这句话加以概括。

为什么称为向上转型

该术语的使用是有其历史原因的,并且是以传统的类继承图的绘制方法为基础的,将根置于页面的顶端,然后慢慢向下。

由导出类转型成基类,在继承图上是向上移动的,因此一般称为向上转型。

由于向上转型是从一个较专用类型向较通用类型转换,所以总是很安全的。也就是说,导出类是基类的一个超集。

向上转型的过程中,类接口中唯一可能发生的事情是丢失方法,而不是获取它们。

再论组合与继承

到底是该用组合还是用继承,一个最清晰的判断办法就是问一问自己是否需要从新类向基类进行向上转型。如果必须向上转型,则继承是必要的。

8 final关键字

Java的关键字final的含义存在着细微的区别,但通常它指的是“这是无法改变的”。

以下谈论了可能使用到final的三种情况:数据、方法和类。

final数据

许多编程语言都有某种方法,来向编译器告知一块数据是恒定不变的。有时数据的恒定不变是很有用的,比如:

  1. 一个永不改变的编译时常量。
  2. 一个在运行时被初始化的值,而你不希望它被改变。

final方法

使用final方法的原因有两个。

第一个原因是把方法锁定,以防任何继承类修改它的含义。

这是出于设计考虑:想要确保在继承中使方法行为保持不变,并且不会被覆盖。

第二个原因是效率。

final和private关键字

类中所有的private方法都隐式地指定为是final的。由于无法取用private方法,所以也就无法覆盖它。

final类

当将某个类的整体定义为final时,就表明了你不打算继承该类,而且也不允许别人这样做。

换句话说,你对该类的设计永不需要做任何变动,或者出于安全的考虑,你不希望它有子类。

9 初始化及类的加载

Java中,加载方式不同于C++,在Java中所有的事物都是对象。每个类的编译代码都存在于它自己的独立的文件中。该文件只有在需要使用程序代码时,才会被加载。一般来说,可以说:“类的代码在初次使用时才加载。”这通常是指加载发生于创建类的第一个对象之时,但是当访问static域或static方法时,也会发生加载。

初次使用之处也是static初始化发生之处。所有的static对象和static代码段都会在加载时依程序中的顺序(即,定义类时的书写顺序)而依次初始化。

当然,定义为static的东西只会被初始化一次。

10 总结

继承和组合都能从现有的类型生成新类型。

组合一般是将现有类型作为新类型底层实现的一部分来加以复用,而继承复用的是接口。

在使用继承时,由于导出类且有基类接口,因此它可以向上转型至基类,这对多态来说至关重要。

尽管面向对象编程对继承极力强调,但在开始一个设计时,一般应优先选择使用组合(或者可能是代理),只在确实必要时才使用继承。

在设计一个系统时,目标应该是找到或创建某些类,其中每个类都有具体的用途,而且即不会太大(包含太多的功能而难以复用),也不会太小(不添加其他功能就无法使用)。如果你的设计变得过于复杂,通过将现有的类拆分为更小的部分而添加更多的对象,通常会有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值