[转]JavaScript类的继承

利用共享prototype实现继承
继承是面向对象开发的又一个重要概念,它可以将现实生活的概念对应到程序逻辑中。例如水果是一个类,具有一些公共的性质;而苹果也是一类,但它们属于水果,所以苹果应该继承于水果。
在JavaScript中没有专门的机制来实现类的继承,但可以通过拷贝一个类的prototype到另外一个类来实现继承。一种简单的实现如下:
fucntion class1(){
      //构造函数
}

function class2(){
      //构造函数
}
class2.prototype=class1.prototype;
class2.prototype.moreProperty1="xxx";
class2.prototype.moreMethod1=function(){
      //方法实现代码
}
var obj=new class2();
这样,首先是class2具有了和class1一样的prototype,不考虑构造函数,两个类是等价的。随后,又通过prototype给class2赋予了两个额外的方法。所以class2是在class1的基础上增加了属性和方法,这就实现了类的继承。
JavaScript提供了instanceof操作符来判断一个对象是否是某个类的实例,对于上面创建的obj对象,下面两条语句都是成立的:
obj instanceof class1
obj instanceof class2
表面上看,上面的实现完全可行,JavaScript也能够正确的理解这种继承关系,obj同时是class1和class2的实例。事是上不对, JavaScript的这种理解实际上是基于一种很简单的策略。看下面的代码,先使用prototype让class2继承于class1,再在 class2中重复定义method方法:
<script language="JavaScript" type="text/javascript">
<!–
//定义class1
function class1(){
      //构造函数
}
//定义class1的成员
class1.prototype={
      m1:function(){
            alert(1);
      }
}
//定义class2
function class2(){
      //构造函数
}
//让class2继承于class1
class2.prototype=class1.prototype;
//给class2重复定义方法method
class2.prototype.method=function(){
      alert(2);
}
//创建两个类的实例
var obj1=new class1();
var obj2=new class2();
//分别调用两个对象的method方法
obj1.method();
obj2.method();
//–>
</script>
从代码执行结果看,弹出了两次对话框“2”。由此可见,当对class2进行prototype的改变时,class1的prototype也随之改变, 即使对class2的prototype增减一些成员,class1的成员也随之改变。所以class1和class2仅仅是构造函数不同的两个类,它们 保持着相同的成员定义。从这里,相信读者已经发现了其中的奥妙:class1和class2的prototype是完全相同的,是对同一个对象的引用。其 实从这条赋值语句就可以看出来:
//让class2继承于class1
class2.prototype=class1.prototype;
在JavaScript中,除了基本的数据类型(数字、字符串、布尔等),所有的赋值以及函数参数都是引用传递,而不是值传递。所以上面的语句仅仅是让 class2的prototype对象引用class1的prototype,造成了类成员定义始终保持一致的效果。从这里也看到了instanceof 操作符的执行机制,它就是判断一个对象是否是一个prototype的实例,因为这里的obj1和obj2都是对应于同一个prototype,所以它们 instanceof的结果都是相同的。
因此,使用prototype引用拷贝实现继承不是一种正确的办法。但在要求不严格的情况下,却也是一种合理的方法,惟一的约束是不允许类成员的覆盖定义。下面一节,将利用反射机制和prototype来实现正确的类继承。
利用反射机制和prototype实现继承
前面一节介绍的共享prototype来实现类的继承,不是一种很好的方法,毕竟两个类是共享的一个 prototype,任何对成员的重定义都会互相影响,不是严格意义的继承。但在这个思想的基础上,可以利用反射机制来实现类的继承,思路如下:利用 for(…in…)语句枚举出所有基类prototype的成员,并将其赋值给子类的prototype对象。例如:
<script language="JavaScript" type="text/javascript">
<!–
function class1(){
      //构造函数
}
class1.prototype={
      method:function(){
           alert(1);
      },
      method2:function(){
           alert("method2");
      }
}
function class2(){
      //构造函数
}
//让class2继承于class1
for(var p in class1.prototype){
       class2.prototype[p]=class1.prototype[p];
}

//覆盖定义class1中的method方法
class2.prototype.method=function(){
      alert(2);
}
//创建两个类的实例
var obj1=new class1();
var obj2=new class2();
//分别调用obj1和obj2的method方法
obj1.method();
obj2.method();
//分别调用obj1和obj2的method2方法
obj1.method2();
obj2.method2();
//–>
</script>
从运行结果可见,obj2中重复定义的method已经覆盖了继承的method方法,同时method2方法未受影响。而且obj1中的method方 法仍然保持了原有的定义。这样,就实现了正确意义的类的继承。为了方便开发,可以为每个类添加一个共有的方法,用以实现类的继承:
//为类添加静态方法inherit表示继承于某类
Function.prototype.inherit=function(baseClass){
     for(var p in baseClass.prototype){
            this.prototype[p]=baseClass.prototype[p];
     }
}
这里使用所有函数对象(类)的共同类Function来添加继承方法,这样所有的类都会有一个inherit方法,用以实现继承,读者可以仔细理解这种用法。于是,上面代码中的:
//让class2继承于class1
for(var p in class1.prototype){
       class2.prototype[p]=class1.prototype[p];
}
可以改写为:
//让class2继承于class1
class2.inherit(class1)
这样代码逻辑变的更加清楚,也更容易理解。通过这种方法实现的继承,有一个缺点,就是在class2中添加类成员定义时,不能给prototype直接赋值,而只能对其属性进行赋值,例如不能写为:
class2.prototype={
      //成员定义
}
而只能写为:
class2.prototype.propertyName=someValue;
class2.prototype.methodName=function(){
      //语句
}
由此可见,这样实现继承仍然要以牺牲一定的代码可读性为代价,在下一节将介绍prototype-1.3.1框架(注:prototype-1.3.1框 架是一个JavaScript类库,扩展了基本对象功能,并提供了实用工具详见附录。)中实现的类的继承机制,不仅基类可以用对象直接赋值给 property,而且在派生类中也可以同样实现,使代码逻辑更加清晰,也更能体现面向对象的语言特点。

prototype-1.3.1框架中的类继承实现机制
在prototype-1.3.1框架中,首先为每个对象都定义了一个extend方法:
//为Object类添加静态方法:extend
Object.extend = function(destination, source) {
for(property in source) {
     destination[property] = source[property];
}
return destination;
}
//通过Object类为每个对象添加方法extend
Object.prototype.extend = function(object) {
return Object.extend.apply(this, [this, object]);
}
Object.extend方法很容易理解,它是Object类的一个静态方法,用于将参数中source的所有属性都赋值到destination对象 中,并返回destination的引用。下面解释一下Object.prototype.extend的实现,因为Object是所有对象的基类,所以 这里是为所有的对象都添加一个extend方法,函数体中的语句如下:
Object.extend.apply(this,[this,object]);
这一句是将Object类的静态方法作为对象的方法运行,第一个参数this是指向对象实例自身;第二个参数是一个数组,包括两个元素:对象本身和传进来 的对象参数object。函数功能是将参数对象object的所有属性和方法赋值给调用该方法的对象自身,并返回自身的引用。有了这个方法,下面看类继承 的实现:
<script language="JavaScript" type="text/javascript">
<!–
//定义extend方法
Object.extend = function(destination, source) {
for (property in source) {
     destination[property] = source[property];
}
return destination;
}
Object.prototype.extend = function(object) {
return Object.extend.apply(this, [this, object]);
}
//定义class1
function class1(){
      //构造函数
}
//定义类class1的成员
class1.prototype={
      method:function(){
           alert("class1");
      },
      method2:function(){
           alert("method2");
      }

}
//定义class2
function class2(){
      //构造函数
}
//让class2继承于class1并定义新成员
class2.prototype=(new class1()).extend({
      method:function(){
           alert("class2");
      }
});

//创建两个实例
var obj1=new class1();
var obj2=new class2();
//试验obj1和obj2的方法
obj1.method();
obj2.method();
obj1.method2();
obj2.method2();
//–>
</script>
从运行结果可以看出,继承被正确的实现了,而且派生类的额外成员也可以以列表的形式加以定义,提高了代码的可读性。下面解释继承的实现:
//让class2继承于class1并定义新成员
class2.prototype=(new class1()).extend({
      method:function(){
           alert("class2");
      }
});
上段代码也可以写为:
//让class2继承于class1并定义新成员
class2.prototype=class1.prototype.extend({
      method:function(){
           alert("class2");
      }
});
但因为extend方法会改变调用该方法对象本身,所以上述调用会改变class1的prototype的值,犯了和以前一样的错误。在 prototype-1.3.1框架中,巧妙的利用new class1()来创建一个实例对象,并将实例对象的成员赋值给class2的prototype。其本质相当于创建了class1的prototype 的一个拷贝,在这个拷贝上进行操作自然不会影响原有类中prototype的定义了。

Read: 900

[个人记录用]Fedora 8 常规使用设置

Fedora 8 常规使用设置

以前装linux都没有作记录,虽然再装起来也不是什么难事,但总会忘这忘那,找资料也总会花不少时间的。

昨天挂了一晚上下了Fedora 8(F9test官方已经有消息了…这速度也太快了),这次也干脆来次重新安装,顺便记录一下一些设置啊什么的。

[安装]
我用的是硬盘安装,本来安装的系统是Fedora 7

硬盘安装方法:

我的驱动器信息
________________________
挂载点       对应标号
/       sda1
/home       sda2
/workspace   sda3
/soft       sda6
————————

1、挂载iso文件
mount -t iso9660 -o loop ISO文件路径 挂载路径

2、复制安装引导程序
然后进入iso目录把isolinux拷到 / 下面

3、编辑启动菜单
编辑 /etc/grub.conf
追加一下4行

title Fedora 8 Installation # 引导项目标题
        root (hd0,0) # 根目录(/)的位置
        kernel /isolinux/vmlinuz
        initrd /isolinux/initrd

4、启动安装
重新启动系统,从引导菜单中选择 “Fedora 8 Installation”
选择安装介质的时候选 Hard Disk
然后选择Fedora-8-i386-DVD.iso所在的分区确定就行
确定….
重新启动以后就会开始安装,根据需要选择一些要安装的附件什么以后就可以开始安装了。

主要选了几个
KDE   我比较喜欢这个,感觉可配置的地方多一些
Eclipse 比较强大的IDE
MySQL   F8带的版本也比较新,刚好装上得了,反正我
   就算自己装也懒得去下源码包编译的,毕竟是自己用作测试的。
   至于HTTP,PHP什么的,还是自己装吧,要配置的东西比较多。

其他乱七八糟的好像也选了几个….反正是无关紧要的东西

[字体安装]
直接到windows下面弄了点字体过来 放进 /usr/share/fonts/zh_CN 里面
然后执行
ttmkfdir -o fonts.scale
ttmkfdir
fc-cache -fv
就行了…其实我还没搞明白上面几句是干嘛的..哈…哈哈….

我用到的字体:
arialbd.ttf
arialbi.ttf
ariali.ttf
arial.ttf
fonts.scale
simfang.ttf
simhei.ttf
simkai.ttf
simsun.ttc
tahomabd.ttf
tahoma.ttf
verdanab.ttf
verdanai.ttf
verdana.ttf
verdanaz.ttf

[配置]
。。。。。。。。
突然发现也没什么好写的,随便记吧。。。本来就是是方便自己记忆而已。。。

第一个问题,音乐
没有音乐怎么能行?以前用KDE一直在用 Amarok 感觉很好,不过现在我打算用用Gnome,F8里看起来挺舒服的打算试试
查了一下,听说Audacious不错。

先到 http://rpm.livna.org/rlowiki/ 把livna的repo加上
然后
yum install audacious
yum install audacious-plugins-nonfree-mp3
yum install audacious-plugins-nonfree-wma

OK了,MP3也能放了
附上一文顺便解释一下关于MP3中文标签在LINUX乱码的问题:
[Amarok的中文支持到底是怎么回事]http://www.myswear.net/forum/viewthread.php?tid=7536&extra=page%3D10

[PHP开发环境配置]
apache 2.2.6
php 5.2.5

apache configure :
./configure –prefix=/usr/local/apache –enable-rewrite –enable-so

php configure :
./configure
–prefix=/usr/local/php
–with-apxs2=/usr/local/apache/bin/apxs
–enable-mbstring
–with-zlib
–with-gd
–with-mysql=shared
–with-sqlite=shared
–enable-pdo=shared
–with-pdo-sqlite=shared
–with-pdo-mysql=shared

/usr/kerberos/sbin:/usr/lib/qt-3.3/bin:/usr/kerberos/bin:/usr/lib/ccache:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/home/gik/bin:/sbin

因为可能会经常改配置,所以把配置文件的链接弄到etc里,方便点,免得用起来还要输个长长的路径
ln -s /usr/local/php/lib/php.ini /etc/php.ini
ln -s /usr/local/apache/conf/httpd.conf /etc/httpd.conf

再编译PHP/PDO 什么的时候 有时候会出现 Cannot find MySQL header files under 之类的问题
解决方法: sudo ln -s /usr/local/mysql/bin/mysql_config /usr/bin/mysql_config

[FIREFOX 字体问题]
F8 界面字体很小的,不知道被改过什么地方。
不管,直接动手术

cd ~/.mozilla/firefox/XXXXXXXX.default/chrome/
cp userChrome-example.css userChrome.css

修改浏览器界面字体
vi userChrome.css
加上这两行
*{ font-size:10pt; font-family:sans; }
menupopup > * { font-size:12pt; }

保存退出

再修改页面字体大小
cp userContent-example.css userContent.css
vi userContent.css
加上 body,input,button { font-size:12px; }

改完以后很多页面看着还是很奇怪,英文字体和中文字体大小参差不齐,查了一下 发现是DPI的问题
打开firefox进入 about:config
找到 layout.css.dpi , 这项默认为-1,据说值为-1的时候字体DPI为96(我们平时用的字体分辨率都是72),所以字体看起来会特别小

修改
layout.css.dpi = 0

好了 FIREFOX正常了

另外,如果是自己安装firefox会由于缺少 libstdc++.so.5 而运行不了 直接 yum install libstdc++.so.5 就行了

[ZEND安装问题]
装zend的时候出现新问题了,运行安装程序出现 “xcb_xlib.c:50: xcb_xlib_unlock: Assertion `c->xlib.lock failed”
据说是JDK导致的问题

解决办法:
还原到F7的libX11
rpm -e –nodeps libX11-1.1.3-4.fc8
rpm -e –nodeps libX11-devel-1.1.3-4.fc8

到http://rpm.pbone.net/找到下面那两个包 装上
rpm -ivh libX11-1.0.3-8.fc7.i386.rpm
rpm -ivh libX11-devel-1.0.3-8.fc7.i386.rpm

再加上下面两行到 /etc/yum.conf,防止更新的时候又恢复到新版本
# List of packages to exclude from updates or installs
exclude=libX11 libX11-devel

[ZEND中文问题]
linux下安装的ZEND辑中文时会变成方块,这个问题是由于ZEND自带的JRE没有中文字体造成的
找到ZEND的安装目录
进入 jre/lib/fonts/
建立一个 fallback 目录
找点中文字体放进去就行了,我比较喜欢用宋体

[PHP extensions问题]
由于编译mysql,sqlite,pdo的时候用的是shared方式
所以还要在PHP.ini中设定相应的选项才行

编译的时候由于没有特别指定,所以.so文件产生的位置是在

PHP安装目录/lib/php/extensions/[no-debug-non-zts-20060613]
中括号括起的部分可能会变
还有,linux下面的extension是.so不是.dll哦。。。别搞错了,反正我自己是忘了。。哈哈。。。以前一直用静态编译
还有编译产生的so文件前面是没有 php_前缀的 不过php.ini里的是有的 一定要注意。。。表像我那么粗心

2008年的第一天补上。。。。

关于字体发虚的问题,其实主要体现是在中文字体上,还有默认用的好像是那个什么Mingliu的字体,在FIREFOX里面看起来好恶心哦。。。

恩。。。解决办法如下:

一、关闭部分大小的字体反锯齿功能
二、设置替换字体

具体。。。

/etc/fonts/conf.d/10-XXXXXXXX.conf

内容——————————————————————–
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<!– /etc/fonts/conf.avail/50-user.conf file to configure system font access –>
<fontconfig>
<!–
   default settings for all fonts.
–>
<match target="font" >
<!– 打开字体的反锯齿即AA,大号字用AA会更美观   –>
       <edit mode="assign" name="antialias" >
           <bool>t</bool>
       </edit>
       <edit mode="assign" name="hintstyle" >
           <const>hintslight</const>
       </edit>
<!– 打开hint –>
       <edit mode="assign" name="hinting" >
           <bool>t</bool>
       </edit>
<!– 关闭autohint –>
       <edit mode="assign" name="autohint" >
           <bool>false</bool>
       </edit>
</match>

<!– 关闭 8到17号字体的AA –>
<match target="font" >
                <test compare="contains" name="lang" >
                        <string>zh-cn</string>
                        <string>zh-tw</string>
                        <string>ja</string>
                        <string>ko</string>
                </test>
                <test compare="more_eq" name="pixelsize" qual="any" >
                        <double>9</double>
                </test>
                <test compare="less_eq" name="pixelsize" qual="any" >
                        <double>14</double>
                </test>
                <edit mode="assign" name="antialias" >
                        <bool>false</bool>
                </edit>
</match>

<!– 解决英文字体间距过宽 –>
<match target="font">

                <test target="pattern" name="lang" compare="contains">
                        <string>zh-tw</string>
                        <string>zh-cn</string>
                        <string>ja</string>
                        <string>ko</string>
                </test>
                <edit name="spacing">
                        <const>proportional</const>
                </edit>
                <edit name="globaladvance">
                <bool>false</bool>
                </edit>
</match>

<!–
设定中文最小字号,使得小字的中文美观
–>
<match target="font" >
   <test name="family" qual="any" >
       <string>SimSun</string>
       <string>NSimSun</string>
       <string>SimHei</string>
       <string>AR PL ShanHeiSun Uni</string>
       <string>AR PL ZenKai Uni</string>
       <string>AR PL New Sung</string>
       <string>FZSongTi</string>
      <string>FZMingTiB</string>
       <string>FangSong_GB2312</string>
       <string>KaiTi_GB2312</string>
   </test>
   <test compare="more_eq" name="pixelsize" >
       <int>8</int>
   </test>
   <test compare="less_eq" name="pixelsize" >
       <int>12</int>
   </test>
   <edit compare="eq" name="pixelsize" >
       <int>12</int>
   </edit>
</match>
<!–
把serif ,sans,monospace的family(字体族)重新排序,适应中文用户的用字习惯
–>
   <alias>
      <family>serif</family>
      <prefer>
         <family>Times New Roman</family>
         <family>Nimbus Roman No9 L</family>
         <family>Luxi Serif</family>
         <family>Times</family>
   <family>Bitstream Vera Serif</family>
         <family>Simsun</family>
   <family>MingLiu</family>
         <family>WenQuanYi Bitmap Song</family>
   <family>AR PL ShanHeiSun Uni</family>
   <family>AR PL ZenKai Uni</family>
         <family>AR PL New Sung</family>
   <family>FZSongTi</family>
   <family>FZMingTiB</family>
         <family>Kochi Mincho</family>
         <family>AR PL SungtiL GB</family>
         <family>AR PL Mingti2L Big5</family>
         <family>Baekmuk Batang</family>
      </prefer>
   </alias>
   <alias>
      <family>sans-serif</family>
      <prefer>
   <family>Arial</family>
   <family>Verdana</family>
   <family>Tahoma</family>
   <family>Helvetica</family>
   <family>Bitstream Vera Sans</family>
         <family>SimSun</family>
   <family>MingLiu</family>
         <family>WenQuanYi Bitmap Song</family>
   <family>AR PL ShanHeiSun Uni</family>
   <family>AR PL ZenKai Uni</family>
         <family>AR PL New Sung</family>
   <family>FZSongTi</family>
   <family>FZMingTiB</family>
         <family>Kochi Gothic</family>
         <family>AR PL KaitiM GB</family>
         <family>AR PL KaitiM Big5</family>
         <family>Baekmuk Dotum</family>

      </prefer>
   </alias>
   <alias>
      <family>monospace</family>
      <prefer>
   <family>Courier New</family>
   <family>Courier</family>
         <family>Andale Mono</family>
         <family>Luxi Mono</family>
         <family>Nimbus Mono L</family>
   <family>Bitstream Vera Sans Mono</family>
   <family>NSimSun</family>
   <family>PMingLiu</family>
         <family>WenQuanYi Bitmap Song</family>
   <family>AR PL ShanHeiSun Uni</family>
   <family>AR PL ZenKai Uni</family>
         <family>AR PL New Sung</family>
   <family>FZSongTi</family>
   <family>FZMingTiB</family>
         <family>Kochi Gothic</family>
         <family>AR PL KaitiM GB</family>
         <family>Baekmuk Dotum</family>
      </prefer>
   </alias>
</fontconfig>
内容——————————————————————–

待续。。。。

Read: 755