您的位置:首页 > 编程语言 > Java开发

JAVA学习笔记36——泛型2:泛型继承、擦除+泛型接口+泛型无多态、通配符

2015-02-08 19:52 459 查看
最近在看JAVA教学的视频,觉得老师讲的很好,同时借用源代码还有笔记来撰写本系列博客,记录自己的学习内容,同时也供看到的人学习。

关于泛型的知识点除了简介之外,本篇以及下一篇一共介绍6点,本篇介绍前3点:

NO.1:泛型的继承、擦除,先来看一下相关概念:



/**
*泛型的擦除
*1、继承||实现声明 不指定类型
*2、使用时 不指定类型
*统一Object 对待
*1、编译器警告 消除使用Object
*2、不完全等同于Object ,编译不会类型检查
* @author Administrator
*
* @param <T>
*/
public class Student<T> {
private T javaScore;
private T oracleScore;
//泛型声明时不能使用 静态属性|静态方法上
//private static T1 test;
public T getJavaScore() {
return javaScore;
}
public void setJavaScore(T javaScore) {
this.javaScore = javaScore;
}
public T getOracleScore() {
return oracleScore;
}
public void setOracleScore(T oracleScore) {
this.oracleScore = oracleScore;
}
public static void main(String[] args) {
Student stu1 = new Student();
//消除警告 使用 Object
Student<Object> stu = new Student<Object>();
//stu.setJavaScore("af"); //以Object对待

test(stu1); //stu1 相当于Object 但是不完全等同Object
//擦除,不会类型检查
//test(stu);
test1(stu1);
test1(stu);
}
public static  void test(Student<Integer> a){
}
public static  void test1(Student<?> a){
}
}


泛型继承有四种可行的情况以及一种不可行情况,具体体现在下述代码中:

/**
* 父类为泛型类
* 1、属性
* 2、方法
* ******要么同时擦除,要么子类大于等于父类的类型********
* 不能子类擦除,父类泛型
* 1、属性类型由什么决定:
*  父类中,随父类而定
*  子类中,随子类而定
* 2、方法重写由什么决定:
*  随父类而定
* @param <T>
*/
public abstract class Father<T,T1> {
T name;
public abstract void test(T t);
}
/**
* 第一种可行情况:子类声明时指定具体类型
* 属性类型为具体类型
* 方法同理
*/
class Child1 extends Father<String,Integer>{
String t2;
@Override
public void test(String t) {
}
}
/**
*第二种可行情况: 子类为泛型类 ,类型在使用时确定
*/
class Child2<T1,T,T3> extends Father<T,T1>{
T1 t2;
@Override
public void test(T t) {
}
}
/**
* 第三种可行情况:子类为泛型类,父类不指定类型 ,泛型的擦除,使用Object替换
*/
class Child3<T1,T2> extends Father{
T1 name2;
@Override
public void test(Object t) {
// TODO Auto-generated method stub
}
}
/**
* 第四种可行情况:子类与父类同时擦除
*/
class Child4 extends Father{
String name;
@Override
public void test(Object t) {
}
}
/**
*错误情况:子类擦除(子类不能擦除),父类使用泛型
class Child5 extends Father<T,T1>{
String name;
@Override
public void test(T t) {
}
*/
NO.2:泛型的接口:



看一个示例代码:

/**
* 泛型接口:与继承同理
* 重写方法随父类而定
* @param <T>
*/
public interface Comparable<T> {
void compare(T t);
}
//声明子类指定具体类型
class Comp implements Comparable<Integer>{
public void compare(Integer t) {
}
}
//擦除
class Comp1 implements Comparable{
public void compare(Object t) {
// TODO Auto-generated method stub
}
}
//父类擦除,子类泛型
class Comp2<T> implements Comparable{
@Override
public void compare(Object t) {
}
}
//子类泛型>=父类泛型
class Comp3<T> implements Comparable<T>{
@Override
public void compare(T t) {
}
}
//父类泛型,子类擦除 错误
NO.3:泛型无多态、通配符:

我们先来看一个正常的多态的例子:

public class Fruit {
}
class Apple extends Fruit{
}
/**
* 多态的两种形式
* @author Administrator
*/
public class FruitApp {
/**
* @param args
*/
public static void main(String[] args) {
Fruit f =new Apple();
test(new Apple());
}
//形参使用多态
public static void test(Fruit f){
}
//返回类型使用多态
public static Fruit  test2(){
return new Apple();
}
}
那么既然泛型下面不允许使用多态,那么如果我们想实现多态的功能该怎么办呢?那就是使用通配符:



示例代码:

/**
* 通配符
* ?类型不定,使用时确定类型
* ?使用:声明类型|声明方法上,不能声明类或使用时
* ? extends : <= 上限  指定类型 子类或自身
* ? super :>=下限   指定类型 为自身或父类
* @author Administrator
*
*/
public class Student<T> {
T score;
public static void main(String[] args) {
Student<?> stu = new Student<String>();
test(new Student<Integer>());

test2(new Student<Apple>());
//test3(new Student<Apple>()); //泛型没有多态

//test4(new Student<Apple>()); //<
stu  = new Student<Fruit>();;
//test4(stu); //使用时确定类型
test4(new Student<Object>());
test4(new Student<Fruit>());

}
public static void test(Student<?> stu){

}
public static void test3(Student<Fruit> stu){

}
// <=
public static void test2(Student<? extends Fruit> stu){

}
//>=
public static void test4(Student<? super Fruit> stu){

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐