超类与子类(Superclass Subclass)

2024-04-26 16:48

本文主要是介绍超类与子类(Superclass Subclass),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

超类与子类(Superclass & Subclass)

Q: 我看了WINX开发包中的文档中,你提到了超类,它是什么概念?我平常只听过子类(Subclass)。

A: 子类化(Subclass)是指替换窗口过程(WNDPROC)。
    超类(Superclass)是替换窗口过程(WNDPROC),并且替换ClassName。
   Subclass不太象继承,而像是一种外挂(Hook)行为。
   Superclass则更像继承,因为生成了新的窗口类,并且继承了行为。
   winx中Subclass和Superclass用同一个类实现。都是winx::SubclassWindow。
   其他界面库一般不提供Superclass。
  
Q: 你说其他界面库不提供Superclass?MFC里继承应该属于Superclass吧?

A: 不,MFC中用的是Subclass。

Q: 我怎么感觉不出二者的区别?我是说用法上和结果上。

A: 两者在用法上有异,但获得的结果确实无太大差别。
   我们以Button为例。如果是Subclass,那么用户先要有一个Button,然后Subclass它。
   也就是说Subclass发生在CreateWindow之后。
   如果是Superclass,那么用户CreateWindow的时候直接传入新的窗口类名称,根本就没有Button被生成。
   当然,这要求CreateWindow之前调用过该窗口类的RegisterClass。
   MFC用的是Subclass。因为CButton类通过DDX技术和对话框上的Button关联的。
   也就是说,MFC中是先有了Button,然后由DDX技术Subclass它。
   所以,一般你看不到Subclass流程。
  
Q: 什么情况下需要用SuperClass?
   哦,我明白了,是不是有了SuperClass技术,用户可以很方便的创建自己的Control?
  
A: 对了。不需要从零开始。

Q: 对。感觉多数用户自定义控件还是和系统控件有关系的。

A: 是的。这正是Superclass存在的意义。
   你可以想象一下:在以前,你提供一个控件,你要告诉它,先创建Button,然后调用我的Subclass函数。
   而有了Superclass,现在你只需要告诉它窗口类的名字就可以了。
   因为Superclass隐蔽了你从Button继承这个事实。
  
Q: 对。

A: 之所以winx可以有superclass而其他界面库没有,究其原因,还是与屏蔽“窗口类”这个出发点有关。

Q: 对,对,对。以后自己定义的控件也可以可视化开发。

A: 是的。

Q: 指定一下我们自己的窗口类就可以了。
   WINX这种控件感觉是介于系统控件和ActiveX控件之间的一种控件。

A: 是的。这种控件其实就是Windows系统控件的实现方式。
   只是系统控件不需要你主动注册,Windows已经帮你注册好了。
  
Q: 系统实现这些系统控件不是通过SuperClass吧?它应该是从最一般化的窗口继承而来。

A: 呵呵,当然不是。它们没有什么可以借用的,只好从最基础的winx::Window继承。

Q: 不管是白手起家,还是有点基础,做法都是SuperClass。
   因为winx::Window的基础是DefWindowProc,也是一个窗口过程。
  
A: 可以这么理解。

Q: 是不是可以这样理解,SubClass只是更改了WndProc,而SuperClass还更改了其他窗口属性?

A: 是的。你的理解完全正确,这正是Subclass与Superclass最本质的区别。
   Superclass可以改窗口类(WNDCLASSEX)的任何数据。WINX就是这么实现的。

附录

样例参见:

tutorials/winx/step004-user-ctrl/2.superclass/hello.cpp

子类化样例代码:

//  -------------------------------------------------------------------------
//  class CMyEdit - 使用子类化(Subclass)技术

class  CMyEdit :  public  winx::Edit < CMyEdit >
{
public :
    VOID OnContextMenu(HWND hWnd, winx::CPoint pt)
    {
        
// 禁止了右键菜单...
    }
};

//  -------------------------------------------------------------------------
//  CHelloDlg

class  CHelloDlg :  public  winx::ModalDialog < CHelloDlg, IDD_HELLO >
{
public :
    BOOL OnInitDialog(HWND hDlg, HWND hWndDefaultFocus)
    {
        CMyEdit::DoSubclassDlgItem(hDlg, IDC_EDIT1);
        
return  TRUE;
    }
};

//  -------------------------------------------------------------------------

int  APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     
int        nCmdShow)
{
    CHelloDlg dlg;
    dlg.DoModal();
    
return   0 ;
}

//  -------------------------------------------------------------------------

超类化样例代码:

//  -------------------------------------------------------------------------
//  class CMyEdit2 - 使用超类化(Superclass)技术

class  CMyEdit2 :  public  winx::Edit < CMyEdit2 >
{
    WINX_CLASS(
" MyEdit " );
public :
    VOID OnContextMenu(HWND hWnd, winx::CPoint pt)
    {
        
// 禁止了右键菜单...
    }
};

//  -------------------------------------------------------------------------
//  CHelloDlg

class  CHelloDlg :  public  winx::ModalDialog < CHelloDlg, IDD_HELLO >
{
};

//  -------------------------------------------------------------------------

int  APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     
int        nCmdShow)
{
    CMyEdit2::RegisterClass();
    CHelloDlg dlg;
    dlg.DoModal();
    
return   0 ;
}

//  -------------------------------------------------------------------------

 

这篇关于超类与子类(Superclass Subclass)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/938121

相关文章

c++11工厂子类实现自注册的两种方法

文章目录 一、产品类构建1. 猫基类与各品种猫子类2.狗基类与各品种狗子类 二、工厂类构建三、客户端使用switch-case实现调用不同工厂子类四、自注册方法一:公开注册函数显式注册五、自注册方法二:构造函数隐形注册总结 一、产品类构建 1. 猫基类与各品种猫子类 class Cat {public:virtual void Printer() = 0;};class

获取所有classpath指定包下类的所有子类

1.问题 开发过程中,有时需要找到所有classpath下,特定包下某个类的所有子类,如何做到? 2. 实现 比较常见的解决方案是自己遍历目录,查找所有.class文件。 下面这个方法使用spring工具类实现,简化过程,不再需要自己遍历目录 /*** 获取在指定包下某个class的所有非抽象子类** @param parentClass 父类* @param packagePat

泛型第二课,派生子类、属性类型、方法重写、泛型擦除

子类(实现类) 子类与父类|接口一样使用泛型子类指定具体的类型子类与父类|接口 同时擦除类型子类泛型,父类|接口 擦除错误:不能子类擦除,父类|接口泛型 package com.pkushutong.genericity3;/*** 父类为泛型类* 1、属性* 2、方法* * 要么同时擦除,要么子类大于等于父类的类型* 不能子类擦除,父类泛型* 1、属性类型* 父类中,随父类型定

【大数据Java基础-JAVA 面向对象14】面向对象的特征二:继承性 (三) 关键字:super以及子类对象实例化全过程

关键字:super 1.super 关键字可以理解为:父类的 2.可以用来调用的结构: 属性、方法、构造器 3.super调用属性、方法: 3.1 我们可以在子类的方法或构造器中。通过使用"super.属性"或"super.方法"的方式,显式的调用父类中声明的属性或方法。但是,通常情况下,我们习惯省略"super." 3.2 特殊情况:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类

Drawable 的 子类

从Drawable的继承结构上看,还有几个没有介绍到。 1、ColorDrawable ColorDrawable使用很简单,使用<Color>元素就可以定义一个ColorDrawable,然后再其他的地方使用。 在color.xml文件中定义: [java] view plaincopy <?xml version="1.0" encoding="utf-8"?>  <color

The method xxxx of type xxxx must override a superclass method 解决方式

使用eclipse/myeclipse 时可能会出现@override 报错的问题 The method xxxx  of type xxxx  must override a superclass method 解决方法一: 修改eclipse的 Compiler level  window ---> preferences-->java -->Compiler 把Co

穿越Java世界的继承奇旅:从基类到子类的华丽蜕变

1.为什么要继承 2.什么是继承以及继承的方式 3.继承的一些语法 4.父类成员的访问 5.关键字super 6.关键字protected 7.关键字final 8.继承与组合 一:为什么要继承 ①代码重用:继承允许我们重用、扩展或修改父类的属性和方法,而无需重新编写相同的代码。这有助于减少代码冗余,提高代码的可维护性和可扩展性。 ②实现多态:多态是面向对象编程的三大特性之

scrapy--子类CrawlSpider中间件

免责声明:本文仅做分享参考~ 目录 CrawlSpider 介绍 xj.py 中间件 部分middlewares.py wyxw.py  完整的middlewares.py CrawlSpider 介绍 CrawlSpider类:定义了一些规则来做数据爬取,从爬取的网页中获取链接并进行继续爬取. 创建方式:scrapy genspider -t crawl

OC一般类(简单类,组合类,继承关系的子类)的拷贝

1、对于简单的类而言,如果想要实现拷贝操作,就需要先将这个类遵守NSCopying协议,然后在它的实现文件即.m文件中实现-(id)copyWithZone:(NSZone *)zone方法,在方法内以allocWithZone的方式分配内存,若本类实现有初始化成员方法则直接调用初始化方法并用自身成员变量作为实参对其相应的形参进行赋值 ,然后生成新的对象指针,把新的对象指针返回即可;若本身没有

python 父类与子类的一些说明

Python中类的初始化方法是__init__(),因此父类、子类的初始化方法都是这个,如果子类不实现__init__()这个函数,初始化时调用父类的初始化函数, 如果子类实现了这个函数,则要在这个函数里显式调用一下父类的__init__(),这跟C++,jAVA不一样,他们是自动调用父类构造函数的。 #初始化中调用父类初始化方法示例 #B是A的子类 class B(A):