深入浅出关键字---base和this

合集下载

【C#】关键字this和base比较

【C#】关键字this和base比较
{
int num;
public BaseClane("in BaseClass()");
}
public BaseClass(int i)
{
num = i;
Console.WriteLine("in BaseClass(int {0})", num);
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Friends Name: {0}", E[i]);
}
Console.ReadLine();
get { return this._age; }
}
// 打印雇员资料
public void PrintEmployee()
{
// 将Employee对象作为参数传递到DoPrint方法
Print.DoPrint(this);
Console.ReadLine();
}
}
/**//*
控制台输出:
in BaseClass()
in BaseClass(1)
*/
注意:
从静态方法中使用 base 关键字是错误的。
base 主要用于面向对象开发的对态这方面,在示例2中有体现。
+++++++++++++++++++++++++++++ 文章二 +++++++++++++++++++++++++++++

this的四种用法及注意事项

this的四种用法及注意事项

this的四种⽤法及注意事项1.代表成员变量我们如何区分开:同名的成员变量和在构造⽅法中的局部变量呢?---⽤this。

package com.dh.oop;public class ThisDemo {public String name;public ThisDemo(String name){//将构造⽅法的参数值赋值给成员变量 = name;}}在构造⽅法中,this代表的就是成员变量。

2.代表当前对象的引⽤我们知道,在实例化对象时,会利⽤构造⽅法进⾏初始化成员变量,所以每调⽤⼀次构造⽅法,初始化的都是正在实例化的这个对象的成员变量,即this,所以在构造⽅法中输出this,结果为当前对象的哈希码值。

对象是引⽤数据类型,直接输出,输出的就是其地址。

package com.dh.oop;public class ThisDemo {public String name;public ThisDemo(){//在构造⽅法中输出this,为当前调⽤构造⽅法实例化对象的哈希码值System.out.println(this);}public static void main(String[] args) {ThisDemo tom = new ThisDemo();ThisDemo jerry = new ThisDemo();}}3.在构造⽅法中使⽤this调⽤其它构造⽅法package com.dh.oop;public class ThisDemo {public String name;public int age;//第⼀个构造⽅法public ThisDemo(String name){//调⽤第⼆个构造⽅法this(name,18);}//第⼆个构造⽅法public ThisDemo(String name,int age) { = name;this.age = age;}public static void main(String[] args) {//调⽤第⼀个构造⽅法ThisDemo tom = new ThisDemo("tom");System.out.println(+"\t"+tom.age);}}分析结果,虽然在main⽅法中调⽤的是第⼀个构造⽅法,但由于在第⼀个构造⽅法中调⽤了第⼆个构造⽅法,所以输出了tom 18。

探讨一下构造函数中base和this的用法与区别

探讨一下构造函数中base和this的用法与区别

探讨一下构造函数中base和this的用法与区别(C#版)探讨一下构造函数中base和this的用法与区别(C#版)这篇文章主要介绍一下在构造函数中base和this的用法和区别的。

接下来的文章会陆续介绍一下静态变量和静态构造函数。

希望大家能够将意见反馈给我。

代码最具有说服性了,看下面代码吧://代码段一public class ConstructorProgram1{private string name;public ConstructorProgram1(){Console.WriteLine("No Info Left");}public ConstructorProgram1(string name){ = name;Console.WriteLine("name=" + );}}这里我重载了另外一个构造函数,里面的this作为一个指针指示了一个类的引用。

即是ConstructorProgram1类的引用。

这个很简单,但不是重点。

这篇文章最重点要说一下:this和base在构造函数中扮演的角色。

看下面的代码:public class ConstructorProgram{private string name;private int age;public ConstructorProgram():this("bell"){//Console.WriteLine("No Info Left.");}public ConstructorProgram(string name):this("Simple Programmer",20){ = name;Console.WriteLine("name=" + );}public ConstructorProgram(string name, int age){ = name;this.age = age;Console.WriteLine("name=" + );Console.WriteLine("age=" + this.age);}public static void Main(){ConstructorProgram cp1= new ConstructorProgram("goal");ConstructorProgram cp2 = new ConstructorProgram();}}运行结果:name=Simple Programmerage=20name=goalname=Simple Programmerage=20name=bell在上面的代码当中,可以看出来这里红色字体的this用来调用ConstructorProgram类的自身的构造函数。

[深入浅出]深入浅出、深入深出、浅入浅出、浅入深出

[深入浅出]深入浅出、深入深出、浅入浅出、浅入深出

[深入浅出]深入浅出、深入深出、浅入浅出、浅入深出[深入浅出]深入浅出、深入深出、浅入浅出、浅入深出篇一 : 深入浅出、深入深出、浅入浅出、浅入深出在网上读到这样一段话:世界上有四种老师,第一种是讲课能深入浅出,很深奥的道理,他能讲得浅显易懂,很受学生的欢迎,这是最好的老师;第二种是深入深出,这样的老师很有学问,但缺乏好的教学方法,不能把深奥的学问讲得浅显易懂,学生学起来就费劲,这也算是好老师;第三种是浅入浅出,这样的老师本身学问不深,但却实事求是,把自己懂的东西讲出来,这也能基本保证质量,也算是个好老师;最糟糕的是第四种老师,浅入深出,本身并无多大学问,却装腔作势,把本来很浅近的道理讲得玄而又玄,让人听不懂。

对比一下,我大概属于第三种。

一般我搞不懂的东西,我会避开不讲,只讲自己弄懂的东西;弄懂多少就讲多少。

学生问我问题,我会结合自己的切身经历告诉他自己碰到同样的问题会怎么做,甚至恨不得亲自示范给他/她看。

我知道有一种老师,他们总是能站在更高的地方给学生方法论方面的指导;我也见过另一种老师,他们对学生提出的问题总不正面回答,而是大谈一番似是而非不着边际的话题。

譬如学生问:老师,我想去云南自助游,应该怎么走,我会告诉他,我去过丽江,当年我是怎么走的。

但学生也许想去的是卢沽湖,我会说那里我没去过,但你可以先到丽江再打听怎样去卢沽湖,或者参照我当年的方法去寻找路线;另一种老师会这样回答:你可以到某某网站或某本书上去了解去那里的路线,并告诉他如何找到那个网站或那本书和出行的注意事项;还有一种老师会说:我写过一篇《自助游的兴起、演变、未来趋势和宏观管理战略》的文章,反响很大,你去找来看看吧,看完就知道怎么去了。

呵呵!篇二 : 深入浅出WinDbg——利用快速定位错误Sharepoint代码的某方法LoadLines中使用了SPSecurity.RunWithElevatedPrivileges此方法两次调用了Common.GetLookupValue,并且问题可能出在这里。

VBS数组深入浅出

VBS数组深入浅出

VBS数组深⼊浅出vbs教程《数组使⽤》rem 定义dim arr(5)rem 赋值arr(0) = 20arr(1) = 2arr(2) = 5arr(3) = 3arr(4) = 1arr(5) = 100rem 访问msgbox(arr(2))rem 遍历for each v in arrmsgbox(v)nextVBS数组在应⽤中没有像其他语句那么⼴泛,VBS数组存在不少功能上的局限性(如⼆维数组的定义、赋值),在使⽤上也没有java等语⾔那么便捷。

下⾯来具体讲解下⼏个数组函数的使⽤⽅式:Array 函数返回包含数组的 Variant。

Array(arglist)arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(⽤逗号分隔)。

如果没有指定此参数,则将会创建零长度的数组。

说明⽤于引⽤数组元素的表⽰符,由跟随有括号的变量名组成,括号中包含指⽰所需元素的索引号。

在下⾯的⽰例中,第⼀条语句创建名为 A 的变量。

第⼆条语句将⼀个数组赋值给变量 A。

最后⼀条语句将包含在第⼆个数组元素中的值赋值给另⼀个变量。

arr = array("t1","t2")MsgBox arr(0)MsgBox arr(1)注意未作为数组声明的变量仍可以包含数组。

虽然包含数组的 Variant 变量与包含 Variant 元素的数组变量有概念上的不同,但访问数组元素的⽅法是相同的。

IsArray 函数返回 Boolean 值指明某变量是否为数组。

IsArray(varname)varname 参数可以是任意变量。

说明如果变量是数组,IsArray 函数返回 True;否则,函数返回 False。

当变量中包含有数组时,使⽤ IsArray 函数很有效。

下⾯的⽰例利⽤ IsArray 函数验证 MyVariable 是否为⼀数组:Dim MyVariableDim MyArray(3)MyArray(0) = "Sunday"MyArray(1) = "Monday"MyArray(2) = "Tuesday"MyVariable = IsArray(MyArray) ' MyVariable 包含 "True"。

深入浅出CDP(ChromeDevToolsProtocol)

深入浅出CDP(ChromeDevToolsProtocol)

深⼊浅出CDP(ChromeDevToolsProtocol)深⼊浅出 CDP (Chrome DevTools Protocol)14 Jan 2020Table of Contents背景⾃从 Chrome 59 发布⽀持 –headless 启动参数以后 (Windows 上是 60 版本), 轻量级浏览器内核就不再是 webdriver ⼀家独⼤, 甚⾄ phantomjs 作者也发⽂表⽰不再维护该项⽬, 国外也有越来越多的⽂章推荐使⽤ headless Chrome 代替过去 selenium + webdriver 的⽅式进⾏ Web 测试或者爬⾍相关⼯作. ⽬前国内实际上使⽤ headless Chrome 的并不少, 只不过⽬前⼤量营销号的存在, 导致为了点击量频繁刷⽂, 进⽽把早年间 selenium ⽤作爬⾍的旧⽂章重新翻到读者眼前, 所以遇到各种稀奇古怪的问题, 初学者使⽤体验较差. selenium 作为⽼牌 Web 测试⼿段闻名已久, 在⾼级功能 API 层⾯⾮常成熟, 后来也加强了对 Chrome headless 模式下 CDP 的⽀持, ⽬前依然拥有⼤量⽤户在使⽤.这⾥, 简单提⼀下 selenium + webdriver ⽅式的⼀些不⾜:1. 默认参数启动时很容易被服务端发现2. 性能与 Chrome headless 相⽐, 较差3. 存在了⽆数年的内存泄漏问题4. 不像 Chrome 有⼤⼚在背后⽀撑, 上千 issues 解决不完5. ⽆法作为完整浏览器使⽤和调试简⽽⾔之, 都 2020 年了, 不要再抱着 selenium 不放了概述CDP交流⽅式通过 HTTP, WebSocket 两种⽅式, 对添加了远程调试接⼝参数( --remote-debugging-port=9222 )的浏览器进⾏远程调试, ⼤部分功能其实与浏览器⼿机打开的 devtools ⼀致1. HTTP 负责总览当前 Tabs 信息2. 每个 Tab 的对话使⽤ WebSocket 建⽴连接, 并接收已开启功能 (enabled domain) 的事件消息.Headless Browser俗称的⽆头浏览器, 实际上就是没有图形界⾯的浏览器, 因为省去了视觉渲染的⼯作, 性能和开销有较⼤优化, 粗略估计, 原本只能启动⼗个浏览器的内存, 使⽤ Headless 模式可以⾄少启动三倍的数量常见⽤途1. 主要还是 Web 测试2. 少数情况会⽤来做爬⾍, 所见即所得的调试体验⾮常容易上⼿3. 有⼀些 Web ⾃动化的⼯作, 可以替代⾃⼰写扩展或者 tampermonkey JS 脚本, 毕竟权限更⾼更全⾯, GUI 模式调试完以后, ⽆⼈参与操作的多数情况, 则可以⽆痛改成 –Headless 模式来提⾼性能常见问题1. Chrome 浏览器有⼀个并发连接数的限制. 即对同⼀个⽹站, 只允许建⽴最多 6 个连接(纯静态情况下, 可以看作是 6 个同 domain 的 Tabs). 如果真的遇到超过 6 个连接的需求, 可以通过新开⼀个浏览器实例来解决.2. 对于 Linux 来说, ⼦进程处理不正确会导致出现僵⼫进程/孤⼉进程, 导致⽩⽩浪费资源, 时间长了整台服务器的内存都会垮掉. 常见解决⽅案有 3 种1. 将 Chrome 守护进程 (Daemon) 与业务代码隔离, 随需要启动对应数量的 Chrome 实例2. 就 Python subprocess 这个内置模块来说, 确定每次关闭的时候执⾏正确的姿势1. 调⽤ Browser.close 功能 gracefully 地关闭浏览器2. 然后 terminate ⼦进程后, 记得 wait ⼀下消息3. 最后保险起见可以再加个 kill, 虽然实际没什么⽤3. 最简单的其实是找到 chrome 实例的进程 ID 来杀, 毕竟杀死以后, subprocess 那边⽴刻就结束了3. 神奇的是, 除了 chrome 实例有僵⼫进程, 连 tab 也会存在⼀些看不见 ( /json ⾥那些⾮ “page” 类型的就是了)或关不掉(僵⼫标签页)的 tab 页1. ⽬前这种 tab 不确定会不会⾃⼰关闭, 访问 B 站遇到过2. 以前我处理这种 tab 的⽅式是给每个 tab 设定⼀个 lifespan, 异步⼀个循环, 扫描并关闭那些⾮ page 类型或者寿命超时了的 tab3. 然⽽ tab 数量多了以后, 反⽽会出现很多⽆法关闭的僵⼫ tab, 通过 /json/close 或者发送 Page.close 事件都⽆效, 暂时只好重启 chrome 实例来清理4. 拿来做爬⾍还有⼏个问题没解决1. chronium 开发团队本着 “你并不是真的特别需要” 原则, 没有动态挂代理的开发意向, 毕竟⼈家也不太希望⼈们拿它来做爬⾍, 只能指望不同代理 IP 启动多个 chrome 实例来解决2. 在 “⾮ headless” 情况下, 可以通过代理扩展, 或者 pac ⽂件, 来搞定动态代理的问题3. 在 headless 的模式, 那就只好从 upstream ⾓度搞了, 甚⾄挂上 mitmproxy 也⾏吧4. ⾄于动态修改 UA, 暂时可以⽤扩展来搞, 不过如果喜欢钻研, 可以发现 CDP ⾥⽀持动态修改 Request 的各项属性, 在这⾥改 headers 是有效的⽂档常⽤功能Chrome DevTools Protocol ⽂档的使⽤, 主要还是使⽤⾥⾯的检索功能, 不过最常⽤的还是以下⼏个领域1. Page1. 简单地理解, 可以把⼀个 Page 看成⼀个 Page 类型的 Tab2. 对 Tab 的刷新, 跳转, 停⽌, 激活, 截图等功能都可以找到3. 也会有很多有⽤的事件需要 enable Page 以后才能监听到, ⽐如 loadEventFired4. 多个⽹站的任务, 可以在同⼀个浏览器⾥打开多个 Tab 进⾏操作, 通过不同的 Websocket 地址进⾏连接, 相对隔离, 并且托异步模型的福, Chrome 多个标签操作的抗压能⼒还不错5. 然⽽并发操作多个 Tab 的时候, 可能会出现⼀点⼩问题需要注意: 同⼀个浏览器实例, 对⼀个域名只能建⽴ 6 个连接, 这个不太好改; 过快⽣成⼤量 Tab, 可能会导致有的 Tab ⽆法正常关闭(zombie tabs)2. Network1. 和产⽣⽹络流量有关系的⼤都在这个 Domain2. ⽐如 setExtraHTTPHeaders / setUserAgentOverride 对当前标签页的所有请求修改原是参数3. ⽐如对 cookie 的各种操作4. 通过 responseReceived + getResponseBody 来监听流量, 只⽤前者就能嗅探到 mp4 这种特殊类型的 url 了, ⽽后者可以把流量⾥已经 base64 化的数据进⾏其他操作, ⽐如验证码图⽚的处理3. 其他功能也基本和 devtools ⼀致常规姿势1. 和某个 Tab 建⽴连接2. 通过 send 发送你想使⽤的 methods3. 通过 recv 监听你发送 methods 产⽣的事件, 或者其他 enable 的事件, 并执⾏对应回调实践准备⼯作1. 安装 chrome 浏览器2. 安装 Python3.7pip install ichrome -Uichrome 库是可选的, 主要是为了演⽰通过 HTTP / Websocket client 与 chrome 实例实现通信ichrome 库除了协程实现, 也有⼀个同步实现, 观察它的源码⽐协程版本的更直观⼀点, 也易于学习启动调试模式下的 chromefrom ichrome import ChromeDaemondef launch_chrome():with ChromeDaemon(host="127.0.0.1", port=9222, max_deaths=1) as chromed:chromed.run_forever()if __name__ == "__main__":launch_chrome()以上代码负责启动 chrome 调试模式的守护进程, 具体参数如下:1. **chrome_path: **表⽰ chrome 的可执⾏路径 / 命令, 默认为 None 的时候, 会⾃动根据操作系统去尝试找寻 chrome 路径, 如 linux 下的 google-chrome 和 google-chrome-stable, macOS 下的 /Applications/Google Chrome.app/Contents/MacOS/Google Chrome, 或者Windows 下的1. C:/Program Files (x86)/Google/Chrome/Application/chrome.exe2. C:/Program Files/Google/Chrome/Application/chrome.exe3. “%s\AppData\Local\Google\Chrome\Application\chrome.exe” % os.getenv(“USERPROFILE”)2. **host: ** 默认为 127.0.0.1, 之所以不⽤ localhost, 是因为很多 Windows / macOS 的 etc/hosts ⽂件⾥被强制绑定到了 ipv6 地址上3. **port: ** 默认为 92224. **headless: ** 常见参数 –headless, –hide-scrollbars, 放在初始化参数⾥了5. **user_agent: ** 常见参数 –user-agent6. **proxy: ** 常见参数 –proxy-server7. **user_data_dir: ** 避免 chrome 到处乱放 user data, 所以默认会放到 user ⽬录下的 ichrome_user_data ⽂件夹下, 命名按端⼝号chrome_92228. **disable_image: ** 常⽤参数 –blink-settings=imagesEnabled=false, 从 blink 层⾯禁⽤, ⽐其他禁⽌图⽚加载的⽅式要靠谱9. **max_deaths: ** ⽤来⾃动重启, max_deaths=2 表⽰快速杀死 chrome 实例 2 次才能避免再次⾃动重启, 所以默认为 110. **extra_config: ** 就是添加其他更多 chrome 启动的参数, 参数类型为 list启动带图形界⾯的 chrome 之后, 可以⼿动尝试下通过 http 请求和 chrome 实例通信了1. 访问 , 会拿到⼀个列出当前 tabs 信息的 json2. 其他操作参考 (HTTP Endpoints 部分)[{"description": "","devtoolsFrontendUrl": "/devtools/inspector.html?ws=127.0.0.1:9222/devtools/page/E6826ED4A0365605F3234B2A441B1D03","id": "E6826ED4A0365605F3234B2A441B1D03","title": "about:blank","type": "page","url": "about:blank","webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/page/E6826ED4A0365605F3234B2A441B1D03"}]操作 Tab1. 建⽴到 webSocketDebuggerUrl 的 Websocket 连接, 然后监听事件2. ⼤部分功能 ichrome 已经打包好了from ichrome import AsyncChromeimport asyncioasync def async_operate_tab():chrome = AsyncChrome(host='127.0.0.1', port=9222)if not await chrome.connect():raise RuntimeErrortab = (await chrome.tabs)[0]async with tab():# 跳转到 httpbin, 3 秒 loading 超时的话则 stop loadingawait tab.set_url('', timeout=3)# 注⼊ js, 并查看返回结果result = await tab.js("document.title")title = result['result']['result']['value']# 打印 titleprint(title)# # 通过 js 修改 titleawait tab.js("document.title = 'New Title'")# click ⼀个 css 选择器的位置, 跳转到了 Githubawait tab.click('body > a:first-child')# 等待加载完成await tab.wait_loading(3)async def callback_function(request):if request:# 监听到经过过滤的流量, 等待它加载⼀会⽐较保险for _ in range(3):result = await tab.get_response(request)if result.get('error'):await tab.wait_loading(1)continue# 拿到整个 htmlbody = result['result']['body']print(body)def filter_func(r):url = r['params']['response']['url']print('received:', url)return url == 'https:///'# 监听流量, 需要异步处理, 则使⽤ asyncio.ensure_future 即可# 监听 10 秒task = asyncio.ensure_future(tab.wait_response(filter_function=filter_func,callback_function=callback_function,timeout=10),loop=tab.loop)# 点击⼀下左上⾓的⼩章鱼则会触发流量await tab.click('[href="https:///"]')# 等待监听流量await taskif __name__ == "__main__":asyncio.run(async_operate_tab())总结CDP 单单⼊门的话, 其实没想象中那么复杂, chrome 59 刚出的时候, puppeteer 都没的⽤, 更别说 pyppeteer 之类的包装, 看了⼏个早期项⽬的源码, 发现简单使⽤的话, 其实主要就是:1. HTTP2. Websocket3. Javascript4. Protocolpyppeteer 诞⽣之初曾体验了⼀下, 第⼀步就因为⼀些不可抗⼒导致下载 chromium 失败, 所以之后只能阅读⼀下⾥⾯⼀些有意思的源码, 主要看了下如何从 puppeteer 原⽣事件驱动转为 Python ⾓度的事件, pyee 的使⽤也让⼈眼前⼀亮之后⾃⼰摸索过程中也碰到了各种各样问题, 除了上⾯提到的, 其实还遇到 Websocket 粘包(粘包本⾝就是个因为理解不⾜导致的伪命题), Chrome Headless 阉割掉了很多基础功能也使开发过程中总是⽆理由地调试失败, 甚⾄关闭 user-dir 使⽤匿名模式导致⼀系列不知名故障也是费⼼费⼒, 不过总体来说收获颇⼤⽤ Python 来操作 chrome 能做的事情挺多, 尤其是各路签到爬⾍, 或者索取微信公众平台⼤概 20 ⼩时有效期的 cookie / token 给后台爬⾍使⽤, 采集视频, ⾃动化测试时候截图, 启动 Headless 模式以后节省了很多⼿动操作的时间, 甚⾄可以丢到⽆ GUI 的 linux server 上去. 要知道以前指望的还是 tampermonkey 或者⼿写扩展, 很多 Python 的功能只能转 js 再⽤, 劳⼼劳⼒.。

this关键字的作用

this关键字的作用

this 关键字的作用this 关键字的作用this 关键字的用法1.this 是指当前对象自己。

当在一个类中要明确指出使用对象自己的的变量或函数时就应该加上this 引用。

如下面这个例子中: 矚慫润厲钐瘗睞枥庑赖賃軔朧。

public class Hello {String s =public Hello(String s){System.out.println(System.out.println(this.s = s;System.out.println(}public static void main(String[] args) {Hello x=}}运行结果:s = HelloWorld!1 -> this.s = Hello2 -> this.s = HelloWorld!在这个例子中, 构造函数Hello 中,参数s 与类Hello 的变量s 同名, 这时如果直接对s 进行操作则是对参数s 进行操作。

若要对类Hello 的成员变量s 进行操作就应该用this 进行引用。

运行结果的第一行就是直接对构造函数中传递过来的参数s 进行打印结果; 第二行是对成员变量s 的打印; 第三行是先对成员变量s 赋传过来的参数s 值后再打印,所以结果是HelloWorld! 聞創沟燴鐺險爱氇谴净祸測樅。

2.把this 作为参数传递当你要把自己作为参数传递给别的对象时,也可以用this 。

如: public class A {public A() {new B(this).print();}public void print() {System.out.println(}}public class B {A a;public B(A a) {this.a = a;}public void print() {a.print();System.out.println(}}运行结果:Hello from A!Hello from B!在这个例子中,对象 A 的构造函数中, 用new B(this) 把对象 A 自己作为参数传递给了对象 B 的构造函数。

PHP常用的关键字

PHP常用的关键字

PHP常用的关键字PHP常用的关键字PHP可编译成具有与许多数据库相连接的函数。

将自己编写外围的函数去间接存取数据库。

通过这样的途径当更换使用的数据库时,可以轻松地修改编码以适应这样的变化。

下文yjbys店铺为大家分享的是PHP常用关键字,一起来看看吧!final:在PHP中final关键字充当锁的作用,当定义类的时候该类不能被继承,当用来定义方法的时候该方法不能被重载self:用来访问当前类中内容的关键字,类似于$this关键字,但$this需要类实例化后才能使用,$this不能够访问类中的静态成员,self可以直接访问当前类中的`内部成员,包括静态成员。

$this关键字类实例化后可以使用,也可以在类的内容访问非静态化成员static:单独占据内存,只初始化一次,访问静态成员要用::,类中的静态成员和方法可以直接访问,不需要实例化const:用来定义类中的常量,类似PHP外部定义的常量的关键字define();CONSET只能修饰类当中的成员属性!常量建议都大写,不使用$关键字是不需要加$的。

在类中访问常量也是用self关键字举例:/** Created on 2012-2-12** To change the template for this generated file go to* Window - Preferences - PHPeclipse - PHP - Code Templates */abstract class cl1{static $ss='我的电脑';//静态成员变量public $aa='你的电脑';abstract function fun1();abstract function fun2();abstract function fun3();function ok(){echo self::$ss;//在类的内部访问static成员也要用的self关键字echo $this->aa;}}class cl2 extends cl1{function fun1(){}function fun2(){}function fun3(){return 1;}}$instance=new cl2();echo $instance->fun3().$instance->ok();echo cl1::$ss;//无需实例化也可以访问到变量ss?>【PHP常用的关键字】。

C++关键字及说明解释

C++关键字及说明解释

C++关键词asmautobad_castbad_typeidboolbreakcasecatchcharclassconstconst_castcontinuedefaultdeletedodoubledynamic_cast elseenumexcept explicit externfalsefinallyfloatforfriendgotoifinlineintlongmutable namespaceoperator private protected publicregister reinterpret_cast returnshortsignedsizeofstaticstatic_caststructswitch templatethistruetrytype_infotypedeftypeid typename unionunsignedusingvirtualvoidvolatilewchar_t whileasm已经被__asm替代了,用于汇编语言嵌入在C/C++程序里编程,从而在某些方面优化代码.虽然用asm关键词编译时编译器不会报错,但是asm模块的代码是没有意义的.(2)auto这个这个关键词用于声明变量的生存期为自动,即将不在任何类、结构、枚举、联合和函数中定义的变量视为全局变量,而在函数中定义的变量视为局部变量。

这个关键词不怎么多写,因为所有的变量默认就是auto的。

(3)bad_cast,const_cast,dynamic_cast,reinterpret_cast,static_cast关于异常处理的,还不是太了解..(4)bad_typeid也是用于异常处理的,当typeid操作符的操作数typeid为Null指针时抛出.(5)bool不用多说了吧,声明布尔类型的变量或函数.(6)break跳出当前循环.The break statement terminates the execution of the nearest enclosing loop or conditional statement in which it appears.(7)caseswitch语句分支.Labels that appear after the case keyword cannot also appear outside a switch statement.(8)catch,throw,try都是异常处理的语句,The try, throw, and catch statements implement exception handling.(9)char声明字符型变量或函数.(10)class声明或定义类或者类的对象.The class keyword declares a class type or defines an object of a class type.(11)const被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。

C#关键字详解

C#关键字详解

1第一部分2访问关键字:base,this3base访问基类的成员。

用于从派生类中访问基类的成员,1.调用基类上已经被重写的方法。

2.指定创建派生类实例时应调用的基类构造函数。

**对基类的访问只能在派生类的构造函数实例的方法实例的属性访问器中。

属性访问器:get,set函数。

注意:!!!!!!!!!不能在静态方法中使用base关键字。

例:在子类的方法中写base.GetInfo();调用基类的方法。

基类中的构造函数重载了,Mybase()和Mybase(int i);在子类的构造函数中public MyDerived():base(int i)public MyDerived(int i):base()this:引用当前对象。

用于引用为其调用方法的当前实例。

静态成员函数没有this指针。

可以用于从构造函数,实例方法,实例访问器中访问成员。

this的一般用途:1.限定被相似的名子隐藏的成员public void A(int a, int b ){this.a=a;this.b=b;}2.将对象作为参数传递到函数中public void ShowInstance(){print(this);console.writeline("lalalalllalalala");}3.声明索引器public int this[int param]{get{ return array[param]; }set{ array[param]=value; }}注意!!!!!!静态方法,静态属性访问器或字段声明中不能用this。

二.转换关键字:explicit, implicit, operator1explicit:用于声明用户定义的显式类型转换运算符。

例:class MyType{public static explicit operator MyType(int i){//从int显式转换成MyType类型的代码!!!}}显式类型转换符必须通过类型转换调用。

IPSecVPN详解(深入浅出简单易懂)讲解

IPSecVPN详解(深入浅出简单易懂)讲解

IPSec VPN详解1.IPSec概述IPSec(ip security)是一种开放标准的框架结构,特定的通信方之间在IP 层通过加密和数据摘要(hash)等手段,来保证数据包在Internet 网上传输时的私密性(confidentiality) 、完整性(data integrity)和真实性(origin authentication)。

IPSec只能工作在IP层,要求乘客协议和承载协议都是IP协议1.1.通过加密保证数据的私密性★私密性:防止信息泄漏给未经授权的个人★通过加密把数据从明文变成无法读懂的密文,从而确保数据的私密性1.2.对数据进行hash运算来保证完整性★完整性:数据没有被非法篡改★通过对数据进行hash运算,产生类似于指纹的数据摘要,以保证数据的完整性对数据和密钥一起进行hash运算★攻击者篡改数据后,可以根据修改后的数据生成新的摘要,以此掩盖自己的攻击行为。

★通过把数据和密钥一起进行hash运算,可以有效抵御上述攻击。

DH算法的基本原理1.3.通过身份认证保证数据的真实性★真实性:数据确实是由特定的对端发出★通过身份认证可以保证数据的真实性。

常用的身份认证方式包括:Pre-shared key,预共享密钥RSA Signature,数字签名1.3.1.预共享密钥预共享密钥,是指通信双方在配置时手工输入相同的密钥。

1.3.2.数字证书★RSA密钥对,一个是可以向大家公开的公钥,另一个是只有自己知道的私钥。

★用公钥加密过的数据只有对应的私钥才能解开,反之亦然。

★数字证书中存储了公钥,以及用户名等身份信息。

2.IPSec框架结构2.1.IPSec安全协议IPSec安全协议描述了如何利用加密和hash来保护数据安全★AH (Authentication Header) 网络认证协议,只能进行数据摘要(hash) ,不能实现数据加密ah-md5-hmac、ah-sha-hmac★ESP (Encapsulating Security Payload) 封装安全载荷协议,能够进行数据加密和数据摘要(hash)esp-des、esp-3des、esp-md5-hmac、esp-sha-hmac2.2.IPSec封装模式IPSec支持两种封装模式:传输模式和隧道模式◆传输模式:不改变原有的IP包头,通常用于主机与主机之间。

函数上下文

函数上下文

函数上下文在编程语言中,函数是代码中的一个主要组件,它是一段可以重复调用的代码块,通常用于实现特定任务。

在函数的执行过程中,代码会在函数的作用域内运行,这个作用域就是函数上下文。

本文将探讨函数上下文的概念,功能,以及一些相关的注意事项。

函数上下文是什么?函数上下文指的是当前正在运行的函数所在的范围。

它是一个包含了函数参数和本地变量的环境,函数在执行时会使用这个环境中的变量。

函数上下文可以看作是在函数调用过程中的一个临时存储区,它包含了所有该函数的执行状态和数据。

函数上下文的重要性在于任何函数的执行都依赖于这个上下文。

在函数被调用时,上下文会被创建并传递给函数。

当函数执行结束后,它的上下文也会被销毁。

函数上下文的组成函数上下文由以下几个部分组成:1. 变量环境 (Variable Environment) - 变量环境是一个包含了在函数上下文中声明的所有变量的对象,它还包括了函数的参数和函数声明。

2. 词法环境 (Lexical Environment) - 词法环境是一个包含了在函数上下文中创建的所有变量的对象,它具有词法作用域。

当函数被调用时,词法环境会被创建。

3. this关键字 - this关键字是特殊的变量,它在函数执行时指向当前的执行上下文。

4. 还有一些其他的细节,比如函数返回值、函数执行的位置等等。

函数上下文的作用函数上下文的主要作用是在函数执行过程中保存和管理变量和对象。

每次函数被调用时,上下文会创建一个新的作用域来执行函数,这个作用域中包含了所有函数需要使用的变量和对象。

在函数执行期间,函数可以通过访问上下文中的变量和对象来完成任务。

当函数执行完成后,上下文就被销毁,其中所有的变量和对象都被删除。

这种方式可以防止变量污染或数据泄露。

函数上下文的注意事项1. 函数上下文是堆栈式的。

每次函数调用时,它的上下文会被压入堆栈中。

当函数执行结束后,上下文就会从堆栈中弹出。

如果函数内部还有其他函数被调用,那么它们的上下文也会被添加到堆栈中。

C# base关键字用法详解

C# base关键字用法详解

C#base关键字比较常用,现在我根据自己所学,结合各方面的例子,写了下面一个使用base的比较经典代码(自吹)。

由于属性和方法都可以使用base从派生类向父类中调用,所以这里只涉及方法的base调用,举一反三。

源码如下:【VS2008 .NET3.5】using System;namespace VirtualTest{class VirtualTest{/// <summary>/// 求面积的普通类,提供继承扩展/// </summary>public class Dimensions{public const double PI = Math.PI;protected double x, y; //只能被当前类或继承子类使用/// <summary>/// 普通面积类构造函数/// </summary>public Dimensions(){}/// <summary>/// 普通面积类构造函数重载/// </summary>/// <param name="x">输入x边</param> /// <param name="y">输入y边</param> public Dimensions(double x, double y) {this.x = x;this.y = y;}/// <summary>/// 虚拟方法可被继承子类改写/// </summary>/// <returns>面积大小</returns>public virtual double Area(){return x * y;}}public class Circle : Dimensions{/// <summary>///指定创建派生类实例时应调用的基类构造函数 /// </summary>/// <param name="r">半径</param>public Circle(double r): base(r, 0){}public override double Area(){return PI * x * x;}}class Sphere : Dimensions{public Sphere(double r): base(r, 0){}public override double Area(){return 4 * PI * x * x;}}class Cylinder : Dimensions{public Cylinder(double r, double h): base(r, h){}public override double Area(){return 2 * PI * x * x + 2 * PI * x * y; }}static void Main(string[] args){double r = 3.0, h = 5.0;Dimensions c = new Circle(r);Dimensions s = new Sphere(r);Dimensions l = new Cylinder(r, h);Console.WriteLine("Area of Circle = {0:F2}", c.Area());Console.WriteLine("Area of Sphere = {0:F2}", s.Area());Console.WriteLine("Area of Cylinder = {0:F2}", l.Area());Console.ReadKey();}}}/*【base 关键字知识点】1.用于从派生类中访问基类的成员:调用基类上已被其他方法重写的方法。

Android深入浅出之AudioPolicy

Android深入浅出之AudioPolicy
enum forced_config {强制_配置,看名字好像是强制使用设备吧,比如外放,耳机,蓝牙等 FORCE_NONE, FORCE_SPEAKER, FORCE_HEADPHONES, FORCE_BT_SCO,
FORCE_BT_A2DP, FORCE_WIRED_ACCESSORY, FORCE_BT_CAR_DOCK, FORCE_BT_DESK_DOCK, NUM_FORCE_CONFIG, FORCE_DEFAULT = FORCE_NONE //这个,太无聊了。 };
setSpeakerphoneOn(true),看看实现。 这次我没再浪费时间了,我用一个新的工具 coolfind,把搜索 framework 目录,寻找*.java 文件, 匹配字符串 setSpeakerphone。终于,我在 framework/base/media/java/android/media/AudioService.java 中找到了。 public void setSpeakerphoneOn(boolean on){
ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); }
2.1 new AudioFlinger
前面说过,instantiate 内部会实例化一个对象,那直接看 AF 的构造函数。
AudioFlinger::AudioFlinger() : BnAudioFlinger(),//基类构造函数 mAudioHardware(0), mMasterVolume(1.0f), mMasterMute(false), mNextThreadId(0)
#else ...

深入浅出MFC

深入浅出MFC

CShape::setcolor(2, (CRect*)&rect1); CShape::setcolor(3, (CRect*)&rect2);
Index

類別及其成員-談封裝(encapsulation) 基礎類別與衍生類別-談繼承(Inheritance) This指標


Example(cont’)
#0028 class CSquare : public CRect #0029 #0030 public: #0031 void display() { ... } #0032 }; // 四方形是一種矩形
Example(cont’)
CSquare square; //宣告一個矩形名為square CRect rect1, rect2; //宣告兩個四方形 CCirclቤተ መጻሕፍቲ ባይዱ circle;
compile
class CShape { ... public: void setcolor(int color, (CShape*)this) { this->m_color = color; } };
CRect::setcolor(2, (CRect*)&rect1); CRect::setcolor(3, (CRect*)&rect2);

四方形(Csquare)


color(資料) Display(行為)
Example-Csquare (cont’)

{
對Csquare物件的描述:
class CSquare // 常常我們以C 作為類別名稱的開頭
private:
int m_color; public: void display() { ... } // 通常我們以m_ 作為成員變數的名稱開頭

Java语言中this关键字的用法详解_王丽丽

Java语言中this关键字的用法详解_王丽丽
由运行结果可以看出,通过n a m e=n a m e并没有正确的将内
容赋给中
的,跟类中的属性完全不沾边。
另外,这个程序代码中,有一个成员变量n a m e,同时在方
法中有个形式参数,参数名也是n a m e。然后在方法中将形式参
数name的值传递给成员变量name。虽然我们可以看明白这个代
}
public Student (String name)
{ System.out.println("新对象实例化") ; = name ;
}
public Student (String name,int age) // 通过构造方
法赋值
{
System.out.println("新对象实例化") ;
也是相同的道理。在方法体内定义的变量称为局部变量,在类的 内部方法体的外部定义的变量称为成员变量。如果成员变量和方 法中的局部变量的名字相同时,那么在方法中成员变量将会被屏 蔽。如果这个时候还要使用成员变量,就需要使用关键字t h i s。 使用this引用成员变量的方法格式:this.成员变量名。
“this(参数列表)”的形式完成,用this修改以上的代码如下:
class Student
{ private String name ; private int age ; public Student(){
System.out.println("新对象实例化") ; } public Student (String name)
示出哪一个是类中的属性,就要加上“t h i s.属性名称”的操作,
将student类的代码改进如下:
class Student { private String name;

深入浅出binder机制

深入浅出binder机制

{ if (gProcess != NULL) return gProcess;---->第一次进来肯定不走这儿 AutoMutex _l(gProcessMutex);--->锁保护 if (gProcess == NULL) gProcess = new ProcessState;--->创建一个 ProcessState
2.1 ProcessState
第一个调用的函数是 ProcessState::self(),然后赋值给了 proc 变量,程序运行完,proc 会 自动 delete 内部的内容,所以就自动释放了先前分配的资源。 ProcessState 位置在 framework\base\libs\binder\ProcessState.cpp
, mVMStart(MAP_FAILED)//映射内存的起始地址 , mManagesContexts(false) , mBinderContextCheckFunc(NULL) , mBinderContextUserData(NULL) , mThreadPoolStarted(false) , mThreadPoolSeq(1) { if (mDriverFD >= 0) { //BIDNER_VM_SIZE 定义为(1*1024*1024) - (4096 *2) 1M-8K
二 MediaService 的诞生 MediaService 是一个应用程序,虽然 Android 搞了七七八八的 JAVA 之类的东西,但是在本 质上,它还是一个完整的 Linux 操作系统,也还没有牛到什么应用程序都是 JAVA 写。所以, MS(MediaService)就是一个和普通的 C++应用程序一样的东西。 MediaService 的源码文件在: framework\base\Media\MediaServer\Main_mediaserver.cpp 中。让我们看看到底是个 什么玩意儿!

this,super关键字

this,super关键字

this和super 和
• private String strain;//品种在子类中使用 在子类中使用this的前提就是 在子类中使用 的前提就是 父类中存在无参构造。 父类中存在无参构造。 • public Dog(String strain){this();父类必须存在无参 父类必须存在无参 • this.strain=strain;} • public Dog(String name1,String strain){ • super(name1);显式调用父类有参 显式调用父类有参 • this.strain=strain; } • public Dog(){ } • 如果子类的构造函数中没有通过 子类的构造函数中没有通过super显式调用父类的有 子类的构造函数中没有通过 显式调用父类的有 参构造方法,则系统默认会调用父类的无参构造方法 系统默认会调用父类的无参构造方法。 参构造方法 系统默认会调用父类的无参构造方法 this(),super()不能用于同一个构造 不能用于同一个构造因为他们都要位于构造 不能用于同一个构造 的第一条语句.
this和static的区别 和 的区别
• static修饰 修饰的属性和方法称为类属性 类变 类属性(类变 修饰 类属性 类方法.不用static修饰的属性和方法 量)和类方法 类方法 称为实例属性 实例变量 实例方法 实例属性(实例变量 实例方法。 实例属性 实例变量),实例方法 • this指的是当前实例【不能使用类方法中】。 当前实例【 当前实例 不能使用类方法中】 • 由于静态成员函数存在于类一级 静态成员函数存在于类一级,并且不 静态成员函数存在于类一级 是对象的一部分,因此没有 this 指针。在 没有 指针 静态方法中引用 this 是错误的。

深入浅出复合事件处理

深入浅出复合事件处理

CEP关键过程
格式化 预处理 模式侦测 事件发派 报警
CEP关键模块
3 件接入 模块
4 预处理 模块
1 EPL 解析器
6 据模型 模块
5 EP规则 引擎
2 则管理 模块
7 件发派 模块
8 动模块
CEP辅助工具
规则制作工具 报表输出工具 实时仪表板
事件接入 模块
EPL解析器
预处理 模块
EPL 解析器
对内外:防止资损 银行、商户、用户错帐;内部错帐
对内:业务状况监控 趋势因应、营销决策、风险规避
商业CEP产品
难得有微软没做的领域? 微软即将推出StreamInsight
CEP关键技术
CEP 关键字
• Streaming - 连续不间断 - 实时处理
• Base - 资料量大 -数据库
• Insight - 有用的信息 -智能
分「总督系统」都能做到!
这么强大?不会只是 宣传噱头吧?
冤枉呀!大人。 总督系统通过状态机引擎运行监 控规则,只要编写各式各样的总 督规则,就可做各种不同的监控。 而这总督规则就是程序,可以做 任何的事,任何数学计算与逻辑
运算都难不倒它。
这么强大,给本府一 套玩玩。
大人你有所不知,因为小的编程能 力有限,所以系统现在还有很多 BUG,不太稳定。加上人力短缺, 开发进度一直快不起来,估计最快 还要两三季才能完善整个系统。
ORDER BY INSERT INTO

CEP
CEP-EPL
RETAIN MATCHING
OUTPUT …
无误报警,但漏网之鱼很多…
有误报警,但无漏网之鱼
有误报警,漏网之鱼很少
无误报警,无漏网之鱼… YA!

《深入浅出数据分析》术语翻译对照

《深入浅出数据分析》术语翻译对照

《深入浅出数据分析》术语翻译对照英语 中文alternative hypothesis 备择假设base rate 基础概率baseline 基准belief 信念binomial formula 二项式定理bins 区间Box models 盒子模型causal connections 因果关系causal diagram 因果图central tendency 集中趋势chance error 机会误差,又称“随机误差” Chi Squared Test 卡方检验class interval 组距command 指令comparison 比较,比较因子conditional probability 条件概率confidence interval 置信区间confounder 混杂因素Constraint 约束条件control 控制,也称“对照” Control group 控制组correlation coefficient 相关系数 dependent variable 应变量deviation 偏差dot plot 散点图empirical data 实证数据empirical test 实证检验Evaluate 评估exploratory data analysis 探索性数据分析 extrapolation 外插false positives 假阳性falsification 证伪法fast and frugal tree 快省树Frequency 频数gap 缺口Gaussian distribution 高斯分布gold standard 黄金标准 heterogenous data 异质数据heuristics 启发法histogram 直方图 homogenous 同质hypothese 假设Hypothesis testing 假设检验 independent variable 自变量input 依据intercept 截距 Interpolating 内插linear programming 线性编程mean 平均值median 中间值medical test 医学试验mental model 心智模型method of comparison 比较法metric 度量multiple regression 多元回归 multiplication rule 乘法规则natural tendency 自然倾向 negatively linked 负相关 networked causality 因果关系网络 normal distribution 正态分布null and the alternative 原假设和备择假设 null hypothesis 原假设objective function 目标函数observational data 观察数据 observational studies 观察研究 operations research 运算研究 optimization 最优化outer limit 外限pattern 模式perceived value 感知价值 PivotTable 数据透视表 polynomial 多项式 positively linked 正相关 Probability histograms 概率直方图R.M.S. 均方根 randomization method 随机法 Randomized controlled 随机控制 Randomness 随机性 regression 回归分析,回归 relative likelihood 相对似然 residual 残差residual distribution 残差分布 sample average 样本均值 sampling 取样similar 相似slope 斜率 specific value 特定值 spread 分布 standard deviation 标准偏差 standard error 标准误差 strong 强 Subjective probability 主观概率 test 检验Tests of significance 显著性检验 The law of averages 平均律 The normal approximation 正态逼近法 t-Test T检验 variability 差异z-Test Z检验。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

本文将介绍以下内容:
∙面向对象基本概念
∙base关键字深入浅出
∙this关键字深入浅出
1. 引言
new关键字引起了大家的不少关注,尤其感谢Anders Liu的补充,让我感觉博客园赋予的交流平台真的无所不在。

所以,我们就有必要继续这个话题,把我认为最值得关注的关键字开展下去,本文的重点是访问关键字(Access Keywords):base和this。

虽然访问关键字不是很难理解的话题,我们还是有可以深入讨论的地方来理清思路。

还是老办法,我的问题先列出来,您是否做好了准备。

1.是否可以在静态方法中使用base和this,为什么?
2.base常用于哪些方面?this常用于哪些方面?
3.可以base访问基类的一切成员吗?
4.如果有三层或者更多继承,那么最下级派生类的base指向那一层呢?例
如.NET体系中,如果以base访问,则应该是直接父类实例呢,还是最高
层类实例呢?
5.以base和this应用于构造函数时,继承类对象实例化的执行顺序如何?
2. 基本概念
base和this在C#中被归于访问关键字,顾名思义,就是用于实现继承机制的访问操作,来满足对对象成员的访问,从而为多态机制提供更加灵活的处理方式。

2.1 base关键字
其用于在派生类中实现对基类公有或者受保护成员的访问,但是只局限在构造函数、实例方法和实例属性访问器中,MSDN中小结的具体功能包括:∙调用基类上已被其他方法重写的方法。

∙指定创建派生类实例时应调用的基类构造函数。

2.2 this关键字
其用于引用类的当前实例,也包括继承而来的方法,通常可以隐藏this,MSDN
中的小结功能主要包括:
∙限定被相似的名称隐藏的成员
∙将对象作为参数传递到其他方法
∙声明索引器
3. 深入浅出
3.1 示例为上
下面以一个小示例来综合的说明,base和this在访问操作中的应用,从而对其有个概要了解,更详细的规则和深入我们接着阐述。

本示例没有完全的设计概念,主要用来阐述base和this关键字的使用要点和难点阐述,具体的如下:
base和this示例
3.2 示例说明
上面的示例基本包括了base和this使用的所有基本功能演示,具体的说明可以从注释中得到解释,下面的说明是对注释的进一步阐述和补充,来说明在应用方面的几个要点:
1.base常用于,在派生类对象初始化时和基类进行通信。

2.base可以访问基类的公有成员和受保护成员,私有成员是不可访问的。

3.this指代类对象本身,用于访问本类的所有常量、字段、属性和方法成
员,而且不管访问元素是任何访问级别。

因为,this仅仅局限于对象内
部,对象外部是无法看到的,这就是this的基本思想。

另外,静态成员
不是对象的一部分,因此不能在静态方法中引用this。

4.在多层继承中,base可以指向的父类的方法有两种情况:一是有重载存
在的情况下,base将指向直接继承的父类成员的方法,例如Audi类中的ShowResult方法中,使用base访问的将是Car.ShowResult()方法,而不能访问Vehicle.ShowResult()方法;而是没有重载存在的情况下,base 可以指向任何上级父类的公有或者受保护方法,例如Audi类中,可以使
用base访问基类Vehicle.Run() 方法。

这些我们可以使用ILDasm.exe,从IL代码中得到答案。

.method public hidebysig virtual instance void
ShowResult() cil managed
{
// 代码大小 27 (0x1b)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
//base调用父类成员
IL_0002: call instance void .My_Must_net.Car::ShowResult()
IL_0007: nop
IL_0008: ldarg.0
//base调用父类成员,因为没有实现Car.Run(),所以指向更高级父类
IL_0009: call instance void .My_Must_net.Vehicle::Run()
IL_000e: nop
IL_000f: ldstr "It's audi's result."
IL_0014: call void [mscorlib]System.Console::WriteLine(string)
IL_0019: nop
IL_001a: ret
} // end of method Audi::ShowResult
3.3 深入剖析
如果有三次或者更多继承,那么最下级派生类的base指向那一层呢?例如.NET 体系中,如果以base访问,则应该是直接父类实例呢,还是最高层类实例呢?
首先我们有必要了解类创建过程中的实例化顺序,才能进一步了解base机制的详细执行过程。

一般来说,实例化过程首先要先实例化其基类,并且依此类推,一直到实例化System.Object为止。

因此,类实例化,总是从调用
System.Object.Object()开始。

因此示例中的类 Audi的实例化过程大概可以小结为以下顺序执行,详细可以参考示例代码分析。

1.执行System.Object.Object();
2.执行Vehicle.Vehicle(string name, int speed);
3.执行Car.Car();
4.执行Car.Car(string name, int speed);
5.执行Audi.Audi();
6.执行Audi.Audi(string name, int speed)。

我们在充分了解其实例化顺序的基础上就可以顺利的把握base和this在作用于构造函数时的执行情况,并进一步了解其基本功能细节。

下面更重要的分析则是,以ILDASM.exe工具为基础来分析IL反编译代码,以便更深层次的了解执行在base和this背后的应用实质,只有这样我们才能说对技术有了基本的剖析。

Main方法的执行情况为:
IL分析base和this执行
因此,对重写父类方法,最终指向了最高级父类的方法成员。

4. 通用规则
尽量少用或者不用base和this。

除了决议子类的名称冲突和在一个构造函数中调用其他的构造函数之外,base和this的使用容易引起不必要的结果。

∙在静态成员中使用base和this都是不允许的。

原因是,base和this访问的都是类的实例,也就是对象,而静态成员只能由类来访问,不能由对象来访问。

∙base是为了实现多态而设计的。

∙使用this或base关键字只能指定一个构造函数,也就是说不可同时将this和base作用在一个构造函数上。

∙简单的来说,base用于在派生类中访问重写的基类成员;而this用于访问本类的成员,当然也包括继承而来公有和保护成员。

∙除了base,访问基类成员的另外一种方式是:显示的类型转换来实现。

只是该方法不能为静态方法。

5. 结论
base和this关键字,不是特别难于理解的内容,本文之所以将其作为系列的主题,除了对其应用规则做以小结之外,更重要的是在关注其执行细节的基础上,对语言背景建立更清晰的把握和分析,这些才是学习和技术应用的根本所在,也是.NET技术框架中本质诉求。

对学习者来说,只有从本质上来把握概念,才能在变化非凡的应用中,一眼找到答案。

言归正传,开篇的几个题目,不知读者是否有了各自的答案,我们不妨畅所欲言,做更深入的讨论,以便揭开其真实的面纱。

参考文献
(USA)Stanley B.Lippman, C# Primer
(USA)David Chappell, Understanding .NET
(Cnblog)Bear-Study-Hard,C#学习笔记(二):构造函数的执行序列
广而告之
[预告]
另外鉴于前几个主题的讨论中,不管是类型、关键字等都涉及到引用类型和值类型的话题,我将于近期发表相关内容的探讨,主要包括3个方面的内容,这是本系列近期动向,给自己做个广告。

祝各位愉快。

[声明]
本文的关键字指的是C#中的关键字概念,并非一般意义上的.NET CRL范畴,之所以将这个主题加入本系列,是基于在.NET体系下开发的我们,何言能逃得过基本语言的只是要点。

所以大可不必追究什么是.NET,什么是C#的话题,希望大家理清概念,有的放肆。

相关文档
最新文档