版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1/1泛型类型系统表达能力第一部分类型变量与协变、逆变 2第二部分类型推断与模式匹配 4第三部分泛型边界与类型安全 7第四部分泛型方法与类型约束 10第五部分多态实现与类型擦除 14第六部分存在性类型与类型转换 16第七部分类型族与归纳定义 19第八部分高阶类型与能力提升 23
第一部分类型变量与协变、逆变关键词关键要点【类型变量与协变】
1.协变类型变量允许类型在子类中被扩展。例如,如果一个列表`List<A>`具有超类型`List<B>`,其中`B`是`A`的子类,那么`List<B>`可以安全地分配给`List<A>`。
2.协变性确保了子类的对象可以作为超类的对象使用,而无需进行显式转换。
3.在实际应用中,协变性用于编写可重用代码,该代码可以处理不同类型的对象。例如,一个算法可以操作`List<Integer>`或`List<Double>`,而无需对具体类型进行硬编码。
【类型变量与逆变】
类型变量与协变、逆变
在泛型类型系统中,类型变量是一种特殊的类型参数,它用于表示一种未知的类型,并在泛型类、接口或方法的定义中进行使用。类型变量的使用提供了极大的灵活性,允许编写可重用的代码,适用于各种不同的类型。
协变和逆变
协变和逆变是泛型类型变量的两个重要概念。它们描述了类型变量在继承中的行为方式。
协变类型变量
协变类型变量表示一个类型,其子类型也是该类型的子类型。这意味着,如果一个类或接口使用了一个协变类型变量,那么该类型的任何子类或接口也可以使用该类型变量,而无需进行任何修改。
反之,如果一个父类使用了一个协变类型变量,那么它的所有子类也都可以使用该类型变量。
逆变类型变量
逆变类型变量表示一个类型,其超类型也是该类型的超类型。这意味着,如果一个类或接口使用了一个逆变类型变量,那么该类型的任何超类或接口都可以使用该类型变量,而无需进行任何修改。
反之,如果一个父类使用了一个逆变类型变量,那么它的所有子类都无法使用该类型变量。
协变与逆变的示例
下面是一个协变类型变量的示例:
```
privateTvalue;
returnvalue;
}
this.value=value;
}
}
```
在这个示例中,`T`是一个协变类型变量,表示一个可以存储任何类型的值的容器。因此,我们可以使用`Container`类来存储任何类型的值,而无需对类进行修改。
下面是一个逆变类型变量的示例:
```
intcompare(To1,To2);
}
```
在这个示例中,`T`是一个逆变类型变量,表示一个可以比较两个相同类型的对象的比较器。因此,我们可以使用`Comparator`接口来比较任何类型的对象,而无需对接口进行修改。
协变与逆变的限制
虽然协变和逆变提供了极大的灵活性,但它们也需要遵循某些规则。
*协变类型变量只能出现在输出位置。例如,它们可以出现在返回类型或方法参数列表中。
*逆变类型变量只能出现在输入位置。例如,它们可以出现在方法参数列表中。
*协变和逆变类型变量不能同时出现在同一个位置。
这些规则确保了类型系统的安全性和健壮性。
结论
类型变量与协变、逆变是泛型类型系统的重要组成部分。它们提供了极大的灵活性,允许编写可重用的代码,适用于各种不同的类型。理解协变和逆变的概念對於有效使用泛型类型变量至關重要。第二部分类型推断与模式匹配类型推断与模式匹配
#类型推断
泛型类型系统中的类型推断是指编译器或解释器能够自动推断类型参数或本地变量类型的过程。这通过分析表达式中的类型信息来实现,可以节省显式声明类型参数或变量类型的需要。
例如,在Java泛型中,编译器可以从方法调用中推断类型参数:
```java
List<String>names=newArrayList<>();
names.add("Alice");//编译器推断类型参数为String
```
#模式匹配
泛型类型系统中的模式匹配是一种机制,允许开发者将类型检查与数据提取相结合。模式匹配表达式将值与预定义的模式进行匹配,模式通常包含类型信息和值限制。如果匹配成功,则可以提取与模式匹配的数据。
例如,在Scala泛型中,模式匹配可用于从Option类型中提取值:
```scala
valmaybeName:Option[String]=Some("Alice")
caseSome(name)=>//模式匹配成功,提取name
caseNone=>//模式匹配失败
}
```
#类型推断与模式匹配的结合
类型推断和模式匹配的结合在泛型类型系统中非常有用,因为它允许开发者在代码中编写更简洁且更具表现力的类型检查和数据提取。
例如,在Haskell泛型中,类型推断和模式匹配可以结合使用来定义基于类型的信息提取函数:
```haskell
head::[a]->a
head(x:_)=x
```
此函数使用模式匹配确定列表是否为空,如果是则引发错误,否则则提取列表的第一个元素。
类型推断与模式匹配的优势
#更简明的代码
类型推断和模式匹配可以消除显式类型声明的需要,从而使代码更加简洁。开发者不必重复指定类型信息,从而减少代码冗余。
#更具表现力的类型检查
模式匹配允许开发者指定复杂的类型检查,这些检查无法通过传统类型检查机制实现。它使开发者能够检查值是否符合特定模式,并提取与模式匹配的数据。
#更好的错误报告
当类型推断和模式匹配失败时,编译器或解释器可以提供更详细的错误消息。这些消息指出类型不匹配的原因和位置,从而帮助开发者更快地调试代码。
#改进的代码重用
类型推断和模式匹配促进代码重用,因为开发者可以编写通用函数和数据结构,这些函数和数据结构可以处理不同类型的参数和值。
结论
类型推断和模式匹配是泛型类型系统中的强大工具。它们结合在一起,使开发者能够编写简洁、类型安全且具有表现力的代码。通过消除显式类型声明的需要、提供更具表现力的类型检查、改进错误报告和促进代码重用,这些机制极大地提高了代码的可读性、可维护性和可重用性。第三部分泛型边界与类型安全关键词关键要点类型变量边界
1.类型变量的边界指定了一个类型变量允许的类型范围。
2.上界边界确保类型变量只能接受与其上界兼容的类型。
3.下界边界确保类型变量只能接受与其下界兼容的类型。
类型参数化
1.类型参数化允许创建可以接受不同类型参数的泛型类型。
2.类型参数化提供了代码重用和灵活性,减少了重复代码的需要。
3.类型参数化还可以通过接收类型参数并将其用作其自身类型的组成部分来实现自类型化。
类型擦除
1.类型擦除是在编译时从泛型代码中移除类型信息的过程。
2.类型擦除简化了字节码并提高了代码执行效率。
3.类型擦除的缺点是它会丢失在编译时无法推断的类型信息。
类型通配符
1.类型通配符表示未知类型,允许泛型方法和类接受任意类型参数。
2.上限通配符(?)允许方法或类接受其上界兼容的类型。
3.下限通配符(super)允许方法或类接受其下界兼容的类型。
类型推断
1.类型推断是编译器根据上下文的推断类型变量或类型参数的实际类型。
2.类型推断可以减轻开发人员的负担并提高代码的可读性。
3.类型推断机制因语言而异,其准确性和可靠性取决于语言的类型系统。
类型继承
1.类型继承允许泛型类型继承其他泛型类型的类型参数。
2.类型继承提供了代码重用,允许创建具有更具体类型参数的子类型。
3.类型继承还可以用于实现多态行为,允许方法或类接受具有共同基类型的不同类型参数。泛型边界与类型安全
泛型边界是泛型类型的关键特性,用于确保类型安全和限制泛型类型实例化的范围。
类型擦除与类型安全
Java等静态类型语言在编译时对类型进行检查,而泛型类型在编译后经过类型擦除过程,泛型类型信息将被删除。这导致在运行时无法区分不同类型的泛型实例,而如果不使用泛型边界,可能会导致类型安全问题。
泛型边界类型
泛型边界可以指定泛型类型参数的约束条件,确保泛型类型实例化时遵循特定类型要求。泛型边界类型可以是:
*接口边界:指定泛型类型参数必须实现指定的接口。
*类边界:指定泛型类型参数必须是指定类的子类或该类本身。
*多个边界:可以指定多个边界,泛型类型参数必须同时满足所有边界要求。
泛型边界的作用
泛型边界通过以下方式确保类型安全:
*约束实例化:限制泛型类型实例化范围,确保只实例化为满足边界要求的类型。
*类型推断:根据边界类型推断泛型类型参数的实际类型,增强代码可读性和可维护性。
*防止类型转换异常:在进行类型转换时,边界类型确保转换是安全有效的,防止ClassCastException异常。
*增强代码可读性:边界类型清晰地表达了泛型类型的预期用途和约束条件,提高代码可理解性。
泛型边界示例
以下示例展示了泛型边界的使用:
```java
//...操作列表的方法...
}
MyList<ArrayList>myList=newMyList<>();//合法,ArrayList实现List接口
MyList<String>myList2=newMyList<>();//非法,String不实现List接口
```
在这个示例中,泛型类型参数`T`定义了一个边界类型`List`,这意味着`MyList`只能实例化为实现`List`接口的类型。
高级泛型边界
除了基本的边界类型外,Java还支持高级泛型边界,包括:
*通配符边界:使用通配符(*)指定泛型类型参数可以是任何类型。
*类型变量边界:使用类型变量作为泛型类型参数的边界类型。
*泛型方法边界:指定泛型方法参数或返回值的泛型类型边界。
结论
泛型边界是泛型类型系统中至关重要的机制,通过约束泛型类型实例化的范围来确保类型安全。通过指定接口、类或其他类型边界,泛型边界确保了泛型类型的安全使用,提高了代码的可读性和可维护性。第四部分泛型方法与类型约束关键词关键要点【泛型方法与类型约束】:
1.泛型方法允许定义具有类型变量的方法,这些变量可以表示任何类型。
2.类型约束用于指定类型变量的类型限制,以确保方法的行为的正确性和健壮性。
3.类型参数化方法提供代码重用和灵活性,因为它们可以用于各种类型而不必重写代码。
【类型通配符】:
泛型方法与类型约束
泛型方法
泛型方法允许将方法的行为参数化,使其能够适用于不同类型的参数数据。泛型方法使用尖括号<>来指定类型参数,这些参数可以在方法内部用于类型检查和操作。
例如,以下C#代码展示了一个泛型方法`Swap<T>`,它交换两个同类型值的顺序:
```csharp
publicstaticvoidSwap<T>(refTa,refTb)
Ttemp=a;
a=b;
b=temp;
}
```
类型约束
类型约束用于指定泛型类型参数的限制。约束可以确保类型参数满足某些要求,例如它是某个基类的派生类,或者它实现了某个接口。
类型约束使用where子句来指定,它紧跟在类型参数声明之后。where子句中可以包含一个或多个约束条件,由逗号分隔。
例如,以下Java代码展示了一个泛型类`BoundedBox<T>`,其中类型参数`T`被约束为实现`Comparable<T>`接口的类:
```java
privateTvalue;
//...
}
```
类型约束类型
类型约束可以是以下类型的之一:
*类约束:指定类型参数必须派生自指定的基类。例如:`whereT:BaseClass`。
*接口约束:指定类型参数必须实现指定的接口。例如:`whereT:IComparable<T>`。
*构造函数约束:指定类型参数必须具有一个具有特定参数类型的构造函数。例如:`whereT:new()`。
*委托约束:指定类型参数必须是一个委托类型。例如:`whereT:Delegate`。
约束的优点
类型约束提供以下优点:
*增强类型安全:确保泛型代码仅适用于满足指定约束的类型。
*提高可读性和可维护性:通过明确指定类型约束,使泛型代码更容易理解和修改。
*允许更通用的代码:约束允许泛型代码在更广泛的类型范围内工作,从而提高代码的可重用性。
约束的示例
以下是一些类型约束示例:
*`whereT:class`:类型参数`T`必须为引用类型(类或接口)。
*`whereT:struct`:类型参数`T`必须为值类型(结构体)。
*`whereT:new()`:类型参数`T`必须具有无参构造函数。
*`whereT:IComparable<T>`:类型参数`T`必须实现`IComparable<T>`接口。
*`whereT:delegate()`:类型参数`T`必须是一个委托类型。
泛型方法与类型约束的结合
泛型方法和类型约束通常结合使用,以创建适用于特定类型参数的通用方法。例如,以下C#代码展示了一个泛型方法`Max<T>`,它返回两个具有类型参数`T`的值中的较大值,并使用了`whereT:IComparable<T>`约束:
```csharp
publicstaticTMax<T>(Ta,Tb)whereT:IComparable<T>
if(a.CompareTo(b)>0)
returna;
else
returnb;
}
```
结论
泛型方法和类型约束是泛型类型系统中强大的工具,它们允许编写适用于广泛类型范围的通用代码。类型约束确保了类型安全并提高了代码的可读性和可维护性。通过结合使用泛型方法和类型约束,可以创建健壮且可重用的代码。第五部分多态实现与类型擦除关键词关键要点【多态实现】
1.多态性意味着对象可以响应相同的操作调用,但具有不同的行为,具体取决于对象的类型。
2.Java使用动态绑定和虚方法表来实现多态性,允许在运行时确定调用哪个方法。
3.多态性提供了代码的灵活性和可扩展性,使对象能够在不修改代码的情况下与不同的类型交互。
【类型擦除】
多态实现与类型擦除
在泛型类型系统中,多态实现是通过类型擦除技术实现的。类型擦除是一种编译时技术,它将泛型类型信息从编译后代码中移除,从而使代码对所有类型参数都具有相同的行为。
类型擦除的原理
类型擦除通过创建泛型类型的“rawtype”来工作。rawtype是泛型类型在类型擦除后剩余的部分,它只保留类型名称和方法签名,而删除了所有类型参数。例如,对于泛型类`List<T>`,其rawtype为`List`。
当泛型代码被编译时,编译器会生成一个rawtype的版本。对于任何特定类型参数实例化,都会创建一个该rawtype的特定实例。例如,对于代码`List<String>list=newArrayList<String>();`,编译器会生成`Listlist=newArrayList();`。
类型擦除的优点
类型擦除为泛型类型系统提供了以下优点:
*运行时效率:通过移除类型信息,类型擦除可以节省运行时内存和计算资源,因为它不需要存储或检查类型参数。
*代码简洁:类型擦除使代码更加简洁,因为类型参数不必明确指定。
*向下兼容性:类型擦除允许不同版本的代码使用相同的泛型库,即使这些版本的类型系统不同。
类型擦除的缺点
尽管有这些优点,类型擦除也有一些缺点:
*潜在的类型安全性问题:类型擦除可能会导致类型安全性问题,例如类型转换错误或不安全的操作。
*调试难度增加:类型擦除可以使调试变得更加困难,因为类型信息在运行时不可用。
*有限的多态表达式:类型擦除限制了多态表达式,因为它只能在编译时进行类型推断。
替代方案
为了解决类型擦除的一些缺点,一些语言(如Scala和F#)采用了替代方案,例如类型别名和类型推导。这些技术允许在编译时保留类型信息,同时保持高效性和简洁性。
总结
类型擦除是一种编译时技术,它通过创建泛型类型的rawtype来实现多态实现。它提供了运行时效率、代码简洁性和向下兼容性的优点,但也有潜在的类型安全性问题、调试难度增加和多态表达式限制的缺点。替代方案,如类型别名和类型推导,可以解决一些这些缺点。第六部分存在性类型与类型转换关键词关键要点存在性类型
1.存在性类型表示一个非空的对象,但具体类型未知。
2.泛型类型系统中,存在性类型允许构造新的类型,这些类型从现有类型抽象出共享的特性。
3.在编译时,存在性类型可以帮助消除冗余代码并提高程序效率。
类型转换
存在性类型与类型转换
#存在性类型
存在性类型表示具有未知具体类型的对象。它使用类型变量表示未知类型,类型变量本身没有特定约束。存在性类型的语法通常表示为:
```
∃X.T
```
其中:
*`∃`是存在量词
*`X`是类型变量
*`T`是包含类型变量`X`的类型表达式
示例:
```
∃X.List[X]
```
该类型表示一个列表,其中元素类型是未知的。
#类型转换
存在性类型可以通过类型转换来从一个类型转换为另一个类型。类型转换将对象从一种类型转换为另一种类型,同时遵循类型系统规则。在存在性类型的情况下,类型转换涉及将未知类型的对象转换为具有已知类型的对象。
语法:
```
T1=T2
```
其中:
*`T1`是转换后的类型
*`T2`是转换前的类型
示例:
```
∃X.List[X]=List[int]
```
该转换将具有未知类型元素的列表转换为整数列表。
#存在性类型与类型转换的表达式能力
存在性类型和类型转换扩展了类型系统的表达能力,原因如下:
*允许动态类型化:存在性类型允许在编译时未知的对象,从而实现动态类型化的某些方面。
*支持参数化类型:类型转换允许使用参数化类型,其中类型参数可以是存在性类型。
*实现类型推断:存在性类型和类型转换可用于从代码中推断类型,从而简化开发。
*提高代码的可重用性:通过允许转换具有未知类型的对象,代码可以更轻松地重用于不同类型的数据。
*处理异构数据:存在性类型和类型转换允许处理具有不同类型的异构数据,从而扩展了程序的灵活性。
#存在性类型与类型转换的应用
存在性类型和类型转换在各种场景中都有应用:
*泛型编程:在泛型编程中,存在性类型和类型转换允许在不知道具体类型的情况下操作参数化类型。
*数据转换:类型转换允许将对象从一种类型转换为另一种类型,从而实现数据转换。
*类型推断:存在性类型和类型转换可用于从代码中推断类型,从而简化开发。
*实现多态性:存在性类型和类型转换允许通过将对象视为具有不同类型来实现多态性。
*处理异构数据:存在性类型和类型转换允许处理具有不同类型的异构数据,从而扩展了程序的灵活性。
#限制和注意事项
虽然存在性类型和类型转换提供了增强表达能力,但需要注意一些限制和注意事项:
*类型安全性:存在性类型可能会削弱类型安全性,因为它们允许在运行时转换对象类型。
*效率:类型转换可能会引入运行时开销,需要仔细考虑。
*复杂性:存在性类型和类型转换的语义可能复杂,需要对类型系统有深入的了解。
结论
存在性类型和类型转换是扩展类型系统表达能力的重要特征。它们允许动态类型化、参数化类型、类型推断和异构数据处理。然而,在使用这些特性时,必须考虑其限制和注意事项,以确保类型安全性和效率。第七部分类型族与归纳定义关键词关键要点【类型族与集合】:
1.类型族的数学基础是由家族(family)概念自然推广而来的,一个家族是一个索引集合上的一个映射,它对应于一个类型族,而索引集合对应于这个类型族的参数空间。
2.类型族是将类型作为对象的参数化概念,它允许我们定义类型构造,这些构造可以通过不同的类型参数实例化,从而生成新的类型。
3.集合类型族提供了一种表达集合的概念,它定义了集合的成员类型,并允许我们定义集合的操作,如成员资格、并集、交集和差集。
【类型族与归纳】:
类型族与归纳定义
在泛型类型系统中,类型族和归纳定义是两个强大的机制,可以用于表示复杂的类型结构和递归类型。
#类型族
类型族是一种参数化类型,允许我们为一组类型定义一个统一的接口。它可以用一个类型变量(类型参数)来表示,其值是一个类型。
例如,我们可以定义一个类型族`List`,表示不同类型元素的列表:
```
typeList<T>=
|Nil
|Cons(T,List<T>)
```
这里,`T`是类型参数,`List<T>`表示类型为`T`的列表。
类型族可以用来表示各种类型的集合,例如:
*`Maybe`:表示具有`Just`或`Nothing`值的可选值。
*`Either`:表示具有两个可能的类型中的一个值的并集类型。
*`Tuple`:表示具有固定数量元素的有序组。
*`Vector`:表示可变长度元素序列。
#归纳定义
归纳定义允许我们定义递归类型,即其构造函数引用其自身类型。归纳定义通过一系列构造函数来定义类型,每个构造函数都表示该类型的不同状态或变体。
例如,我们可以定义一个归纳类型`BinTree`,表示二叉树:
```
inductiveBinTree<T>=
|Leaf(T)
|Node(BinTree<T>,T,BinTree<T>)
```
这里的`BinTree<T>`是归纳类型,`Leaf`和`Node`是其构造函数。`Leaf`构造函数表示一个叶节点,其中包含一个`T`类型的值。`Node`构造函数表示一个内部节点,其中包含一个左子树、一个`T`类型的值和一个右子树。
归纳定义可以用来表示各种递归类型,例如:
*链表
*树
*图
*算术表达式
*正则表达式
#类型族和归纳定义的结合
类型族和归纳定义可以结合使用,以表示更加复杂和可表达的类型结构。例如,我们可以定义一个类型族`Map<K,V>`,表示从键`K`到值`V`的映射,并使用归纳定义来表示映射中不同类型的键值对:
```
typeMap<K,V>=
|Empty
|Insert(K,V,Map<K,V>)
```
这种结合允许我们表示具有动态数量和类型的键值对的映射,从而实现了强大的类型安全集合。
#类型族的表达能力
类型族的表达能力非常强大,因为它允许我们定义任意数量和类型的类型参数。这使得我们能够表示比传统泛型类型(例如Java中的泛型)更复杂和灵活的类型结构。
例如,我们可以使用类型族来表示:
*具有任意数量类型参数的多态函数。
*具有动态数量和类型的嵌套数据结构。
*具有类型级计算能力的高阶类型。
#归纳定义的表达能力
归纳定义的表达能力也很强大,因为它允许我们定义具有复杂结构和递归性质的类型。这使得我们能够表示各种数据结构和算法,而无需使用显式的递归。
例如,我们可以使用归纳定义来表示:
*具有复杂分支结构的离散类型。
*具有递归结构的嵌套数据类型。
*表示无限数据结构的协变类型。
#结论
类型族和归纳定义是泛型类型系统中强大的机制,可以用来表示复杂和可表达的类型结构。它们共同作用,使我们能够构建高度类型安全的程序,并抽象出复杂的类型级计算。第八部分高阶类型与能力提升关键词关键要点【高阶类型与具体化】
1.类型变量和多态性:高阶类型系统允许定义类型变量,表示可以被任意其他类型替代的抽象类型,从而实现多态性。
2.类型抽象:可以通过抽象类型变量来创建新的类型,用于表示具有特定性质或行为的数据结构或函数。
3.类型实例化:类型变量可以被具体类型实例化,从而生成新的具体类型,其性质和行为取决于实例化类型。
【高阶类型与泛型编程】
泛型类型系统表达能力:高阶类型与能力提升
高阶类型
在泛型类型系统中,高阶类型允许类型本身成为类型参数。通过使用高阶类型,可以创建通用代码,该代码可以处理各种类型的输入或输出。
高阶类型示例
*`List[T]`:一个列表,其中`T`是元素的类型。
*`Function[T,U]`:一个函数,它接受`T`类型的输入并返回`U`类型的输出。
*`Map[K,V]`:一个映
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024副食品保障供应合同
- 农产品采购合作协议书
- 社区物业管理服务合同
- 小额民间借款合同范本
- 建筑行业材料购销协议模板
- 2023年高考地理复习精题精练-区域发展对交通运输布局的影响(解析版)
- 2024年售房的合同范本
- 建筑工地物资租赁合同书
- 房产抵押担保协议参考
- 2024年劳务协议书样本
- 企业如何利用新媒体做好宣传工作课件
- 如何培养孩子的自信心课件
- 中医药膳学全套课件
- 颈脊髓损伤-汇总课件
- 齿轮故障诊断完美课课件
- 2023年中国盐业集团有限公司校园招聘笔试题库及答案解析
- 大班社会《特殊的车辆》课件
- 野生动物保护知识讲座课件
- 早教托育园招商加盟商业计划书
- 光色变奏-色彩基础知识与应用课件-高中美术人美版(2019)选修绘画
- 前列腺癌的放化疗护理
评论
0/150
提交评论