封装编程
㈠ 编程之封装框架
有了函数封装和封装大项后,有时候调用还是有不少重复卖型的编程代码,为了不做重复的低效复制粘贴,引用框架就显得相当重要,我认为的框架是将重复的代码部分做归纳总结,进一步提炼得出执行框架,重复的部分是框架的组成部分,可变的是调用框架执行代码的部分。
注:可以看我之前的文章描述的关于函数封装(功能小项)和封装大项说明
比如下面是自制的菜单框架YMC,仿MVC,防止递归调用。
菜单是独立操作,当一个菜单调用时,前一个菜单就要退出。
菜单框架分为刷新整个视图,刷新元素视图,菜单变化处理,按键输入、菜单的进入、菜单的退出和定时任务。
菜单框中肢猜架YMC的h文件内容:
typedef struct
{
void (*DrawViewData)(void);//视图数据
void (*DrawViewFrame)(void);//视图窗体
void (*DrawViewChange)(void);//视图数据变化
void (*MenuBtnCtrl)(U32);//控制按键识别
void (*MenuExit)(void);//菜单退出
void (*OnTimer)(void);//定时任务
} _ViewCtrl;
enum
{
TIMER_ONCE,//单次
TIMER_FOR,//永久
TIMER_SEC,//永久秒
};
void YMCCtrl_SetTimer(U8 Opt,U16 Timer);//设置定时
void YMCCtrl_Set(_ViewCtrl *main_Ctrl);//设置菜单主体元素
//Index 第几个元素更新
void SetYMCViewElement(U16 Index);
U8 GetYMCViewElement(U16 Index);
//刷新整个界面元素
void SetYMCViewFrameTrue(void);
//菜单使用的缓存
U8 *YMC_SettempsBuf(void);
void YMC_SettempsBufClear(void);
extern OS_EVENT * msg_YMCkey; //按键邮箱事件块指针主界面键值
extern void (*YMCJumper)(void);
菜单框架YMC的c文件内容:
//全局跳转函数菜单跳转
void (*YMCJumper)(void);
static U8 YMCLastSec;
//菜单使用的缓存
U8 YMC_GETTEMPS[800];
U8 *YMC_SettempsBuf(void)
{
return YMC_GETTEMPS;
}
void YMC_SettempsBufClear(void)
{
memset(YMC_GETTEMPS,0x00,sizeof(YMC_GETTEMPS));
}
typedef struct
{
U16 UpdataDataEle;//更新元素
U8 UpdataMenuFrame:1;//更新整个menu
U8 TimerOpt:2;//0一次,1永久,2秒定时
U8 :0;
U16 Timer;//0,1次数10ms 2次数秒
} ViewSetup; //
static ViewSetup YMCViewDraw= {0};
//更新菜单全部内容
void SetYMCViewFrameTrue(void)
{
YMCViewDraw.UpdataMenuFrame = 1;
}
//Index 第几个位置更新
void SetYMCViewElement(U16 Index)
{
YMCViewDraw.UpdataDataEle |= 1<<index; p=""> </index;>饥唤
}
//更新菜单全部内容
U8 GetYMCViewElement(U16 Index)
{
return ((YMCViewDraw.UpdataDataEle&(1< 0);
}
//设置菜单定时
void YMCCtrl_SetTimer(U8 Opt,U16 Timer)
{
YMCViewDraw.TimerOpt = Opt;
YMCViewDraw.Timer = Timer;
}
static _ViewCtrl YMCCtrl= {0};
void YMCCtrl_Set(_ViewCtrl *main_Ctrl)
{
YMCCtrl = *main_Ctrl;
}
//更新菜单内容
void YMCViewUpdata(void)
{
if(YMCViewDraw.UpdataMenuFrame)//更新菜单全部内容
{
YMCViewDraw.UpdataMenuFrame = 0;
Mutex_Pend();//互斥保护
if(YMCCtrl.DrawViewFrame)
{
YMCCtrl.DrawViewFrame();
}
if(YMCCtrl.DrawViewData)
{
YMCCtrl.DrawViewData();
}
Mutex_Post();
YMCViewDraw.UpdataDataEle = 0;
}
if(YMCViewDraw.UpdataDataEle)//更新菜单元素内容
{
Mutex_Pend();//互斥保护
if(YMCCtrl.DrawViewData)
{
YMCCtrl.DrawViewData();
}
Mutex_Post();
YMCViewDraw.UpdataDataEle = 0;
}
}
//检查当前menu是否改变
static U8 CheckYMCCg(void)
{
static void *func = NULL;
if(YMCJumper != func)
{
func = YMCJumper;
return 1;
}
return 0;
}
//定时
static void CalcOnTimer(U16 *Timer)
{
if(YMCViewDraw.TimerOpt == 0)
{
if(*Timer<=YMCViewDraw.Timer)
{
(*Timer)++;
}
if(*Timer==YMCViewDraw.Timer)
{
YMCCtrl.OnTimer();
}
}
else if(YMCViewDraw.TimerOpt == 1)
{
if(*Timer<=YMCViewDraw.Timer)
{
(*Timer)++;
}
if((*Timer>=YMCViewDraw.Timer)&&(YMCViewDraw.Timer))
{
*Timer = 0;
YMCCtrl.OnTimer();
}
}
else
{
if (YMCLastSec != User_RtcTime.RTC_Seconds)
{
YMCLastSec = User_RtcTime.RTC_Seconds;
if(*Timer<=YMCViewDraw.Timer)
{
(*Timer)++;
}
if((*Timer>=YMCViewDraw.Timer)&&(YMCViewDraw.Timer))
{
*Timer = 0;
YMCCtrl.OnTimer();
}
}
}
}
//YMC菜单框架主函数
void CtrlYMC_Func(void)
{
U8 err;
U32 UserKeyCmd;
U16 Timer = 0;
//默认显示窗体
YMCViewDraw.UpdataMenuFrame = 1;
YMCCtrl_SetTimer(0,0);
YMCLastSec = User_RtcTime.RTC_Seconds;
SetMenuSetupflag(MENUSET_TMDLYCLOSE,MENUSETCLOSEDLY);
YMCJumper();
while(1)
{
YMCViewUpdata();
MenuDelayClose();//菜单定时自动退出,简单分层状态机
if(CheckYMCCg())
{
if(YMCCtrl.MenuExit)
{
YMCCtrl.MenuExit();
CheckYMCCg();
}
Run_SavePlan();//退出时存储菜单数据
return;
}
if(YMCCtrl.DrawViewChange)
{
YMCCtrl.DrawViewChange();
}
if(YMCCtrl.OnTimer)
{
CalcOnTimer(&Timer);
}
UserKeyCmd = (U32)OSMboxPend(msg_YMCkey,10,&err);
if(OS_ERR_TIMEOUT != err)
{
if(YMCCtrl.MenuBtnCtrl)
{
YMCCtrl.MenuBtnCtrl(UserKeyCmd);
}
}
}
}
//执行YMC菜单框架的任务。
void CtrlYMC_task(void *pdata)
{
//跳转到主界面
YMCJumper = Menu_Init_Func;
CheckYMCCg();//初始化菜单跳转
while(1)
{
//跳转函数执行
CtrlYMC_Func();
delay_ms(10);
}
}
菜单主体:(功能大项)
typedef struct {
U8Minute;//分
}MainMenuCg;
MainMenuCg MainMenu_Cg;
//清除当前颜色区
void Dw_Pic_Window_YMCMenu(void)
{
}
//显示窗口控件
void Dw_Pic_Whole_YMCMenu(void)
{
}
/***********************************************************************
* 函数名称 : YMCMenu_Init
* 描述 : 初始化按键值和缓存
* 输入形参 :
* 返回值 :
************************************************************************/
static void YMCMenu_Init(void)
{
}
/***********************************************************************
* 函数名称 : ShowYMCMenu_DataInfo
* 描述 : 显示数据
* 输入形参 :
* 返回值 :
************************************************************************/
static void ShowYMCMenu_DataInfo(void)
{
if (GetYMCViewElement(0))
{
Dw_Element0();
}
if(GetYMCViewElement(1))
{
Dw_Element1();
}
}
/***********************************************************************
* 函数名称 : ShowYMCMenu_DataChange
* 描述 : 数据更改
* 输入形参 :
* 返回值 :
************************************************************************/
static void ShowYMCMenu_DataChange(void)
{
if(YMCMenu_Cg.Minute != User_RtcTime.RTC_Minutes)//全局rtc分比较 1分钟刷一次
{
YMCMenu_Cg.Minute = User_RtcTime.RTC_Minutes;
SetYMCViewElement(1);
}
}
/***********************************************************************
* 函数名称 : YMCMenu_Exit
* 描述 : 退出
* 输入形参 :
* 返回值 :
************************************************************************/
static void YMCMenu_Exit(void)
{
}
/***********************************************************************
* 函数名称 : YMCMenu_Btn
* 描述 : 按键处理
* 输入形参 :
* 返回值 :
************************************************************************/
static void YMCMenu_Btn(U32 UserKeyCmd)
{
switch (UserKeyCmd)
{
case YMCKEY:
{
Func1();
}
break;
case YMCKEY+1:
{
Func2();
}
break;
case YMCKEY+2:
{
MainJumper = YMCMenu2_func;
}
break;
default:
break;
}
}
/***********************************************************************
* 函数名称 : ShowYMCMenu_func
* 描述 : 显示界面
* 输入形参 :
* 返回值 :
************************************************************************/
static void ShowYMCMenu_func(void)
{
Dw_Pic_Window_YMCMenu();
Dw_Pic_Whole_YMCMenu();
SetYMCViewElement(0);
}
/***********************************************************************
* 函数名称 : YMCMenu_func
* 描述 : 界面
* 输入形参 :
* 返回值 :
************************************************************************/
void YMCMenu_func(void)
{
_ViewCtrl YMCCtrl = { 0 };
YMCCtrl.DrawViewData = ShowYMCMenu_DataInfo;
YMCCtrl.DrawViewFrame = ShowYMCMenu_func;
YMCCtrl.DrawViewChange = ShowYMCMenu_DataChange;
YMCCtrl.MenuBtnCtrl = YMCMenu_Btn;
YMCCtrl.MenuExit = YMCMenu_Exit;
YMCCtrl_Set(&YMCCtrl);
YMCMenu_Init();
}
外部引用:void YMCMenu_func(void);
执行菜单跳转:
MainJumper = YMCMenu_func;调用之后
1、进入YMCMenu_func主体函数执行,
2、执行一次初始化YMCMenu_Init,
3、执行一次窗体全部绘制ShowYMCMenu_func
4、循环执行当元素需要刷新时执行ShowYMCMenu_DataInfo里菜单显示元素刷新
5、当有按键按下时识别按键后执行YMCMenu_Btn,执行按键功能
6、当菜单数据变化时执行ShowYMCMenu_DataChange,自动执行变更数据
7、最后当执行MainJumper = YMCMenu2_func;时退出当前菜单执行YMCMenu_Exit
8、再执行进入YMCMenu2_func主体函数执行,重复上诉步骤。
从而完成菜单的初始化、显示,交互,菜单变化处理,退出。
下面是空函数控制,当执行空菜单时相当于执行空的菜单,没有任何菜单显示和控制。
/***********************************************************************
* 函数名称 : VOID_Func
* 描述 : 空菜单控制
* 输入形参 :
* 返回值 :
************************************************************************/
void VOID_Func(void)
{
_ViewCtrl YMCCtrl = { 0 };
YMCCtrl_Set(&YMCCtrl);
}
总结:YMC特点菜单不会递归调用,运行时加载(不使用菜单时不会占用系统资源)
框架是总结整合的东西,类似一个篮筐将独立运行在系统的一个地方,成为一个独立小系统,每次使用是使用一个整体,而不是一个小部分功能。
㈡ 编程中封装是什么意思
封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。(采自java面试题)
㈢ 编程语言中的,封装,继承,多态 怎么解释
网上能找到的都是说的严谨的,如果没理解真没办法一两句说清楚,封装提高了代码可重用性可维扩性,写方法、类都是封装;继承是然将两个或两个以为有共性的成员拿出来写成基类,其根本目的还是提高可重用性,并且也更符日常生活中的面向对象思想。多态是不同对象实例对同一个消息作出不同响应的能力。但这些不同对象实例必须有共性约束,或是父子类的方法继承,或是对同一接口的消息实现,比如:员工类有以下子类:项目经理、前台、程序员,都有一个共同成员方法”开工“,当执行该指令时,不同实例所执行的任务是不一样的
㈣ 请问: 在编程中, 对函数进行封装的目的和好处是什么
封装的目的是便于之后的调用,整体性比较好,同时打包成dll文件后,对自己的源码也是一种保护。
㈤ 3。试叙述面向对象编程封装的好处
封装的意思是说对象数据和操作该数据的指令都是对象自身的一部分,封装能够实现尽可能对外部世界隐藏数据。譬如,当你在某个模块中定义某个变量、常量、函数前声明了关键字Private,你就将它封装了起来,降低了它被外界污染的可能。
将抽象得到的数据成员和代码成员相结合,形成一个有机的整体,也就是将数据与操作数据的行为进行有机 的结合,这就是封装。在面向对象的程序设 计中,通过封装,将一部分成员作
为与外部通讯的接口,将其他 的成员隐藏起来,这样可以使程序中的不同部分的相互依赖减少到最小。
/封装 目的与实现类就是对现实实体或者虚拟对象的抽象表示,抽象就是有
选择 的忽略,而封装就是忽略的具体实现手段。
类就是通过“封装”特性把实现的细节进行隐藏,呈现给用户一个清晰易用的接。
一个类其实有点像一个黑 匣子!
㈥ 在Java面向对象的编程当中的为什么要封装什么叫封装
概念:所谓封装,就是通过定义类并且给类的属性和方法加上访问控制来抽象事物的本质特性.
这个意思:
封装就是定义一个类,然后给该类的 属性(成员变量) 和 方法 加上 访问控制修饰词(public,private,
protected,默认包访问权限),使得该类的属性和方法对于类外部来说,想可见的可见,不想可见的隐藏。
所以,通过封装这个手段,就抽象出来了事物的本质特性。
对上面进行进一步的解释:
什么叫抽象?比如拿 人类 来举例子,封装是一种手段,通过封装定义出来的这个类,和现实当中的人这个实体(对象),他们之间就是一种抽象,我们现实当中只存在一个一个的人(对象),人类只是一个概念性的东西,是我们人自己归纳总结出来的,我们知道人都长什么样,所以我们知道符合这个样子的就叫人,人的大脑总是习惯将事物分类,因此人类的概念就出现了,那么我们发现一个一个的人,都有眼睛鼻子嘴(属性),都能吃饭(方法),等等,这就是人这个事物的本质特性,然后我们得编程啊,人类的概念光在脑海中出现了还不行,还得体现到代码上,那么你想体现到代码上,也就是定义一个类,就要使用封装这个手段。
为什么要加上访问控制?
一是,有些东西是很关键很机密的,不想随便被使用,被改变,被访问。
二是,可能这个东西不是很关键机密,访问和改变也无所谓,但是,因为有些属性和方法,它们对于外部来说,是无关的没用的,但是对于我自己这个类来说,是必要的,因为可能在我自己这个类中要使用它们,这个时候,进行隐藏,不让外部看,好处就是,如果将这些不必要的内容也暴露给外部的话,那么在使用的时候,使用者会被迷惑,因为这个东西对他没用,但是又可以调用,访问,而且他又不知道又没有用,但是如果进行隐藏,不给外部查看,那么就很清晰了,因为这样一来,只要是对外暴露的属性方法,都是有用的,你想一下,JDK的类库里面的那些类,比如String类,对外暴露的属性和方法,哪个是无用的?这也是一种良好的编程习惯和规范。
说了这么多,其实我的理解也有限,面向对象思想又不局限于某种语言,楼主仔细体会一下吧,我说的可能也不全对,这只是我个人的一点理解。
刚才上网搜到了一句话,不是我说的,但我感觉说的也不错,可以仔细体会一下:
封装是人们对现实世界中解决问题时,为了进行简化问题,对研究的对象所采用的一种方法,一种信息屏蔽技术。
㈦ 在Java面向对象的编程当中的为什么要封装什么叫封装
java面向对象编程中所谓封装,就是通过定义类并且给类的属性和方法加上访问控制来抽象事物的本质特性。
封装就是定义一个类,然后给该类的属性(成员变量)和方法加上访问控制修饰词(public,private, protected,默认包访问权限),使得该类的属性和方法对于类外部来说,想可见的可见,不想可见的隐藏。就是把数据和行为结合在一起在一个包中,并对对象使用者隐藏数据的实现过程。Java用3个关键字来设置边界,从而进行对数据的隐藏。Public(共有)的定义任何人都可使用.private(私有)意味着除你自己,类型创建者及那个类型的内部函数成员可以访问外其他任何人使用都会产生错误。Friendly(友好)
意味在包(package)中是可以访问的.
㈧ 封装在所有的编程语言里都有用到吗
封装是面向备毕对象的特性,面向对象大滚锋语言(c++.c#.Java等)都用的到滚晌,面向过程的语言(例如c语言)没见过