< >内是自定义名称
在以前的学习中,对共性抽取的方法:
package com.vv.generic.define.demo;
import com.vv.bean.Person;
/*
* 用工具类对Perosn进行设置和获取
* 但如果想使用工具类同时对Student对象也进行设置和获取
* 就需要创建另一个工具类吗?
* 不,应该学会抽取其共性
* 即Object,
* */
public class Tool {
private Object object;
public Object getObject(){
return object;
}
public void setObject(Object object){
this.object = object;
}
/*
private Person person;
public Person getPerson(){
return person;
}
public void setPerson(Person person){
this.person = person;
}
*/
}
但在测试类中如果出现错误设置对象,则只会在运行后报错
package com.vv.generic.define.demo;
import com.vv.bean.Student;
public class GenericDefineDemo {
public static void main(String[] args) {
Tool tool = new Tool();
tool.setObject(new Worker());
Student stu = (Student) tool.getObject();
}
}
为避免上述错误的出现,在对对象的共性进行抽取的同时,我们采用泛型类,就会避免此类情况的发生,即在编译时就会提示我们有错,上述代码改进如下:
即泛型类:
package com.vv.generic.define.demo;
import com.vv.bean.Person;
public class Tool<People>{
private People people;
public People getPeople(){
return people;
}
public void setPeople(People people){
this.people = people;
}
}
而在编译时就会提示错误:
package com.vv.generic.define.demo;
import com.vv.bean.Student;
public class GenericDefineDemo {
public static void main(String[] args) {
Tool<Student> tool = new Tool<Student>();
//The method setPeople(Student) in the type Tool<Student> is not applicable for the arguments (Worker)即无法将Worker转化成Student
tool.setPeople(new Worker());
Student stu = tool.getPeople();
}
}
当泛型定义在方法上时的使用:
即如下的show和print方法中:
package com.vv.generic.define.demo;
import com.vv.bean.Person;
public class Tool<People>{
private People people;
public People getPeople(){
return people;
}
public void setPeople(People people){
this.people = people;
}
public void show(String str){
System.out.println("show:" + str);
}
public void print(People str){
System.out.println("print:"+str);
}
}
测试类在进行使用时,当输出的类型不同时,会出现编译错误:
错误出现在show方法处,是因为泛型已经定义为String类型,即无法输出int类型
package com.vv.generic.define.demo;
import com.vv.bean.Student;
public class GenericDemo4 {
public static void main(String[] args) {
Tool<String> tool = new Tool<String>();
tool.show("aa");
tool.show(2);
tool.print("sd");
}
}
故将调用的方法进行改进,改进如下:
泛型方法:定义在返回值前,修饰符后
将泛型定义在方法上:
public <F>void show(F str){
System.out.println("show:" + str);
}
则再次编译时,可以正常运行
注意:当方法是静态时,不能访问类上定义的泛型,如果静态方法使用泛型,只能将泛型定义在方法上。因为静态是不需要对象的
public static <S>void method(S obj){
System.out.println(obj);
}
同时在测试类进行调用时,类名.方法:
Tool.method("as");
注意:泛型中是无法打印字符串长度的,因为一旦使用泛型,是无法使用具体类型的方法,只能使用Object的方法。
泛型接口:将泛型定义在接口上
类实现接口时,明确类型
package com.vv.generic.define.demo;
public class GenericDemo5 {
public static void main(String[] args) {
InterImpl inter = new InterImpl();
inter.show("sa");
}
}
interface Inter<T> {
public void show(T t);
}
class InterImpl implements Inter<String> {
@Override
public void show(String t) {
System.out.println(t);
}
}
类实现接口时接收的类型不明确,在创建对象时才明确
package com.vv.generic.define.demo;
public class GenericDemo5 {
public static void main(String[] args) {
InterImpl2<String> inter = new InterImpl2<String>();
inter.show("sa");
}
}
interface Inter<T> {
public void show(T t);
}
class InterImpl2<Q> implements Inter<Q> {
@Override
public void show(Q q) {
System.out.println(q);
}
}
网友评论