您的位置:首页 > 职场人生

黑马程序员--Java基础加强--03.代码简化 书写规律II_参数化数据类型【重载】【多态】【泛型】【泛型限定】【个人总结】

2013-07-29 09:18 1041 查看

代码简化 书写规律II --参数化数据类型

      重载类似 多态     泛型 泛型限定

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------
这篇日志着重阐述如何简化类型化参数数据类型做函数的参数的时候,代码简化技巧以及extends,?和super的使用规则

1.    背景_原始函数

[1]. 有以下代码片段

/*
*功能:打印集合中的元素 集合中的元素此时是String类型的
*/
public class TestV {
public void printColl(ArrayList<String> al){
for(String s: al){
System.out.print(s+" ");
}
}
}

/*

       需求变化:想在想传入Integer的元素,可以么,如果不可以,怎么修改程序?
*/
不可以在测试程序中传入new ArrayList<Integer>( ); 因为类型参数确定之后,在< >中的具体类型不具有多态性。所以,传入newArrayList<Integer>( );会编译失败。

解决办法:在类重写一个方法

public
void
printColl(ArrayList<Integer> al){
        for(int i: al){
            System.out.print(i+" ");
        }
    }

但是由于同一个类中,这两个方法参数个数相同,并且编译器对泛型信息进行擦除的原因,两个参数化类型 (ArrayList<Integer> 和 ArrayList<String>中的泛型信息:Integer和String) 被擦除具体参数之后,都变成相同的原始类型ArrayList了。因此,这两个函数还没有办法以重载的形式写到同一个类中。

[2]. 重载类似

功能相同,参数个数一致,但是参数类型不一致。同时,由于是参数化类型的原因不能重载到一个类中,现在就把处于这种情况的多个函数之间的关系称为重载类似

【需求】如何统一重载类似的几段代码?

2.    程序扩展性的逐步提高

(1). 借鉴上一篇日志的总结I

虽然不能重载,也不是真正的多态吧,但那时可以借鉴上一篇日志的总体优化思想:

重载---->多态 ---->泛型

       以这两段代码为例:

public
void
printColl(ArrayList<String>al){…}

public
void
printColl(ArrayList<Integer>al){…}

(2). 代码简化步骤 ----类型参数的公共父类是Object

假设:如果类型参数公共父类Object

[1]. 先将这几个类型化参数函数进行类似多态处理。

Object替换其他类型参数进行功能相同重载类似函数统一

写成如下形式:void printColl(ArrayList<Object> al){…}

【注意】

由于类型参数之间不具有多态性,所以这一步只能算上一步推理用到工程中不好使!

[2]. 遇到Object就进行泛型升华

此时由于这个参数化类型具体化的类型参数处于<>中,所以此时可以使用通配符进行占位
(?),还原为原始类型(没有泛型的原始数据类型就是Object本身)和自定义类型参数

所以,类型化参数是Object的公共父类的时候,可以统一成以下三种形式

{1}.通配符占位       
public void
printColl(ArrayList<?> al){…}

{2}. 原始类型           
public void
printColl(ArrayList al){…}

{3}. 自定义类型参数public <T>
voidprintColl(ArrayList<T> al){…}

[泛型类/泛型方法]

以上的分析可以用下面的图来表示:

 


(3). 代码简化步骤 ----类型参数的直接父类不是Object

假设:如果类型参数公共父类不是Object类,设为java.lang.Number类型

要简化的代码如下:

public
void
printColl(ArrayList<Long> al){…}

public
void
printColl(ArrayList<Integer> al){…}

[1]. 先将这几个类型化参数函数进行类似多态处理。

直接公共父类Number替换其他类型参数进行功能相同重载类似函数统一

写成如下形式:void printColl(ArrayList<Number> al){…}

[2]. 遇见父类类型使用泛型限定进行升华

采用extends进行泛型限定,有下面两种形式:

{1}. 使用父类固定的普通方法:

格式:public
void
printColl(ArrayList<? extends Number> al){…}

示例代码:

public class GenericFuncitonXV{
public void printColl(ArrayList<? extends Number> al){
Iterator<?extends Number> it =al.iterator();
while(it.hasNext()){
Objectobj =it.next();
System.out.print(obj+" ");
}
System.out.println();
}

public static void main(String[] args) {

GenericFuncitonXV genObj=new GenericFuncitonXV();
ArrayList<Integer>al1 =new ArrayList<Integer>();
al1.add(123);
al1.add(456);
al1.add(789);
genObj.printColl(al1);
System.out.println("**********************");
ArrayList<Long>al2 =new ArrayList<Long>();
al2.add(12345678l);
al2.add(45645678l);
al2.add(78945678l);
genObj.printColl(al2);
}
}


{2}. 使用父类通用的泛型类+普通方法:
class A <T> {
    public
void
printColl(ArrayList<?
extends T> al){
        //…
    }
}
 
示例代码:
public class GenericFuncitonXIII <T> {
public void printColl(ArrayList<? extends T> al){
Iterator<?extends T> it =al.iterator();
while(it.hasNext()){
Objectobj =it.next();
System.out.print(obj+" ");
}
System.out.println();
}

public static void main(String[] args) {

GenericFuncitonXIII<Number> genObj =new GenericFuncitonXIII<Number>();
ArrayList<Integer>al1 =new ArrayList<Integer>();
al1.add(123);
al1.add(456);
al1.add(789);
genObj.printColl(al1);
}
}

3.    总结II

遇见参数化类型的时候:

整体思路:

重载类似---->由多态类似统一【思想上的过渡,不能使用在工程中】

多态类似---->由泛型限定升华【extends升华】

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐