泛型接口_泛型接口自动注入对象 - CSDN
精华内容
参与话题
  • 根据《Java编程思想 (第4版)》中的描述,泛型出现的动机在于:有许多原因促成了泛型的出现,而最引人注意的一个原因,就是为了创建容器类。泛型类容器类应该算得上最具重用性的类库之一。先来看一个没有泛型的情况...

    根据《Java编程思想 (第4版)》中的描述,泛型出现的动机在于:

    有许多原因促成了泛型的出现,而最引人注意的一个原因,就是为了创建容器类

    泛型类

    容器类应该算得上最具重用性的类库之一。先来看一个没有泛型的情况下的容器类如何定义:

    public class Container {
        private String key;
        private String value;
    
        public Container(String k, String v) {
            key = k;
            value = v;
        }
        
        public String getKey() {
            return key;
        }
    
        public void setKey(String key) {
            this.key = key;
        }
    
        public String getValue() {
            return value;
        }
    
        public void setValue(String value) {
            this.value = value;
        }
    }

    Container类保存了一对key-value键值对,但是类型是定死的,也就说如果我想要创建一个键值对是String-Integer类型的,当前这个Container是做不到的,必须再自定义。那么这明显重用性就非常低。

    当然,我可以用Object来代替String,并且在Java SE5之前,我们也只能这么做,由于Object是所有类型的基类,所以可以直接转型。但是这样灵活性还是不够,因为还是指定类型了,只不过这次指定的类型层级更高而已,有没有可能不指定类型?有没有可能在运行时才知道具体的类型是什么?

    所以,就出现了泛型。

    public class Container<K, V> {
        private K key;
        private V value;
    
        public Container(K k, V v) {
            key = k;
            value = v;
        }
    
        public K getKey() {
            return key;
        }
    
        public void setKey(K key) {
            this.key = key;
        }
    
        public V getValue() {
            return value;
        }
    
        public void setValue(V value) {
            this.value = value;
        }
    }

    在编译期,是无法知道KV具体是什么类型,只有在运行时才会真正根据类型来构造和分配内存。可以看一下现在Container类对于不同类型的支持情况:

    public class Main {
    
        public static void main(String[] args) {
            Container<String, String> c1 = new Container<String, String>("name", "findingsea");
            Container<String, Integer> c2 = new Container<String, Integer>("age", 24);
            Container<Double, Double> c3 = new Container<Double, Double>(1.1, 2.2);
            System.out.println(c1.getKey() + " : " + c1.getValue());
            System.out.println(c2.getKey() + " : " + c2.getValue());
            System.out.println(c3.getKey() + " : " + c3.getValue());
        }
    }

    输出:

    name : findingsea
    age : 24
    1.1 : 2.2

    泛型接口

    在泛型接口中,生成器是一个很好的理解,看如下的生成器接口定义:

    public interface Generator<T> {
        public T next();
    }

    然后定义一个生成器类来实现这个接口:

    public class FruitGenerator implements Generator<String> {
    
        private String[] fruits = new String[]{"Apple", "Banana", "Pear"};
    
        @Override
        public String next() {
            Random rand = new Random();
            return fruits[rand.nextInt(3)];
        }
    }

    调用:

    public class Main {
    
        public static void main(String[] args) {
            FruitGenerator generator = new FruitGenerator();
            System.out.println(generator.next());
            System.out.println(generator.next());
            System.out.println(generator.next());
            System.out.println(generator.next());
        }
    }

    输出:

    Banana
    Banana
    Pear
    Banana

    泛型方法

    一个基本的原则是:无论何时,只要你能做到,你就应该尽量使用泛型方法。也就是说,如果使用泛型方法可以取代将整个类泛化,那么应该有限采用泛型方法。下面来看一个简单的泛型方法的定义:

    public class Main {
    
        public static <T> void out(T t) {
            System.out.println(t);
        }
    
        public static void main(String[] args) {
            out("findingsea");
            out(123);
            out(11.11);
            out(true);
        }
    }

    可以看到方法的参数彻底泛化了,这个过程涉及到编译器的类型推导和自动打包,也就说原来需要我们自己对类型进行的判断和处理,现在编译器帮我们做了。这样在定义方法的时候不必考虑以后到底需要处理哪些类型的参数,大大增加了编程的灵活性。

    再看一个泛型方法和可变参数的例子:

    public class Main {
    
        public static <T> void out(T... args) {
            for (T t : args) {
                System.out.println(t);
            }
        }
    
        public static void main(String[] args) {
            out("findingsea", 123, 11.11, true);
        }
    }

    输出和前一段代码相同,可以看到泛型可以和可变参数非常完美的结合。

    以上,泛型的第一部分的结束。


    from:https://segmentfault.com/a/1190000002646193

    展开全文
  • using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace InterImp {  class Program ... interface Inter //定义泛
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    namespace InterImp
    {
        class Program
        {
            interface Inter<T>  //定义泛型接口Inter
            {
                void show(T t); //约定功能show
            }
            class InterImpA : Inter<String>  //定义接口Inter的子类InterImpA,明确泛型类型为String
            {
                public void show(String t)  //子类InterImpA重写方法show,指明参数类型为String
                {
                    Console.WriteLine(t);
                }
            }
            class InterImpB<T> : Inter<T> //定义接口Inter的子类InterImpB,直接声明泛型
            {
                public void show(T t) //子类InterImpB重写方法show,参数类型为泛型
                {
                    Console.WriteLine(t);
                }
            }
            static void Main(string[] args)
            {
                InterImpA i=new InterImpA(); //实例化InterImpA
                i.show("fffff");
                InterImpB<Int32> j=new InterImpB<Int32>(); //实例化InterImpB
                j.show(666);
                Console.Read();
            }
        }
    }
    展开全文
  • 为什么要使用泛型?优点在哪里?使用java泛型的动机在编译时检测出错误。一、泛型方法可以为静态方法定义为泛型类型!1、非受限泛型:&lt;T&gt; 等价于受限泛型&lt;T extends Object&gt;public ...

    为什么要使用泛型?优点在哪里?

    使用java泛型的动机在编译时检测出错误。

    一、泛型方法

    可以为静态方法定义为泛型类型!

    1、非受限泛型:<T> 等价于受限泛型<T extends Object>

    public class GenericMethodDemo {
        public static void main(String[] args) {
        	Integer[] integers = {1,2,3,4,5,6};
        	String[] strings = {"London","Paris","New York","Austin"};
    /*    	GenericMethodDemo.<Integer>print(integers);
        	GenericMethodDemo.<String>print(strings);*/
        	//也可以换成以下形式
        	print(integers);
        	print(strings);
        }
        
        public static <E> void print(E[] list) {
        	for (int i = 0; i < list.length; i++) {
    			System.out.print(list[i] + " ");
    		}
        	System.out.println();
        }
    }

    public class Bounded {
    
    	public static void main(String[] args) {
            Integer a = new Integer(1);
            Integer b = new Integer(2);
            System.out.println(equals(a, b));
            String s1 = new String("123");
            String s2 = new String("123");
            System.out.println(equals(s1, s2));
    	}
    	
        //等价于<E>非受限泛型
    	public static <E extends Object> Boolean equals(E a,E b){
    		return a.equals(b);
    	}
    }


    2、受限泛型:<T extends GemotriObject>:将E指定为GemotriObject的子类型

    public class UnBounded {
    
    	public static void main(String[] args) {
          Rectangle rectangle = new Rectangle(3.0,4.0);
          Rectangle rectangle2 = new Rectangle(3.0, 4.0);
          Circle circle = new Circle(2.0);
          System.out.println(equalArea(rectangle, circle));
          System.out.println(equalArea(rectangle, rectangle2));
    	}
        
    	/**受限泛型*/
    	public static <E extends GeometricObject> boolean equalArea(E e1,E e2) {
    		return e1.getArea() == e2.getArea();
    	}
    } 

    其中Circle和Rectangle都是接口GeometricObject的实现类

    注意:定义一个方法为泛型类型,要将泛型类型放在方法返回类型之前

    案例:对一个对象数组进行排序

    package fanxin;
    
    
    public class GenericSort {
        public static void main(String[] args) {
        	Integer[] integers = {new Integer(2),new Integer(1),new Integer(3)};
        	Double[] doubles = {new Double(2.0),new Double(1.0),new Double(2.0)};
        	Character[] characters = {new Character('a'),new Character('c'),new Character('b')};
        	String[] strings = {"hello","you","world"};
        	
        	Sort(integers);
        	Sort(doubles);
        	Sort(characters);
        	Sort(strings);
        	
        	System.out.print("Sorted Integer objects:");
        	print(integers);
        	System.out.print("Sorted Double objects:");
        	print(doubles);
        	System.out.print("Sorted Character objects:");
        	print(characters);
        	System.out.print("Sorted String objects:");
        	print(strings);
        }
        
        /**泛型排序函数*/
        public static <E extends Comparable<E>> void Sort(E[] list) {
        	E currentMin;
        	int currentMinIndex;
        	
        	for(int i = 0; i < list.length; i++) {
        		currentMin = list[i];
        		currentMinIndex = i;
        		for(int j= i + 1; j < list.length; j++) {
        			if(currentMin.compareTo(list[j]) > 0) {
        				currentMin = list[j];
        				currentMinIndex = j;
        			}
        		}
        		
        		if(currentMinIndex != i) {
        			list[currentMinIndex] = list[i];
        			list[i] = currentMin;
        		}
        	}
        }
        
        /**打印*/
        public static void print(Object[] list) {
        	for(int i =0 ;i < list.length; i++) {
        		System.out.print(list[i] + " ");
        	}
        	System.out.println();
        }
    }
    
    
    /*输出结果
    Sorted Integer objects:1 2 3 
    Sorted Double objects:1.0 2.0 2.0 
    Sorted Character objects:a b c 
    Sorted String objects:hello world you */

    其中要求这些对象都是Comparable接口的实例!


    二、泛型类、泛型接口:

    案例:模拟栈的实现:

    package fanxin;
    
    import java.util.ArrayList;
    
    public class GenericStack<E> {
       private ArrayList<E> list = new ArrayList<>();
       
       public int getSize() {
    	   return list.size();
       }
       
       //返回栈顶元素
       public E peek() {
    	   return list.get(list.size()-1);
       }
       
       public void push(E o) { 
    	   list.add(o);
       }
       
       public E pop() {
    	   E o = list.get(list.size() - 1);
    	   list.remove(o);
    	   return o;
       }
       
       public boolean isEmpty() {
    	   return list.isEmpty();
       }
    
       @Override
       public String toString() {
    	   return "stack:"+list.toString();
       }
       
       
       public static void main(String[] args) {
    	   GenericStack<String> stack = new GenericStack<>();
    	   stack.push("joe");
    	   stack.push("hello");
    	   stack.push("world");
       }
    }

    注意:泛型类可能有多个参数时,所有参数都应放在尖括号内,并用逗号隔开<E1,E2,E3>






    展开全文
  • c#: 泛型接口、泛型方法

    千次阅读 2018-01-04 14:29:05
    泛型可以自定义泛型接口、泛型类、泛型方法、泛型事件、泛型委托。 1>自定义泛型接口 和普通接口一样,一个泛型接口通常也是与某些对象相关的约定规程。泛型接口的声明如下: interface [接口名] { [接口体] } 在c#...

    泛型可以自定义泛型接口、泛型类、泛型方法、泛型事件、泛型委托。

    1>自定义泛型接口

    和普通接口一样,一个泛型接口通常也是与某些对象相关的约定规程。泛型接口的声明如下:

    interface  [接口名]<T>

    {

    [接口体]

    }

    在c#中,通过尖括号“<>”将类型参数括起来,表示泛型。声明泛型接口时,与声明一般接口的唯一区别是增加了一个<T>。一般来说,声明泛型接口与声明非泛型接口遵循相同的规则。

    泛型接口定义完成之后,就要定义此接口的子类。定义泛型接口的子类有以下两种方法。

    (1)直接在子类后声明泛型。

    (2)在子类实现的接口中明确的给出泛型类型。

    interface Inter<T>
    {
        void show(T t);
    }
    
    //定义接口Inter的子类InterImpA,明确泛型类型为String (2)
    public class InterImpA : Inter<String>
    {
        //子类InterImpA重写方法show,指明参数类型为string
        public void show(String t)
        {
            Console.WriteLine(t);
        }
    }
    //定义接口Inter的子类InterImpB,直接声明           (1)
    public class InterImpB<T> : Inter<T>   
    {
        public void show(T t)
        {
            Console.WriteLine(t);
        }
    }
    
    static void Main(string[] args)
    {
        InterImpA i = new InterImpA();
        i.show("aaa");
    
        InterImpB<Int32> j = new InterImpB<Int32>();
        j.show(555);
        Console.Read();
    }
    运行结果:


    2>泛型函数

    i)非泛型类中的泛型方法

    public class SortHelper
    {
        public void BubbleSort<T>(T[] array) where T : IComparable
        {
            int length = array.Length;
            for (int i = 0; i <= length - 2; i++)
            {
                for (int j = length - 1; j >= 1; j--)
                {
                    //如果前面的元素较大,交换相邻两个元素
                    if (array[j].CompareTo(array[j - 1]) < 0)
                    {
                        T temp = array[j];
                        array[j] = array[j - 1];
                        array[j - 1] = temp;
                    }
                }
            }
        }
    }
    static void Main(string[] args)
    {
        SortHelper sortHper = new SortHelper();
        string[] arr = new string[3]{"A","c","b"};
        sortHper.BubbleSort<string>(arr);
        foreach(string s in arr)
        {
            Console.WriteLine(s);
        }
        Console.Read();
    }
    运行结果:


    注:因为“<”和“>”运算符只对数值类型参数有效,要比较两个泛型类型参数值的大小,不能直接用“<”和">"运算符。解决方法是约束泛型T为“where T:IComparable”,表明泛型T是继承自IComparable接口,可以使用IComparable接口的CompareTo方法比较大小。

    泛型方法的泛型参数可以用在该方法的形参,方法体,返回值三处。上述例子的泛型方法的泛型参数用在了形参处。

    ii)泛型类中的泛型方法

    非泛型类的泛型方法,泛型参数直接在方法名称后面声明;泛型类的泛型方法是在类名称后面加一个尖括号,使用这个尖括号来传递占位符(也就是类型参数),再在类中定义泛型方法。

    前面BubbleSort泛型方法也可以这样定义:

    public class SortHelper<T> where T:IComparable
    
    {
        public void BubbleSort(T[] array)
        {
            int length = array.Length;
            for (int i = 0; i <= length - 2; i++)
            {
                for (int j = length-1; j >= 1; j--)
                {
                    //如果前面的元素较大,交换相邻两个元素
                    if (array[j].CompareTo(array[j - 1]) < 0)
                    {
                        T temp = array[j];
                        array[j] = array[j-1];
                        array[j-1] = temp;
    
                    }
                }
            }
        } 
    }    
    
    
    static void Main(string[] args)
    {
        SortHelper<string> sortHper = new SortHelper<string>();
        string[] arr = new string[3]{"A","c","b"};
        sortHper.BubbleSort(arr);
        foreach(string s in arr)
        {
            Console.WriteLine(s);
        }
        Console.Read();
    }
    上述代码中,因为泛型类已经声明了泛型参数T,可以直接使用下面的语句:public void BubbleSort(T[] array)定义泛型类的泛型方法。要调用泛型类的泛型方法时,首先声明泛型类的对象,接着使用泛型类的对象调用泛型方法时与调用普通方法完全一样。

    3、泛型约束

    泛型约束是使用where关键字实现的,用来约束T到一个指定范围。

    常用约束类型

    where T:结构                   类型参数必须是值类型。可以指定除Nullable以外的任何值类型

    where T:类                       类型参数必须是引用类型,包括任何类、接口、委托或数组类型

    where T :new()                类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时,new()约束必须最后指定

    where T:<基类名>            类型参数必须是指定的基类或派生自指定的基类

    where T:<接口名称>        类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的

    public class Book : IComparable
    {
        private int id;
        private string title;
        public Book()
        {
    
        }
        public Book(int id, string title)
        {
            this.id = id;
            this.title = title;
        }
        public int ID
        {
            get { return id; }
            set { id = value; }
        }
        public string Title
        {
            get { return title; }
            set { title = value; }
        }
        public int CompareTo(object obj)
        {
            Book book = (Book)obj;
            return this.ID.CompareTo(book.ID);
        }
    }
    
    public class SortHelper<T> where T : IComparable
    {
        public void BubbleSort(T[] array)
        {
            int length = array.Length;
            for (int i = 0; i <= length - 2; i++)
            {
                for (int j = length - 1; j >= 1; j--)
                {
                    //如果前面的元素较大,交换相邻两个元素
                    if (array[j].CompareTo(array[j - 1]) < 0)
                    {
                        T temp = array[j];
                        array[j] = array[j - 1];
                        array[j - 1] = temp;
    
                    }
                }
            }
        }
    }
    static void Main(string[] args)
    {
        Book[] bookArr = new Book[2];
    
        Book book1 = new Book(1, "语文");
        Book book2 = new Book(2,"数学");
    
        bookArr[0] = book1;
        bookArr[1] = book2;
    
        SortHelper<Book> Sort = new SortHelper<Book>();
    
        Sort.BubbleSort(bookArr);
        foreach (Book b in bookArr)
        {
            Console.WriteLine("ID={0},Title={1}",b.ID,b.Title);
        }
        Console.Read();
    }
    在比较复杂类型对象Book,book1和book2到底谁大,这涉及一个判断依据的问题。如何来实现这种复杂类型对象的比较呢?答案是:让需要进行比较的对象类实现IComparable接口。也就是说,只有实现了IComparable接口的类型才能作为类型参数被传入,即需要对传入参数的类型进行一些约定,这就是要讲的泛型约束。

    c#泛型要求对“任何泛型类型或泛型方法的类型参数”的任何假定,都要基于“显式约束”,以维护c#所要求的类型安全。“显式约束”有where字句表达,可以指定”基类约束”,“接口约束”,“构造器约束”,“值类型/引用类型约束”共4种约束。“显式约束”并非必需,如果没有指定“显式约束”,泛型类型参数只能访问System.Object类型中的公有方法。



    展开全文
  • java泛型接口

    千次阅读 2018-06-17 12:22:50
    java泛型接口 泛型接口 格式: 访问权限 interface 接口名&amp;lt;泛型标示&amp;gt;{} interface Info&amp;lt;T&amp;gt;{ public T getValue(); } class InfoImpl implements Info { ...
  • 泛型接口的实现

    千次阅读 2019-02-24 18:57:38
    泛型接口的实现过程 package cn.itcast.p4.generic.define.demo; public class GenericDefineDemo5 { /** * @param args */ public static void main(String[] args) { InterImpl in = new InterImpl()...
  • 泛型接口中的使用

    千次阅读 2019-06-24 16:58:32
    * 当接口使用泛型,我们创建实现类的时候,可以直接确定数据类型,也可以实现类继续使用泛型*/ public class Demo01 { public static void main(String[] args) { Interface01impl in1 = new Interface01i...
  • 泛型接口的定义 package cn.itcast_06; /* *泛型接口:把泛型定义在接口上 */ public interface Interface <T>{ public abstract void show(T t); } 泛型接口的使用 package cn.itcast_06; /* * 实现类...
  • 一、泛型类   定义Person类 package cn.itcast.p2.bean; public class Person implements Comparable&lt;Person&gt; { private String name; private int age; public Person() { super(); ...
  • Java 泛型方法/接口泛型限定

    万次阅读 多人点赞 2020-08-26 20:43:32
    文章目录
  • 泛型允许我们使用类型参数Type parameter,它用一个自定义的标识符(T、V、E)来代表一个类型,用括住,放在类名后面。然后在类定义中所有使用该类型的地方都用这个标识符来代替,因为在定义这个类的时候还不知道这个...
  • Java泛型接口的定义

    千次阅读 2019-06-22 19:41:23
    接口也可以定义泛型,语法如下: [public] interface接口名<T> 二代码 public class GeneralInterface { public static void main( String[] args ) { System.out.println(new TestIBase().getA()); } ...
  • 泛型接口的实现方式一:在子类的定义上声明泛型类型
  • Java 中泛型

    万次阅读 2015-11-01 11:23:56
    个人 对泛型的理解 ,其实泛型 就是为了通用编程。就像 平时我们预先定义的接口一样 (接口 只不过是推迟方法...1,泛型 包裹 (泛型类,泛型方法 ,泛型接口) 泛型 类 形如 public class Test {} 这就是一个泛型类
  • * 在接口中定义泛型 * */ public interface Ieat { public void eat(T t); } class MyIeat implements Ieat{ public MyIeat(){ } @Override public void eat(String t) { System.out.println(t);
  • 泛型的抽象继承与接口实现注意点

    千次阅读 2017-07-04 17:29:49
    * 父类为泛型类 * 1.属性 * 2.方法 * 要么同时擦除,要么子类大于等于父类的类型 * 不能子类擦除,父类泛型 * 继承有两种,子类为泛型或子类不为泛型 * 子类不为泛型则具体定义T,T1 * * 属性类型: * ...
  • 前言:在向上抽取功能时可能会有需要获取到实现接口的实际泛型参数类型这样的需求,分享一下自己实现的方法。 一、Java 代码 直接上代码,代码上有注释,对API做了相应的解释。 public BasicAction(){ try { ...
  • 泛型方法和泛型参数

    万次阅读 2018-03-19 21:04:00
    最早接触泛型应该是在Java各种容器上面,这样写的好处是避免取值时类型转换出错的可能性,而且指定泛型后get也不需要手动强转。 List&lt;Integer&gt; list = new ArrayList&lt;Integer&gt;(); ...
  • 痛点: 使用Mybatis框架的时候,想封装一个底层JDBC控制器,用于提供和Mybatis交互的增删改查接口(公用的接口),但由于公用的查询方法可能是用户自定义的任意一个和表对应的java bean类型,所以要考虑怎么样给调用...
  • 泛型示例三:public class TPractice&lt;T extends Calendar &amp; SolarTerms &amp; Festival&gt; { // 限制 T类型为继承Calendar 类,并实现SolarTerms、Festival 接口的类类型 private T obj; ...
1 2 3 4 5 ... 20
收藏数 154,950
精华内容 61,980
关键字:

泛型接口