Java语言精粹之二:类型系统

Java是一门面向对象的语言,其中每个对象都是通过类型来创建的,而这些类型是由类和类所实现的接口决定的。实际上一个对象是多个类型的实例,于是有了多态类型系统的概念。

定义类型有三种方式:
1、 类:定义了对象内部的数据结构和一组操作数据的方法。类可以继承其他类,从而形成一棵树,树的根节点是Object。
2、 接口:声明了一组方法,描述自己能干什么。一个类可以实现多个接口。
3、 抽象类:介于类和接口之间,即可以像类一样定义数据结构和方法,也可以像接口一个仅声明一个方法。一个类只能继承一个抽象类。
只有类才可以实例化。

从历史上看,计算机语言引入类型系统,是为了让[i]编译器(1)[/i]能确认相关对象需要分配多少空间。而在[b]Java中类型系统有三个作用:[/b]
1、 确定分配多少空间(只有类才需要,因为只有类才能实例化)
2、 描述方法的参数、返回值、异常
3、 对方法的传入参数、传出返回值、声明异常做编译时检查
正是由于第三点,我们说Java是[b]类型安全[/b]的。
[i]注1[/i]:个人认为是运行时确定对象需要分配多少空间

接口提供了一种将[b]抽象与实现分离[/b]的方式。抽象是指[i]我(1)[/i]能干什么,实现是指我怎么干的。对于类库的使用者,只需要关注这个类库能干嘛,即它提供的接口,而不需要关系它是怎么实现这个功能的。举个例子,比如你向领导汇报工作,只需要告诉他你做了什么,接下来要做什么,而不需要告诉他每件事是怎么做的。当我们设计接口的时候需要注意,接口传递给人们的语义不能和具体的实现相关。[b]由于接口和类的分离,使得我们可以分开考虑抽象的设计和类的实现,让我们的设计更加优良。[/b]
[i]注1[/i]:指定类型的对象

而类就是指接口的实现,通常我们需要从接口中获得一些信息、数据,而这些都要由实现类来提供。那么类如何提供数据呢?要么自己有一份,要么从别的地方获取。也就是说类中可以定义一套相关的数据,方法就是操作这些数据,以返回给用户需要的结果;类也可以从父类中获取一些行为(继承),或者从其他类中获取一些行为(持有)来计算用户需要的结果。

Java类型系统中隐含的问题:
interface A {
void hello();
}

interface B{
void hello();
}

class C implements A, B {
public void hello() {
print(“hello world”);
}
}

实现类C无法为接口A,B的hello()方法提供不同的实现。但是在实际开发中,只要你的方法命名注意的话,这种错误出现的概率基本为0。

Java类型系统中真实的问题:
首先区分一个概念,对象的编译时类型和运行时类型。
编译时类型:对象的全限定名
运行时类型:对象的类加载器 + 对象的编译时类型

由于类加载器的引入,一些看似正确的代码也会出错了,比如:
TypeA type = (TypeA) factory.createTypeA();
在运行时抛出ClassCastException异常。
其原因是factory在创建TypeA的时候使用了自定义的类加载器,而TypeA type中定义的TypeA是由系统类加载器加载的,自定义的类加载器在加载TypeA又不会委托给系统类加载器,于是:
TypeA type中TypeA的运行时类型为:SystemClassLoader + TypeA
factory.createTypeA() 中TypeA的运行时类型为:MyClassLoader + TypeA
两种类型不同,所以抛出ClassCastException异常。

作者思路:
1、 描述Java类型系统的组成:类,接口,抽象类,指出Java类型和其他语言的区别
2、 描述以前人们对接口的误解,强调接口的重要性
3、 对比类和接口,给出一个良好的设计准则
4、 描述类型系统潜在的问题和真实的问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值