




已阅读5页,还剩12页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
目录VB接口的概念1接口要点1示例一:IDisplayer2示例二:ISpeak8示例三:实现多态(Animal)10示例四:IEnumerator11示例五:Implements语句13.NET抽象类13创建VB.NET抽象类14实际操作中使用VB.NET抽象类15示例15.NET接口和.NET抽象类的相同点和不同点16相同点16不同点16.NET接口和.NET抽象类的规则与场合17VB接口的概念2006-09-29 11:12谢谢妖居前辈写的文章,原文地址/archive/2005/09/09/127917.html只支持单继承的VB.NET为了解决多继承的问题,引入了接口的概念。我们可以这样来为接口下一个定义:接口就是指只包含虚成员的虚类。 1.虚类,表明了接口是不能够被直接实例化的。也就是说,接口只是一个抽象概念。比如我们说车可以跑,人可以跑,马可以跑。我们可以看到实例化的车、人、马。但是我们可以定义一个“会跑的物质”。他可以是车,也可以使人、马,但是我们却不能说“这个东西就是一个会跑得物质,但是它并不是车、人或者马。” 2.只包含虚成员,表明了接口只是说明了它具有什么样的功能,可以提供什么样的信息。但是这些功能和信息究竟是什么,如何提供我们无法得知。就像是“会跑的物质”,我们知道它可以跑,但是具体他怎么跑我们就不知道了。 之所以说接口可以部分替代多继承,就是因为VB.NET只允许一个类继承自另一个,且只能是这个类;但是一个类可以实现一个或多个接口。由于接口不实现成员,只声名成员,所以也就不存在多继承的路径问题了。 接口要点1、定义接口名,应按照惯例,将接口名的第一个字母命名为 I,如上例中的 ISpeak,这样做的目的是见名知义,原因是因为接口的英语单词是 Interface;2、由于接口中的成员签名必须在实现该接口的类中给出其具体实现,所以它们前面不用加访问级别修饰符(Public、Privated 等);3、类通过 Implements 关键字实现接口;4、一个类要实现一个接口,就必须实现该接口中定义的所有成员签名;5、一个类可以实现多个接口,方法是在接口名用“,”隔开,如 Implements ISpeak,IRun。现在我们假定您已经知道了接口的声名以及相关的一些基本知识,我们来看看什么时候我们需要使用接口。示例一:IDisplayer当我们面临一个问题,就是我们有一个功能,它需要操作不同的类的实例去完成一个目的相同的方法的时候,我们就可以把这些目的相同的方法作为接口来实现。现在我们看看我们面临的问题。目前我们手头有一些类,它们之间没有继承关系,但是这些类都可以被显示成字符串。 图书类。可以显示的是书名。 Public Class Book Inherits Media Private m_Name As String Public Function Display() As String Return m_Name End FunctionEnd ClassLCD显示器类,可以显示的是显示器屏幕上面的内容。 Public Class LCD Inherits ComputerService Private m_DisplayComment As String Public Function Display() As String Return m_DisplayComment End FunctionEnd Class用户类,显示的是全名(姓 + 名)。 Public Class User Inherits Person Private m_FirstName, m_LastName As String Public Function Display() As String Return m_FirstName & . & m_LastName End FunctionEnd Class现在我们希望我们的程序(函数)能够把这些显示内容通过Console输出到控制台上面。由于它们不是同一个类继承的,所以我么现在有两种选择:1. 为每一个类做一个函数,分别对应着一个类的显示函数:代码复杂,而且如果新加入了别的类,我们不得不在做一个函数。2. 使用一个函数,用Object代替这些类,使用晚期绑定实现:不安全,如果开发者传递了一个没有相应方法的实例进取就会引发异常。现在我们使用接口看看。接口是不依照类的继承关系存在的,所以我们需要首先定义一个接口。它包含了一个Display方法。这说明了符合这个接口的所有实例必然有这样的一个方法,名字叫做Display,没有参数,返回字符串:Public Interface IDisplayer Function Display() As StringEnd Interface这个Display方法只是一个虚函数,没有内容,因为我们并不知道他们应该怎么被Display。但是我们能够保证,他可以被Display,这样就足够了。现在我们使用这个接口来封装我们的三个类。让他们实现这个接口,实现的同时我们也必须实现接口里面的所有虚程序。这相当于告诉编译器,我的类符合接口规定的功能,我能Display,我来告诉你怎样Display。图书类。可以显示的是书名。 Public Class Book Inherits Media Implements IDisplayer Private m_Name As String Public Function Display() As String Implements IDisplayer.Display Return m_Name End FunctionEnd Class LCD显示器类,可以显示的是显示器屏幕上面的内容。 Public Class LCD Inherits ComputerService Implements IDisplayer Private m_DisplayComment As String Public Function Display() As String Implements IDisplayer.Display Return m_DisplayComment End FunctionEnd Class用户类,显示的是全名(姓 + 名)。 Public Class User Inherits Person Implements IDisplayer Private m_FirstName, m_LastName As String Public Function Display() As String Implements IDisplayer.Display Return m_FirstName & . & m_LastName End FunctionEnd Class显示函数。 Public Sub Display(ByVal idr As IDisplayer) MsgBox(idr.Display)End Sub我们使用了参数idr,这个参数的类型是一个接口IDisplayer。我们使用接口可以像使用类一样。实际上我们传递进来的是实现了这个接口的某个类的实例,但是这并不是我们关心的。我们只要知道,这个类可以Display就足够了。所以我么只需要直接调用接口函数Display,就可以调用到这个接口实例里面的Display函数。他肯定存在,因为他实现了接口。如果不存在,编译器就会报错的。这样我们就可以在不知道实例类型的情况下使用方法了,而且它很安全。 如果我们需要加入一个新的类,比如是Company类,我们只要让他也实现了这个接口,就可以直接适用这个函数了。接口也允许继承,而且允许多继承,但是接口只能从接口继承。比如我们的IDisplayer接口继承了两个.NET的接口。Public Interface IDisplayer Inherits ICloneable, IComparer Function Display() As StringEnd Interface一个是ICloneable,他表示我们的接口支持复制(克隆);另一个是IComparer,他表示我们的接口支持比较。现在我们这三个类就出现了编译错误,因为我们现在只实现了IDisplayer的虚函数Display,基接口(ICloneable, IComparer)的虚函数(Compare,Clone())我们还没有实现。所以我们的还必须实现基接口的虚成员。我们以Book为例,需要稍加改动:图书类。可以显示的是书名。 Public Class Book Inherits Media Implements IDisplayerPrivate m_Name As String Public Sub New(ByVal Name As String) m_Name = Name End Sub Public Function Display1() As String Implements IDisplayer.Display Return m_Name End Function Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare Dim bx, by As Book If TypeOf x Is Book AndAlso TypeOf y Is Book Then bx = CType(x, Book) by = CType(y, Book) Return String.Compare(bx.m_Name, by.m_Name) End If End Function Public Function Clone() As Object Implements System.ICloneable.Clone Return New Book(m_Name) End FunctionEnd Class图书类实际上包含了三个接口:IDisplayer、ICloneable和IComparer。但是我们使用的时候,ICloneable和IComparer接口不会出现,它的函数会被当作IDisplayer来实现。Public Sub Display(ByVal idr As IDisplayer) MsgBox(idr.Display) Dim o As Object = idr.CloneEnd Sub当我们发现一些毫不相干的类,却有一个共同的操作,他的参数和返回值一致,而我们恰恰要在某一个(或几个)地方频繁的使用的时候,我们不妨将这些相同的部分用接口实现。但是前提条件是这些操作来设计逻辑来讲却是属于相同的操作。不要为了使用接口而使用它。以下为完整代码:Public Interface IDisplayer Inherits ICloneable, IComparer 此二接口在命名空间System.Collections下 Function Display() As String 表明接口IDisplayer中有函数Display(),此函数具体内容在每个类中不同。End InterfacePublic Class Media statementEnd ClassPublic Class ComputerService statementEnd ClassPublic Class Person statementEnd Class图书类。可以显示的是书名。 Public Class Book Inherits Media Implements IDisplayer Private m_Name As String Public Function Display() As String Implements IDisplayer.Display 接口中函数的具体形式 Return m_Name End Function Public Sub New(ByVal Name As String) m_Name = Name End Sub Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare Dim bx, by As Book If TypeOf x Is Book AndAlso TypeOf y Is Book Then bx = CType(x, Book) by = CType(y, Book) Return String.Compare(bx.m_Name, by.m_Name) End If End Function Public Function Clone() As Object Implements System.ICloneable.Clone Return New Book(m_Name) End FunctionEnd ClassLCD显示器类,可以显示的是显示器屏幕上面的内容。 Public Class LCD Inherits ComputerService Implements IDisplayer Private m_DisplayComment As String Public Function Display() As String Implements IDisplayer.Display Return m_DisplayComment End Function Public Sub New(ByVal Name As String) m_DisplayComment = Name End Sub Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare Dim bx, by As LCD If TypeOf x Is LCD AndAlso TypeOf y Is Book Then bx = CType(x, LCD) by = CType(y, LCD) Return String.Compare(bx.m_DisplayComment, by.m_DisplayComment) End If End Function Public Function Clone() As Object Implements System.ICloneable.Clone Return New LCD(m_DisplayComment) End FunctionEnd Class用户类,显示的是全名(姓 + 名)。 Public Class User Inherits Person Implements IDisplayer Private m_FirstName, m_LastName As String Private fullname As String Public Function Display() As String Implements IDisplayer.Display fullname = m_FirstName & . & m_LastName Return fullname End Function Public Sub New(ByVal Name As String) fullname = Name End Sub Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare Dim bx, by As User If TypeOf x Is User AndAlso TypeOf y Is User Then bx = CType(x, User) by = CType(y, User) Return String.Compare(bx.fullname, by.fullname) End If End Function Public Function Clone() As Object Implements System.ICloneable.Clone Return New User(fullname) End FunctionEnd Class示例二:ISpeak本文提供的VB.NET接口范例希望能为读者建立起对接口一个初步的、正确的认识。本例定义了一个名为 ISpeak 的接口,其中包括了三个签名。由于接口是代表一种约定或者说是一种规则,它并不包含这种约定或者规则的具体实现。所以,我们只需要在接口中定义签名即可。在该接口中,包括了三个成员签名,它们分别代表了属性、方法以及函数。接下来,我又定义了三个类,分别是 Baby、Children 和 Adlut ,这个三类都实现了上述接口。并且,在每个类实现接口的成员时,都给出了具体的实现。来看代码:定义一个接口 Public Interface ISpeak 仅定义签名,不包含任何实现 ReadOnly Property CanSpeak() As Boolean 属性 Sub Speak() 方法 Function GetSpeakLevel() As SpeakLevelEnum 函数 End Interface说话水平枚举 Public Enum SpeakLevelEnum Bad 很差 Ordinary 一般 Fluent 流利 End EnumPublic Class Baby : Implements ISpeak 通过 Implements 关键字实现接口 以下是实现该接口的所有成员 Public ReadOnly Property CanSpeak() As Boolean Implements ISpeak.CanSpeak Get Return False End Get End Property Public Function GetSpeakLevel() As SpeakLevelEnum Implements ISpeak.GetSpeakLevel Return SpeakLevelEnum.Bad End Function Public Sub Speak() Implements ISpeak.Speak Console.WriteLine(旁白):他是一个婴儿,还不会说话。) End SubEnd ClassPublic Class Children : Implements ISpeak Public ReadOnly Property CanSpeak() As Boolean Implements ISpeak.CanSpeak Get Return True End Get End Property Public Function GetSpeakLevel() As SpeakLevelEnum Implements ISpeak.GetSpeakLevel Return SpeakLevelEnum.Ordinary End Function Public Sub Speak() Implements ISpeak.Speak Console.WriteLine(哈哈,我是一个快乐的孩子!) End SubEnd ClassPublic Class Adult : Implements ISpeak Public ReadOnly Property CanSpeak() As Boolean Implements ISpeak.CanSpeak Get Return True End Get End Property Public Function GetSpeakLevel() As SpeakLevelEnum Implements ISpeak.GetSpeakLevel Return SpeakLevelEnum.Fluent End Function Public Sub mySpeak() Implements ISpeak.Speak Console.WriteLine(OK, 我是成年人了,不但能流利地说母语,还会说外语。) End SubEnd Class程序入口点 Public Class AppStart Shared Sub Main() Dim person1 As New Baby Dim person2 As New Children Dim person3 As New Adult person1.Speak() person2.Speak() person3.mySpeak() If person2.GetSpeakLevel SpeakLevelEnum.Bad Then Console.WriteLine( Person2 的说话水平不算很差) End If If person1.CanSpeak Then Console.WriteLine( Person1 会说话) Else Console.WriteLine( Person1 不会说话) End If Console.Read() End SubEnd ClassPublic Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click AppStart.Main() End SubEnd Class在 VS2005/2008 中建立一个“控制台项目”项目,将默认的 Module1.vb 删除,在该项目中添加一个类,将上述代码复制到这个类中覆盖原有内容,即可运行调试。示例三:实现多态(Animal)VB.NET接口实现多态,能够通过使用多接口,用户可以在不中断运行代码的情况下,允许运行多种软件的系统组件。接口象类那样描述属性和方法,但是它和类不同的是,接口不能提供任何实现。为了正确的操作VB.NET接口实现多态,用户需先建立一个接口,并且通过其他的几个类实现该接口。用户可以用几乎相同的方法调用其他对象已经实现的方法。下面这个例子就是VB.NET接口实现多态:Namespace PolyNamespace Interface Animal Sub Move(ByRef Distance As Double) Sub Bite(ByVal What As Object) End Interface Class Flea Implements animal Public Sub bite(ByVal What As Object) Implements Animal.Bite Bite something End Sub Sub Move(ByRef Distance As Double) Implements Animal.Move Distance = Distance + 1 End Sub End Class Class Dog Implements animal Public Sub bite(ByVal What As Object) Implements Animal.Bite Bite something End Sub Sub Move(ByRef Distance As Double) Implements Animal.Move Distance = Distance + 100 End Sub End ClassEnd Namespaceadd this section to the your form Protected Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Dim aFlea As New Flea() Dim anobj As Object() Dim aDog As New Dog() GetFood(aflea, anobj) GetFood(aDog, anobj) End Sub Public Sub GetFood(ByVal Critter As Animal, ByVal Food As Object) Dim dblDistance As Double Code to calculate distance to food(omitted). Critter.Move(dblDistance) Early bound(vtable) Critter.Bite(Food) Early bound(vtable) End Sub示例四:IEnumerator在面向对象的设计中,经常会用到有类似父子关系的这个对象,比如在一个项目中,有订单对象,在一个订单下又包含多个产品,这时我就想用Iterator模式来封装订单下的产品,在.Net中的IEnumerator接口就是用来实现迭代的,来支持.Net中的for each的操作。要VB.NET实现IEnumerator接口,需在实现以下几个函数来支持IEnumerator接口的操作 Overridable ReadOnly Property Current() As ObjectCurrent用于在迭代过程中得到当前的对象。 Public Overridable Function MoveNext() As BooleanMoveNext用于在迭代过程中将迭代指针指向下一个对象,初始是迭代指针指向集合的开始(在第一个节点之前的位置),一旦越过集合的结尾,在调用 Reset 之前,对 MoveNext 的后续调用返回 false。 Overridable Sub Reset()将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。只要集合保持不变,枚举数就将保持有效。如果对集合进行了更改(例如添加、修改或删除元素),则该枚举数将失效且不可恢复,并且下一次对 MoveNext 或 Reset 的调用将引发InvalidOperationException。下面是一个具体的实现IEnumerator接口的对象:Imports System.Collections在此实际实现的是System.Collections.IEnumerable接口,IteratorProduct 用此接口来向使用者提供对IEnumerator接口的操作。 Public Class IteratorProduct : Implements System.Collections.IEnumerable Private Products As Collection 用Collection在存订单中的所有产品 Private item As Integer = -1 Public Sub New() Products = New Collection Products.Add(xh) 这只是为了测试方便,将加入产品的内容直接写在这了 Products.Add(lj) Products.Add(qd) End Sub Overridable ReadOnly Property Current() As Object Get Return Products(item) End Get End Property Public Overridable Function MoveNext() As Boolean item += 1 End Function Overridable Sub Reset() item = -1 End Sub 返回迭代对像给使用者 Overridable Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator Return Me.Products.GetEnumerator End FunctionEnd Class示例五:Implements语句Public Interface ICustomerInfo Event updateComplete() Property customerName() As String Sub updateCustomerStatus()End InterfacePublic Class customerInfo Implements ICustomerInfo Storage for the property value. Private customerNameValue As String Public Event updateComplete() Implements ICustomerInfo.updateComplete Public Property CustomerName() As String _ Implements ICustomerInfo.customerName Get Return customerNameValue End Get Set(ByVal value As String) The value parameter is passed to the Set procedure when the contents of this property are modified. customerNameValue = value End Set End Property Public Sub updateCustomerStatus() _ Implements ICustomerInfo.updateCustomerStatus Add code here to update the status of this account. Raise an event to indicate that this procedure is done. RaiseEvent updateComplete() End SubEnd Class类 customerInfo 在单独的源代码行上使用 Implements 语句,以指示该类实现 ICustomerInfo 接口的所有成员。然后,该类中的每个成员使用 Implements 关键字作为其成员声明的一部分,以指示它实现该接口成员。.NET抽象类抽象类即是不能被实例化的类,而且你不能够在自己的程序里通过这种类来生成一个对象,必须通过继承由派生类实现其抽象方法,因此对抽象类不能使用new关键字,也不能被密封。抽象类提供多个派生类共享基类的公共定义,它既可以提供抽象方法,也可以提供非抽象方法。如果派生类没有实现所有的抽象方法,则该派生类也必须声明为抽象类。你也许会认为不能被实例化的类是没多大用处的。事实上,在某些环境下, 抽象类是非常有用的。你可以把它作为一个基础类以此为基类创建新的类。 在此假设一个要用抽象类的程序设计。假设图形程序提供了大量的drawing类:比如圆,三角,曲线等等。所有这些作drawing类都有某个共同的特性,比如位置,大小,色彩,删除等属性。其它的类成员,比如描绘图形的方法就不同于每个单独的类。因此,这样为利用抽象类创造了一个理想的环境。在抽象类中,你需要定义所有drawing类都需要的全部通用类成员。因为drawing类不响应任何图形。但是当把它作为shape-specific drawing类中的基类,你需要确认所有这些抽象类拥有最基本的功能.创建VB.NET抽象类对抽象类的定义很简单,只要在定义域里加入关键字MustInherit,如:Public MustInherit Class MyAbstractclass. End Class除开要包含关键字之外, 抽象类的定义与非抽象类的定义没什么两样。抽象类包含了从其它类承继而来的属性及方法等等。但是,在抽象类中定义的类成员(属性及方法)是如何与衍生类中的定义元素产生联系的呢?在此并没有复杂的规则,但你作出的决定将与你所拥有的类及它将衍生出来的类的性能密切相关。你有三个选择。1、抽象类中已有的功能比如属性、方法等在衍生类中可以被重载。实现这一功能只要在基类成员定义中输入Overridable关键字。如: Public Overridable Sub Move(NewX As Integer, NewY As Integer). End Sub2、为重载抽象类中的成员,衍生类在执行语句中须使用Overrides关键字。如: Inherits MyAbstractclass Public Overrides Sub Move(NewX As Integer, NewY As Integer). End Sub3、抽象类中已有的功能不能在衍生类中重载。即衍生类必须使用抽象类定义的成员。如果你在抽象类中不使用任何特殊字段来定义某一成员将会使其产生缺省。以下代码定义了抽象类中的Xpos属性,衍生类必须使用该属性,因为该属性不能被重载: Public Property XPos() As Integer . End Property利用MustOverride关键字来定义VB.NET抽象类成员,该成员可以在衍生类中重载。以下举例说明了衍生类必须执行名为GetObjectAt()的方法。 Public MustOverride Function GetObjectAt(X As Integer, Y As Integer) As Object使用MustOverride最方便的地方在于它不仅规定了成员的名称同样也规定了成员的符号。先前的例子要求任一衍生类都需定义名称为GetObjectAt()的方法,因此会产生两种类型的整型变量以及返回一个类型对象。该方法在衍生类中的执行是完全根据程序员的指令要求。通过MustOverride字段说明的方法一些时候也被称为abstract 成员。实际操作中使用VB.NET抽象类设想一下你正在为一家大公司开发一个新的员工数据库。你的工作就是监督类的执行,使雇员的基本情况与管理部门的要求相吻合,同样,在区分公司分支机构的要求时也提供更大的便利。基本要求如下:抽象类里有姓名,雇用时间等属性,这些属性不会被重载。因为大多数雇员来自美国,因此在抽象类里执行退休ID,以运行社会保障号码。国外分公司将会利用不同的方式来鉴别雇员的退休ID,因此该属性会在衍生类里重载,以便单个分支机构分别执行。名称为补偿金的方法不会引起争议,然后会返回一个含有雇员补偿金细节的类型对象。因为不同分公司都规定不同的补偿金,薪金,佣金,红利等,因此灵活的执行这些对象是很有必要的,由此会产生一个抽象方法。由此而产生的抽象类的代码,称为EmployeeBase,会在第一栏里显示。位于法国的分公司的程序员用EmployeeBase类作为EmployeeFrance类的基类,与当地雇员记录软件合作使用。因此,衍生类需要承继名称及雇用日期等字段。更多的是,在EmployeeBase类中的RetirementID成份适合运用在法国,因此,新类不会重载该成份。程序员做的所有这些工作是为了执行abstractCompensationmember的重载。但是在英国,RetirementID属性不适用于该地,因此衍生类将会重载该成员,同样的也会重载Compensation成员。示例Public MustInherit Class MyFiles MyFiles是个抽象类 Inherits CollectionBase Friend MustOverride Sub Add(ByVal MyFileName As String) Add方法必须重载 Friend Sub AddAllFileNames(ByVal MyPath As String) 抽象类中有部分方法可以不重载 For Each SingleFileName As String In My.Computer.FileSystem.GetFiles(MyPath) Add
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年工业互联网平台NFV网络功能虚拟化在智慧城市建设的实践报告
- 2025年环保产业园区产业集聚与区域产业协同发展产业链协同发展风险创新路径规划报告
- 中考英语完形填空基础特训(含十个练习及答案)
- 建筑装潢公司合伙协议书
- 中学2024年校团委工作总结(31篇)
- 河北省唐山市玉田县2024-2025学年六年级上学期期中(1-5单元)数学试题参考答案
- 应交增值税核算课件
- 巡逻兵进行曲课件
- 2025年工程机械行业投资策略分析报告:工程机械海外市场占有率提升国内需求改善
- 巍山食品安全培训课件
- 农产品直播带货策略
- 执业药师考试复习资料-《中药专业知识一》高频考点记忆口诀
- 第2课《互联网应用新特征》课件 2024--2025学年人教版(2024)初中信息技术七年级上册
- 《证券投资学》全套教学课件
- 小学英语教学评一体化
- 函数图像 课件-2025届高三数学一轮复习
- 专题05 《红星照耀中国》试题50题中考语文名著阅读试题50题
- 2022年安徽省体育彩票管理中心招聘考试试题及答案
- 追觅入职测评题库
- 运输公司车辆安全检查表
- 煤矿井下掘进培训课件
评论
0/150
提交评论