泛型接口,类和通配符

java零基础入门-高级特性篇(六) 泛型  中

泛型的使用位置,除了最常见的约束集合元素,还可以使用在接口,类,方法上面。最本质的原因就是为了在使用接口,类,方法的时候,可以将类型作为参数,进行类型的参数传递。这样可以使程序的编写更加的灵活,在创建对象,调用方法的时候动态的指定类型,所以泛型也可以理解为类型的参数化。

类型参数化

光看名字,又不好理解,通俗点可以这样理解。定义方法,接口的时候可以传递参数,参数通常都是指定类型的,比如

public void add(Student student);

public  void add (Teacher teacher);

这里的student是Student类型的参数,teacher是Teacher 类型的参数,他们已经指定好类型了。那么类型的参数化,就是指将类型作为参数传递进方法。比如

public void add(E e);

这里的add方法并没有指定任何一个具体的类型,而是将类型也作为了参数,E是任何一个类型,e是任意类型E的实例。如果传递进来的类型参数是Student,那么这个方法就是add(Student student);,如果传递进来的类型参数是Teacher ,那么这个方法就是add (Teacher teacher);

类型参数话

当使用泛型定义参数的时候,每一个传递进来的类型参数,就创建了一个该方法的版本,add(Student student)是一个add(E e)的版本,add (Teacher teacher)也是一个add(E e)版本。类型参数化的好处是使代码变得更加灵活,原因就在于此,因为可以通过对类型的抽象,使代码匹配各种不同有具体类型版本的需求。

泛型接口和泛型类

泛型接口的定义,public interface man<T>{...}。在接口名后面加上泛型类型参数T,这样就定义了一个泛型接口。

泛型接口

在接口中定义的类型参数可以在接口中当做类型使用,任何需要类型的地方都可以使用类型参数替代。比如传递的类型是Teacher,那么run(T t)就是老师在跑路,getObject()方法返回一个老师对象,getAll(String name)方法可以根据学校名字获取所有老师。加入传递的是Student,那么上面三个方法分别是学生在跑路,获取一个学生对象,根据学校名称返回所有学生。使用泛型接口,可以在实现的时候才定义具体需要实现的类型,使接口可以进行更高级的抽象。

泛型类的定义,public class Man<T>{...},在类名后面加上泛型类型参数T,这样就定义了一个泛型类。

泛型类

和泛型接口不同,类有构造器,并且构造器也可以使用泛型类型参数。在这个泛型类里面,使用了两个泛型类型参数,如果有必要可以定义更多的泛型参数。

如果java里面没有继承这个特性,那么泛型到这里就讲完了,但是,正因为java有继承这个特性,会导致很多其他的问题出现,其复杂程度会几何级的上升,后面的知识点对抽象能力和思维能力有较高的要求,请做好战斗准备。

下面从集合开始,先来思考几个前面没有思考过的问题。

1.如果集合加上了泛型,那么如果添加的元素是泛型的子类或者父类能添加进去吗?

添加子类父类

上面例子可以看出,如果泛型类型有子类,添加泛型类型的子类是可以的,但是如果泛型类型有父类,往集合添加泛型类型的父类会出现编译错误。因为子类继承了父类的所有方法,所以如果添加的是子类,当从集合取出的元素调用泛型类型的方法也不会有什么问题。但是如果定义的是子类的泛型集合,放入的是父类元素,当要使用子类方法的时候,父类元素可能没有,那么就会发生错误,所以泛型是子类型的话,是不允许加入父类型元素的。

2.再看另一个问题,如果父类是泛型类型,如何定义子类?

泛型类的子类

如果将一个类定义为泛型类,那么在创建该泛型类的子类的时候不能将子类直接继承该泛型类,而是需要指定父类泛型的类型。比如父类是Book<T>,子类不能直接extends Book<T>,而是需要指定T的类型,上例中使用的Book<Double>作为类型。

在java中,泛型不能继承和实现。为什么?WHY?请手动滑动到本章最上面,跟我一起念,类型参数化。问题的关键就在这里,因为泛型将类型作为一种参数,而参数是什么?在定义方法的时候,他不需要具体指定是什么数据,但是一旦你调用使用这个方法,就必须指定这个参数具体是什么。

使用泛型

由于方法中的泛型需要在定义类的时候就指定,所以如果需要使用含有泛型的方法,必须在创建该泛型类对象的时候就需要指定泛型类型,因为使用的时候必须指定类型,不论是普通参数还是泛型参数。那为什么继承的时候也要确定泛型呢?因为继承就是在使用一个已经定义好的类,使用泛型类,就要指定类型。

3.用什么样的参数形式来接受List<Book>这种形式的参数?

现在需要为所有List抽象一个方法,不论给的参数是List<Book>,List<String>,都可以接收并且打印List中的元素。是不是理所当然的想到了List<Object>?用List<Object>来接收参数就行了嘛。

泛型类型不匹配

啪啪啪,脸是不是很疼。显然这样是不可以的,错误提示参数类型不匹配,Object是所有类型的父类,但是List<Object>并不是List<Book>的父类,那应该使用什么方法达到上面的要求呢?泛型提供了一个泛型通配符用于接收所有类型的泛型类型。

泛型的通配符

通配符

泛型的通配符可以很好的解决所有泛型类型父类的问题,使用<?>来作为类或接口的泛型参数,这样就可以抽象出泛型类的父类。比如用List<?>可以看做所有List的父类,Set<?>可以看做所有Set的父类,使用?来表示一个未定义的类型,用来接受任何类型参数。

但是如果使用通配符,在部分功能上是会受到限制的。

1.只能通过Object遍历集合。在访问通配符泛型List<?>的时候,集合里的元素只能当做Object来访问,因为在定义的时候只是一个通配符,不是具体类型,所以不能进行类型转换只能作为Object访问。

2.不能使用add方法。List提供的add(E e)方法是需要指定类型的,这里不是E吗?这是个泛型类型啊?为什么要提供类型?因为这是定义,一旦要使用add(E e)方法,必须指定具体的类型。定义通配符以后,在使用通配符的方法里是不知道类型的,所以不能使用add方法。

不能用add方法

就算是Object类型也不能使用add方法,为什么?假设可以添加,会发生什么问题?如果我使用List<Book>作为参数,传入到printAllObject方法,运行完打印元素的语句后,会往List<Book>类型的集合里面新增一个Object类型的对象,而Object又是Book类型的父类,上面说过,泛型类型的父类型元素不能添加到该集合,所以这里就算是Objcet类型也不能添加。所以使用泛型通配符的话,这个集合的作用就是使用Object类型来遍历它。

上面第二点,如果集合使用了泛型通配符,要往集合添加Object是不允许的,因为无论最后来的是什么类型,Object都是这个类型的父类,所以不允许添加Object类型。那么如果我可以保证添加一个元素,一定是泛型类型的子类,那么是不是可以添加元素了?这个问题就涉及到泛型通配符的上下限问题了。下章继续。


本章有很多类名称相同,但是内容不同,请在不同的包下进行操作。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容