Java学习6之泛型

1.泛型定义

1.泛型类:

public class Generic <T>{

  public void get(T t){

    System.out.println(t);

  }

}

example:

public class Generic <T> {
  public void get(T t){
       System.out.println(t);    
  }      
public static void main(String[] args){
Generic <String> generic = new Generic <String>();
generic.get("hello");
Generic <Light> genericOne = new Generic <Light>();
genericOne.get(new Light());
}
}
class Light{
}

声明范性:使用<>括号,里面写上一个范型的名称T,它仅仅是一个名称,不代表任何类型,在整个类的作用范围内都可以使用T这种范型类型。

使用泛型:声明时要明确T所代表的类型,否则编译不通过。上例声明时,一个支持了String,一个支持了Light类型,get函数的参数T也立刻变成了支持上述类型。因为Generic<T>都是在声明的时候将T替换为具体的类型。

notes:泛型就是一种不针对任何具体类型的类型,它是泛泛的类型,极度不具体的类型,所以也就没有具体的可以使用的服务。

可以看出get函数里面根本无法使用T参数中的服务,只是简单的打印。即使在运行过程中可以支持任何类型,但是在设计期却无法预知具体类型,所以使用泛型时,看到的程序通常都是针对泛型T的定义、转换、动态创建等通用代码,也正因为泛型T没有具体服务,这样的代码才非常通用,但为了达到良好的实用性,在设计上也相对复杂。

example:

泛型类型只能通过强制转型才能使用。

public class Generic <T>{
    public void get(T t){
        if(t instanceof Light){
            Light light = (Light) t;
            light.on();
        }
    }
public static void main(String[] args){
Generic <String> generic = new Generic <String>();
generic.get("hello");
Generic <Light> genericOne = new Generic <Light>();
genericOne.get(new Light());
}
}    

class Light{
public void o(){
System.out.println("light on");
}
}

 

2.泛型接口

public interface Generic <A,B>{
public A get();
}

example:

public class Client{
public void show(GenericInterface genericInterface){
System.out.println(gerericInterface.get().getClass().getName());
}

public static void main(String[] args){
Client client =  new Client();
client.show(new ConcreteObjectOne<String>("hello"));  
}
}

interface GenericInterface<T>{
T get();
}

class ConcreteObjectOne <H> implements GenericInterface <H>{
private H t;
public ConcreteObjectOne(H t){
this.t = t;  
}
public H get(){
return t;
}
}

show函数在调用过程中,接收的ConcreteObjectOne在实例化时明确了泛型类型为String,所以ConcreteObjectOne的构造函数立刻变味了以String为参数的构造函数。

 

2.泛型函数

public class Generic{
public <B> void get(B b){
} 
}

泛型函数的使用和普通的函数没有任何区别。

generic.get("hello");

generic.get(1);

generic.get(new Light());

泛型函数在使用时,感觉它是一个被无限次重载的函数,支持所有的类型。通常使用泛型的地方都可以使用接口来登记啊实现,因为接口也是一种极度抽象的、不具体的、没有任何实现的,同时也不限制类的继承关系的弱侵入性类型。

 

3.泛型的边界

由于泛型没有任何服务,如果能够基于一个接口或者类来约束它的类型,那样就可以具有一些需要的服务了。

example:

public class GenericTest<T extends Service>{
public static void main(String[] args){
GenericTest<Service> genericTest = new GenericTest<Service>();
genericTest.callService(new ConcreteService());
}

public void callService(T t){
t.print();
}
}
class ConcreteService implements Service{
public void print(){
System.out.println("print service");
}
}
interface Service {
void print();
}

通过extends关键字达到了类似继承的效果,这种语法约束了泛型的服务范围,只能是Service类型,它使泛型的通用型有了一定的限制,但是增加了可用性。

实际上,这样的代码使事情复杂化了,直接讲callService函数的参数变为接口Service,使用传统的编程方法更简单。

 example:

使用接口编程可以替换泛型边界限制

public class GenericTest{
public static void main(String[] args){
GenericTest genericTest = new GenericTest();
genericTest.callService(new ConcreteService());
}

public void callService(Service t){
t.print();
}
}

example:

多个泛型边界限制

public class GenericTest <T extends Service & ServiceInterfaceOne & ServiceInterfaceTwo>{
public static void main(String[] args){
GenericTest <ConcreteService> genericTest = new GenericTest<ConcreteService>();
genericTest.callService(new ConcreteService());
}
public void callService(T t){
t.write();
t.print();
t.show();
}
}
class ConcreteService extends Service implements ServiceInterfaceOne,ServiceInterfaceTwo{
public void write(){
System.out.println("print service");
}  
public void print(){
System.out.println("service interface one print");
}
public void show(){
System.out.println("service interface two show");
}
}
class Service{
void write(){
System.out.println("service write");
}
}
interface ServiceInterfaceOne{
void print();
}
interface ServiceInterfaceTwo{
void show();
}

通过类似继承和实现的方式限制了泛型的边界,就可以按照泛型的边界类型调用相应的函数实现具体的逻辑代码,这里的设计依然可以使用传统编程方法替换,会更直观。

 4.简单的集合类

public class CollectionTest{
public static void main(String[] args){
SimpleCollection collection = new SimpleCollection(5);
//测试自动扩展性
for(int i = 0;i < 65; i++){
collection.add("hello"+i);
}
System.out.println(collection.size());
System.out.println(collection.delete(10));
System.out.println(collection.delete(30));
System.out.println(collection.delete(40));
//测试边界
collection.add(61,"bad");
collection.add(62,"good");
//测试边界扩展性
collection.add(64,"good1");
collection.add(64,"good2");
//测试边界
collection.add("good3");
//测试边界
System.out.println(collection.delete(collection.size()-1))
//测试打印
System.out.println(collection);
//测试自动收缩性
for(int i = 0;i<30;i++){
collection.delete(0);
}
System.out.println(collection);
//测试get
System.out.println(collection.get(23));
System.out.println(collection.size());
}
}
interface Collection{
void add(Object item);
void add(int index,Object item);
Object delete(int index);
Object get(int index);
int size();
}
class SimpleCollection implements Collection{
//自动扩展的大小
private static final int AUTO_INC_SIZE = 20;
//集合容器
private Object[] array;
//集合中有效对象的数量
private int size;
//初始化制定大小容器
public SimpleCollection(int size){
array = new Object[size];
this.size = 0;
}
//默认大小容器
public SimpleCollection(){
array = new Object[AUTO_INC_SIZE];
this.size = 0;
}
//在末尾添加对象
public void add(Object item){
add(size,item);
}
//在指定位置插入对象
public void add(int index,Object item){
if(index>size)
throw new ArrayIndexOutOfBoundsException("超出索引:"+index+"最大:"+(size-1));
//有效对象数量超出容器大小,自动扩充容器
if(array.length == size){
Object[] result = new Object[array.length + AUTO_INC_SIZE];
for(int i = 0;i<= array.length;i++){
if(i<index){
result[i] = array[i];
}else if(i>index){
result[i] = array[i-1];
}
}
result[index] = item;
array = result;
}else{
//插入位置后的对象整体后移
for(int i = size;i>index;i--){
array[i] =array[i-1];
}
array[index] = item;
}
size++;
}
//删除指定位置对象
public Object delete(int inde){
if(index>size-1)
throw new ArrayIndexOutOfBoundsException("超出索引:"+index+",最大:"+(size-1));
Object delObject = null;
//无效对象过多,容器自动收缩
if(array.length-size>AUTO_INC_SIZE * 2){
Object[] result = new Object[size+ AUTO_INC_SIZE];
for(int i = 0;i<size;i++){
  if(i < index){
    result[i] = array[i];
  }
  if(i>index)
    result[i-1] = array[i];
 }
size--;
delObject = array[index];
array = result;
}
//删除位置后对象前移
if(index<size){
for(int i = index;i<size;i++){
if((i+1)<array.length)
  array[i] = array[i+1];
}
//移动后清楚末尾无用对象
array[size-1] = null;
size--;
return array[index];
}
return delObject;
}

public Object get(int index){
if(index<size){
return array[index];
}
throw new ArrayIndexOutOfBoundsException("超出索引:"+index+",最大:"+(size-1));
}

public int size(){
return size;
}

public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("[");
for(int i = 0;i<size;i++){
sb.append(array[i]);
if(i<size-1)
sb.append(",");
}
sb.append("]");
return sb.toString();
} }

这个集合是使用了最基本的数组进行实现。可以学习到数组的使用、元素的福祉和

posted @ 2015-08-14 20:49  笨笨coding  阅读(208)  评论(0)    收藏  举报