直接来代码'类C1
public sub C()end Sub'类C2
Implements C1
public sub C1_C()end Sub'C3Implements C2'C3要如何实现C2和C1中的接口?

解决方案 »

  1.   

    'Class C3
    Implements C1
    Implements C2
      

  2.   

    '---------------------------------------------------------------------------------------
    ' Module    : Class1
    ' Author    : Anna
    ' Date      : 2009-9-20
    ' Purpose   : Abstract class
    '---------------------------------------------------------------------------------------Option ExplicitPublic Sub M1()End Sub
    '---------------------------------------------------------------------------------------
    ' Module    : Class2
    ' Author    : Anna
    ' Date      : 2009-9-20
    ' Purpose   : Implements Class1
    '---------------------------------------------------------------------------------------Option ExplicitImplements Class1Private Sub Class1_M1()
        Debug.Print "Class2's implementation of Class1's M1"
    End SubPublic Sub M2()End Sub
    '---------------------------------------------------------------------------------------
    ' Module    : Class3
    ' Author    : Anna
    ' Date      : 2009-9-20
    ' Purpose   : Implements Class1 and Class2
    '---------------------------------------------------------------------------------------Option Explicit
    Implements Class1
    Implements Class2Private Sub Class1_M1()
        Debug.Print "Class3's implementation of Class1's M1"
    End SubPrivate Sub Class2_M2()
        Debug.Print "Class3's implementation of Class2's M2"
    End Sub
    '---------------------------------------------------------------------------------------
    ' Module    : Module1
    ' Author    : Anna
    ' Date      : 2009-9-20
    ' Purpose   : Test Multi-Inheritance
    '---------------------------------------------------------------------------------------Option ExplicitSub Test_MultiInherit()
        Dim aa As Class1
        Dim bb As Class2
        Dim cc As Class3
        
        Set cc = New Class3
        
        Set bb = cc
        Call bb.M2
        Set bb = Nothing
        
        Set aa = cc
        Call aa.M1
        Set aa = Nothing
        
        Set cc = Nothing
    End Sub
      

  3.   

    如果你的意思是想在Class3里继承Class2里的Class1_M1()的话,据我所知,好像是不被VB支持的。
      

  4.   

    我感觉VB里并不支持爷孙继承,它不会了解这种隔一代的血缘关系。你看下面的例子(Class1和Class2的定义同4楼):
    '---------------------------------------------------------------------------------------
    ' Module    : Class3
    ' Author    : Anna
    ' Date      : 2009-9-20
    ' Purpose   : Implements Class2 only
    '---------------------------------------------------------------------------------------Option Explicit
    Implements Class2Private Sub Class2_M2()
        Debug.Print "Class3's implementation of Class2's M2"
    End Sub
    '---------------------------------------------------------------------------------------
    ' Module    : Module1
    ' Author    : Anna
    ' Date      : 2009-9-20
    ' Purpose   : Does VB know anything about Grandpa?
    '---------------------------------------------------------------------------------------Option ExplicitSub Test_MultiInherit()
        Dim aa As Class1
        Dim bb As Class2
        Dim cc As Class3
        
        Set cc = New Class3
        
        Set bb = cc
        Call bb.M2'    Set bb = New Class2
        Set aa = bb 'Type MisMatch, 除非把上一句取消注释'
        Call aa.M1
        Set aa = Nothing
        Set bb = Nothing
        
        Set cc = Nothing
    End Sub
    上面这段代码说明,Class3能够了解自己继承自Class2,但是并不会进一步去了解Class2继承自Class1。所以你可以Set bb = cc,但是不能进一步Set aa = bb,更不能Set aa = cc。VB只能记录父类子类这样单层的继承关系。
      

  5.   

    class2里的class1_m1是class1里m1接口的实现,class3如果要继承class2里的class1_m1的话直接去实现class1里的m1接口好了。
      

  6.   


    但是Class3就不能继承Class2里的实现了。打个比方说,Class1是动物类,有个方法叫做吃(M1);Class2是哺乳动物类,Class2继承吃的方法(Class1_M1),加入自己的实现“弄死了再吃”;Class3是人,它要继承吃的方法,比较省力的办法是继承Class2的“弄死了再吃”的步骤,自己再加一个语句叫“烧熟了再吃”就可以了。可是,在VB中并不支持这样的爷孙继承。Class3如果直接继承Class2的话,它就不能继承Class2吃的方法。因为在Class2里,它继承的Class1的吃的方法是私有的(Private Sub Class1_M1)。所以,它只能直接继承Class1的M1方法,并且只好重复写上“弄死再吃”、然后加上“烧熟再吃”。
      

  7.   

    当然你可以试着把Class2里的Private Sub Class1_M1改成Public Sub Class1_M1。之后在Class3里再实现Class2的方法 Class1_M1,但是你会发现VB编译器会无法理解你的实现,因为你的实现现在叫Class2_Class1_M1,这个有二义性的名字会把VB编译器绕晕。
      

  8.   

    C2中实现的C1中的方法不能被公开,不支持多重继承关系,鄙视一下VB
      

  9.   

    这个问题虽然了解一些但是从来没在实际的项目中应用过,所以研究得不是很深,不知道能不能在Class2里面再加一个吃的方法(M1),Class3继承Class2的吃的方法(Class2_M1),并实现“烧熟了再吃”,这样Class3在Class2“弄死了再吃”的基础上再实现“烧熟了再吃”
      

  10.   


    这样做虽然可以,但是假如Class1的吃的方法有一个步骤“抓住一个动物再吃”,用你的方法就无法继承了。就是说,如果我希望既继承Class1的“抓住一个动物再吃”,也希望继承Class2的“弄死了再吃”,并且希望加上自己的“烧熟了再吃”,VB6是不支持的。
      

  11.   

    Implements与聚合配合是可以实现继承功能的.class1代码:
    Option ExplicitPublic Sub M1()
        Debug.Print "吃"
    End Sub
    class2代码:
    Option Explicit
    Implements Class1
    Private mobjClass1 As New Class1Public Sub M1()
        Call mobjClass1.M1
        Debug.Print "弄死再吃"
    End SubPrivate Sub Class1_M1()
        Call M1
    End Sub
    class3代码:
    Option Explicit
    Implements Class1
    Private mobjClass2 As New Class2Public Sub M1()
        Call mobjClass2.M1
        Debug.Print "烧熟再吃"
    End SubPrivate Sub Class1_M1()
        Call M1
    End Sub
    窗口代码:
    Option ExplicitPrivate Sub Form_Load()
        Dim cls As New Class3
        Call cls.M1
    End Sub
      

  12.   

    又完善了一下:Class1代码:Option ExplicitPublic Sub M1()
        Debug.Print "吃"
    End SubClass2代码:Option Explicit
    Implements Class1                   ' Class2实现了Class1的默认接口
    Private mobjClass1 As New Class1    ' Class2聚合了Class1的一个实例' 调用基类方法,同时添加自己的内容
    Public Sub M1()
        Call mobjClass1.M1
        Debug.Print "弄死再吃"
    End Sub' 实现基类接口
    Private Sub Class1_M1()
        Call M1
    End SubClass3代码:Option Explicit
    Implements Class1                   ' Class3实现了Class1的默认接口
    Implements Class2                   ' Class3实现了Class2的默认接口
    Private mobjClass2 As New Class2    ' Class3聚合了Class2的一个实例' 调用基类方法,同时添加自己的内容
    Public Sub M1()
        Call mobjClass2.M1
        Debug.Print "烧熟再吃"
    End Sub' 实现基类接口
    Private Sub Class1_M1()
        Call M1
    End Sub' 实现基类接口
    Private Sub Class2_M1()
        Call M1
    End SubForm1代码:Option ExplicitPrivate Sub Form_Load()
        Debug.Print vbCrLf & "p3->Class3"
        Dim p3 As Class3    ' Class3的默认接口
        Set p3 = New Class3 ' Class3对象
        Call p3.M1
        
        Debug.Print vbCrLf & "p2->Class3"
        Dim p2 As Class2    ' Class2接口
        Set p2 = New Class3 ' Class3对象
        Call p2.M1
        
        Debug.Print vbCrLf & "p1->Class3"
        Dim p1 As Class1    ' Class1接口
        Set p1 = New Class3 ' Class3对象
        Call p1.M1
        
        Debug.Print vbCrLf & "p2->Class2"
        Set p2 = New Class2 ' Class2对象
        Call p2.M1
        
        Debug.Print vbCrLf & "p1->Class2"
        Set p1 = New Class2 ' Class1对象
        Call p1.M1
        
        Debug.Print vbCrLf & "p1->Class1"
        Set p1 = New Class1 ' Class1对象
        Call p1.M1
    End Sub
      

  13.   

    做 QI 接口hook... 自己弄....
    多重接口继承好像是不支持.
      

  14.   

    Implements 语句
    指定要在包含该语句的类模块中实现的接口或类。
    语法
    Implements [InterfaceName | Class]
    所需的 InterfaceName 或 Class 是类型库中的接口或类的名称,该类型库中的方法将用与 Visual Basic 类中相一致的方法来实现。
    说明
    所谓接口就是代表接口封装的成员(方法以及属性)的原型集合;也就是说,它只包含成员过程的声明部分。一个类提供一个或多个接口的所有方法以及属性的一种实现方案。类的控制者每次调用函数时,该函数所执行的代码由类来提供。每个类至少应实现一个缺省接口。在 Visual Basic 中,一个已实现的接口中任何没有显式声明的成员都是缺省接口的隐式成员。
    当 Visual Basic 类实现接口时,都会提供该接口的类型库中说明的所有 Public 过程的版本。除了提供接口原型与自编过程之间的映射关系之外,Implements 语句还使这个类接收对指定接口 ID 的 COM QueryInterface 调用。

    注意 Visual Basic 不能实现派生出来的类或接口。
    在实现接口或类时,必须包括所用到的 Public 过程。如果在实现接口或类时遗漏了成员,就会产生错误。如果正在实现的类中某个过程还没有代码,则可以产生一个适当的错误信息 (Const E_NOTIMPL = &H80004001),以便用户意识到该成员还没有实现。
      

  15.   

    记下  Visual Basic 不能实现派生出来的类或接口。感觉也不是绝对的。
      

  16.   

    注意 Visual Basic 不能实现派生出来的类或接口。 Implements只是实现不是派生
      

  17.   

    在Class3里继承Class2里的Class1_M1(
      

  18.   

    Option Explicit
    Implements Class1                   ' Class3实现了Class1的默认接口
    Implements Class2                   ' Class3实现了Class2的默认接口
    Private mobjClass2 As New Class2    ' Class3聚合了Class2的一个实例
      

  19.   

    C3继承C2,c2继承C1,C3是得不到C1的接口继承的。只有换种方式C3继承C2,C1的方式可以。VB6只支持单层继承。
      

  20.   


    你的代码的实质:
    (1)用聚合来实现多重继承
    (2)用Implements来实现多态。比较典型的:
        Dim p2 As Class2    ' Class2接口
        Set p2 = New Class3 ' Class3对象
        Call p2.M1p2.M1实际上调用了p3.M1。调用过程如下:
    (1)p2实际上指向一个Class3对象
    (2)由于Class3实现了Class2的M1方法,所以多态机制决定对p2.M1会被引向p3里的私有过程Class2_M1
    (3)而在Class2_M1过程里你直接调用了Class3的M1方法;
    (4)而在Class3的M1方法里你又通过聚合的Class2对象调用了Class2的M1方法;
    (5)类似的,在Class2的M1方法中,你也通过聚合的Class1对象调用了Class1的M1方法。最后效果,就是通过调用p2.M1,你居然神奇的把从Class1到Class3可以做的事都做了。对的,所以实际上它不怎么支持继承。赞同。记得以前有次讨论,曾经有个结论说,聚合应该全面替代继承。因为继承的耦合度高,会带来一系列麻烦。好像是ahao说的,你也赞同。不知记错没?现在又觉得这个结论有点费解了。
      

  21.   

    我根本不赞成用聚合代替继承。
    在vb6中用聚合模拟继承是没有办法的办法。
    我个人的实践是在vb6中根本不使用类模块,而是仍然使用面向过程的编程。
      

  22.   

    不支持的。要自己调用子类中的方法,很累人
      
    *****************************************************************************
    欢迎使用CSDN论坛专用阅读器 : CSDN Reader(附全部源代码) http://feiyun0112.cnblogs.com/
      

  23.   


    这是C++中虚(virtual)函数的行为.如果不加virtual,而让子类的方法覆盖父类方法的话,在VB中可以不递归调用来进行模拟.
    也就是说,Class3的p2.M1调用Class2的M1方法就等同于C++的虚函数,不调用的就等用于普通成员函数.
      

  24.   

    说错了,如果模拟普通函数,不是不调用,而是直接调用其模拟父类的相应函数..Class2代码:
    Option Explicit
    Implements Class1                   ' Class2实现了Class1的默认接口
    Private mobjClass1 As New Class1    ' Class2聚合了Class1的一个实例' 调用基类方法,同时添加自己的内容
    Public Sub M1()
        Debug.Print "弄死再吃"
    End Sub' 实现基类接口
    Private Sub Class1_M1()
        Call mobjClass1.M1
    End Sub
    Class3代码:
    Option Explicit
    Implements Class1                   ' Class3实现了Class1的默认接口
    Implements Class2                   ' Class3实现了Class2的默认接口
    Private mobjClass2 As New Class2    ' Class3聚合了Class2的一个实例' 调用基类方法,同时添加自己的内容
    Public Sub M1()
        Debug.Print "烧熟再吃"
    End Sub' 实现基类接口
    Private Sub Class1_M1()
        Dim objClass1 As Class1
        Set objClass1 = mobjClass2
        Call objClass1.M1
    End Sub' 实现基类接口
    Private Sub Class2_M1()
        Call mobjClass2.M1
    End Sub
      

  25.   


    不好意思说错了,今天刚看的COM技术内幕
    这种方式应该被称为包容而不是聚合,聚合是指直接将指针给出去的情况.
      

  26.   

    这些并不是说VB不行吧。应该可以用类型库以及HookQI来实现。
      

  27.   


    这段话说的有点问题,更正下:
    实际上这并不是虚函数而是调用链的行为,即在子类的方法执行完毕后调用父类的方法,这样递归调用.如果只想让他做一件事情的话,可以不做递归调用.
    Class1 爷爷
    Class2 父亲 - 包含爷爷的一个实例,实现了爷爷的接口,在爷爷的接口中调用爷爷的相应方法.
    Class3 本人 - 父亲的一个实例,实现了父亲和爷爷的接口,父亲的接口中调用父亲自身的方法,爷爷的接口中调用父亲实例中爷爷接口的方法.这样,Class3(本人)就可以被当作Class2(父亲)和Class1(爷爷)来使用了:)