1. 动态绑定
若子类SubClass覆盖了父类SuperClass的某个非final非private方法f1()
即使子类被声明为
SuperClass child = new SubClass();
使用child.f1()时仍然访问子类的f1()
2. 如果把某个方法声明为final,可以防止其他人覆盖该方法。更为重要的一点是,这样做可以有效的关闭动态绑定,从而生成更有效的代码。然而,大多数情况下,这样做对程序的整体性能不会有什么改观。因此并不提倡为了仅仅提高性能而使用final。
3. private方法无法被覆盖,但还是要注意覆盖private方法的现象,上面的例子中,如SuperClass中含有private方法f2(),而子类中也声明了同名的方法f2(),子类被声明为
SuperClass child = new SubClass();
child.f2()时访问了父类的f2()
4. 构造器和多态
构造器基本顺序:
1)调用基类构造器(递归过程)
2)按声明顺序调用成员的初始化方法。
3)调用导出类构造器的主体。
5. 继承与清理
通过组合与京城方法来创建新类时,不必担心对象的清理问题。如果确实遇到清理的问题,那么必须为新类创建dispose()方法。当覆盖被继承类的dispose()方法时,务必记住调用基类的dispose()方法,也要注意清理顺序。
6. 构造器内部的多态方法的行为
如果要调用构造器内部的一个动态绑定的方法,就要用到那个方法的被覆盖后的定义。然而,产生的效果可能相当难于预料,并且可能造成一些难于发现的隐藏错误。
在任何构造器的内部,整个对象可能只是部分形成,然而一个动态绑定的方法调用却会向外深入到继承层次结构内部,它可以调用导出类的方法。如果在构造器里这么做,那么就可能会调用某个方法,而这个方法所操纵的成员可能还未初始化--这肯定会出问题。
import com.bruceeckel.simpletest.*;
abstract class Glyph {
abstract void draw();
Glyph() {
System.out.println("Glyph() before draw()");
draw();
System.out.println("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph {
private int radius = 1;
RoundGlyph(int r) {
radius = r;
System.out.println(
"RoundGlyph.RoundGlyph(), radius = " + radius);
}
void draw() {
System.out.println(
"RoundGlyph.draw(), radius = " + radius);
}
}
public class PolyConstructors {
public static void main(String[] args) {
new RoundGlyph(5);
}
}
最后显示
Glyph() before draw()
RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 5
实际应用中,或许这会导致RoundGlyph对象生成后只画了一个点,而不是预期的半径为1的圆。
解释:初始化的实际过程是:
1)将分配给对象的储存空间初始化为二进制的0。
2)调用基类构造器。即此时调用了draw()方法,但radius仍然为0。
3)按照声明的顺序调用成员的初始化方法。
4)调用导出类的构造器主体。
逻辑方法已经十分完美,但行为却会出错(这种情况下,C++会产生更合理的行为)
因此,编写构造器有一条有效的准则:用尽可能简单的方法使对象进入正常状态;如果可以的话,避免调用其他方法。在构造器内唯一能够安全调用的那些方法是基类中的final方法(包括private方法),这些方法不能被覆盖,也就不会出现上述问题。
7. 依然是继承/组合的选择
一条通用的准则是,用继承表达行为间的差异,用字段表达状态上的变化。
8. 纯继承:只有在基类或接口中已经建立的方法才可以在导出类中被覆盖,基类与导出类的接口相同。
9. 向下转型

posted @ 2007-04-22 20:24 ZelluX 阅读(285) | 评论 (0)编辑 收藏

2007-02-17 23:16:32
花个20分钟入个门吧,恩
from http://www.regexlab.com/zh/regref.htm
正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来:(1)检查一个串中是否含有符合某个规则的子串,并且可以得到这个子串;(2)根据匹配规则对字符串进行灵活的替换操作。
正则表达式规则:
1. 普通字符
举例:表达式 "bcd",在匹配字符串 "abcde" 时,匹配结果是:成功;匹配到的内容是:"bcd";匹配到的位置是:开始于1,结束于4。(注:下标从0开始还是从1开始,因当前编程语言的不同而可能不同)
2. 简单的转义符
表达式 可匹配
\r, \n 代表回车和换行符
\t 制表符
\\ 代表 "\" 本身
\^ 匹配 ^ 符号本身
\$ 匹配 $ 符号本身
\. 匹配小数点(.)本身

举例:表达式 "\$d",在匹配字符串 "abc$de" 时,匹配结果是:成功;匹配到的内容是:"$d";匹配到的位置是:开始于3,结束于5。

3. 能够与 '多种字符' 匹配的表达式
\d 任意一个数字,0~9 中的任意一个
\w 任意一个字母或数字或下划线,也就是 A~Z,a~z,0~9,_ 中任意一个
\s 包括空格、制表符、换页符等空白字符的其中任意一个
. 小数点可以匹配除了换行符(\n)以外的任意一个字符

举例:表达式 "\d\d",在匹配 "abc123" 时,匹配的结果是:成功;匹配到的内容是:"12";匹配到的位置是:开始于3,结束于5。
4. 自定义能够匹配 '多种字符' 的表达式
[ab5@] 匹配 "a" 或 "b" 或 "5" 或 "@"
[^abc] 匹配 "a","b","c" 之外的任意一个字符
[f-k] 匹配 "f"~"k" 之间的任意一个字母
[^A-F0-3] 匹配 "A"~"F","0"~"3" 之外的任意一个字符
5. 修饰匹配次数的特殊符号
{n}
表达式重复n次,比如:"\w{2}" 相当于 "\w\w";"a{5}" 相当于 "aaaaa"
{m,n}
表达式至少重复m次,最多重复n次,比如:"ba{1,3}"可以匹配 "ba"或"baa"或"baaa"
{m,}
表达式至少重复m次,比如:"\w\d{2,}"可以匹配 "a12","_456","M12344"...
?
匹配表达式0次或者1次,相当于 {0,1},比如:"a[cd]?"可以匹配 "a","ac","ad"
+
表达式至少出现1次,相当于 {1,},比如:"a+b"可以匹配 "ab","aab","aaab"...
*
表达式不出现或出现任意次,相当于 {0,},比如:"\^*b"可以匹配 "b","^^^b"...

举例:表达式 "go{2,8}gle" 在匹配 "Ads by goooooogle" 时,匹配的结果是:成功;匹配到的内容是:"goooooogle";匹配到的位置是:开始于7,结束于17。
6. 其他一些代表抽象意义的特殊符号
^ 与字符串开始的地方匹配,不匹配任何字符
$ 与字符串结束的地方匹配,不匹配任何字符
\b 匹配一个单词边界,也就是单词和空格之间的位置,不匹配任何字符

举例:表达式 ".\b." 在匹配 "@@@abc" 时,匹配结果是:成功;匹配到的内容是:"@a";匹配到的位置是:开始于2,结束于4。
进一步说明:"\b" 与 "^" 和 "$" 类似,本身不匹配任何字符,但是它要求它在匹配结果中所处位置的左右两边,其中一边是 "\w" 范围,另一边是 非"\w" 的范围。

posted @ 2007-04-22 20:24 ZelluX 阅读(244) | 评论 (0)编辑 收藏

2007-02-16 22:15:50

1.

主  题: 请教关于method override
作  者: amatuer () Blog
等  级:
信 誉 值: 100
所属社区: Java J2SE / 基础类
问题点数: 80
回复次数: 2
发表时间: 2007-2-16 23:50:00


在调用SubClass中的addAll()时,结果输出为"sub"。SuperClass中的addAll()调用的是super.addAll(),按我的理解尽管super.add()被重写,super.addAll()应该调用super.add(),而结果却不是这样。谁给解释一下?
以下示意性的代码:
class SuperClass {
public add() {
System.out.println("super");
}

public addAll() {
add();
}
}

class SubClass extends SuperClass {
public add() {//overriding
System.out.println("sub");
}

public addAll() {//overriding
super.addAll();
}
}

interpb(曾曾胡,深怕情多累美人!!!) ( ) 信誉:87 Blog 2007-2-16 23:58:48 得分: 0


public addAll() {//overriding
super.addAll();
}


这样只是说 调用父类的addAll 方法

但是父类在调用这个addAll的时候会调用add 这个时候因为多态所以调用SubClass的add




Top
interpb(曾曾胡,深怕情多累美人!!!) ( ) 信誉:87 Blog 2007-2-17 0:05:02 得分: 0


public void addAll() {//overriding
super.addAll();
System.out.println(super.getClass());
System.out.println(super.hashCode());
System.out.println(this.hashCode());
}

你可以打印出super的实际是属于SubClass的对象的一个引用
实际上super与this是同一个对象

2.

如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。
instanceof有一些用处。比如我们写了一个处理账单的系统,其中有这样三个类:

public class Bill {//省略细节}
public class PhoneBill extends Bill {//省略细节}
public class GasBill extends Bill {//省略细节}

在处理程序里有一个方法,接受一个Bill类型的对象,计算金额。假设两种账单计算方法不同,而传入的Bill对象可能是两种中的任何一种,所以要用instanceof来判断:

public double calculate(Bill bill) {
if (bill instanceof PhoneBill) {
//计算电话账单
}
if (bill instanceof GasBill) {
//计算燃气账单
}
...
}
这样就可以用一个方法处理两种子类。

然而,这种做法通常被认为是没有好好利用面向对象中的多态性。其实上面的功能要求用方法重载完全可以实现,这是面向对象变成应有的做法,避免回到结构化编程模式。只要提供两个名字和返回值都相同,接受参数类型不同的方法就可以了:

public double calculate(PhoneBill bill) {
//计算电话账单
}

public double calculate(GasBill bill) {
//计算燃气账单
}

所以,使用instanceof在绝大多数情况下并不是推荐的做法,应当好好利用多态。

posted @ 2007-04-22 20:24 ZelluX 阅读(263) | 评论 (0)编辑 收藏

2007-02-16 19:03:01
1. 类的复用有两种方法:组合(composition)和继承
组合技术通常用于想在新类中使用现有类的功能而非它的接口这种情形,一般在新类中嵌入一个现有类的private对象。但有时,允许类的用户访问新类中的组合部分是极具意义的。如果成员对象自身都隐藏了具体实现,那么将它声明为public也是安全的。
2. 为了继承,一般的规则是将所有的数据成员都指定为private,将所有的方法指定为protected/public。
3. 编译器仅会在子类的无参构造器中自动调用父类的无参构造器,如果父类没有无参构造器,或者要在子类的含参构造器中调用父类的构造器,就必须用关键字super显式地调用父类构造器。
4. dispose()方法可以将未存于内存之中的东西恢复到对象存在之前的状态。注意清理的顺序与生成的顺序相反,先执行类的所有特定的清理动作,然后调用基类的清理方法。
最好除了内存以外,不要以来垃圾回收器去做任何事。如果需要进行清理,最好是编写自己的清理方法,但不要依赖finalize()
5. 做了个实验,得出父类的private方法会因为子类的同名方法而隐藏,但仍然存在。
class Father {
private void f1() {
System.out.println("Father.f1() is invoked");
}
public void f2() {
f1();
System.out.println("Father.f2() is invoked");
}
}
class Child extends Father {
public void f1() {
System.out.println("Child.f1() is invoked");
}
}
public class TestHiding {
public static void main(String[] args) {
Child c = new Child();
c.f1();
c.f2();
}
}
6. 对于基本类型,final使数值恒定不变;对于对象引用,final使引用恒定不变,但对象本身是可以被修改的。
7. 空白final,字段可以被声明为final而不给定初值,但是必须在每个构造器中对final进行赋值。
8. final 参数
void f(final int i) 这样就不能在f程序块中修改i的值了
9. final 方法
使用final方法的原因有两个:一是把方法锁定,以防被继承类修改;二是效率,将一个方法指明为final,就是同意编辑器将针对该方法的所有调用转为内嵌调用。
类中所有的private方法都隐式地指定为是final的,因此对private方法添加final修饰词没有什么意义。
10. final 类
由于无法被继承,final类中的所有方法都被隐式地定为final,因为无法覆盖它们。

posted @ 2007-04-22 20:24 ZelluX 阅读(234) | 评论 (0)编辑 收藏

2007-02-16 17:59:42
1. 类的访问权限仅有两个选择:包访问权限或者public。如果不希望其他任何人对该类拥有访问权限,可以把所有的构造器都指定为private,从而组织任何人创建该类的对象,但是有一个例外,就是在该类的static成员内可以创建。如
class Soup {
private Soup() {}
// (1) Allow creation via static method:
public static Soup makeSoup() {
return new Soup();
}
// (2) Create a static object and return a reference
// upon request.(The "Singleton" pattern):
private static Soup ps1 = new Soup();
public static Soup access() {
return ps1;
}
public void f() {}
}

如果把类构造器都指定为private,别人要使用这个类的话,上面的例子给出了两种方法:
1)创建一个static方法,它创建一个新的Soup对象并返回该对象的引用。如果想要在返回引用之前在Soup上做一些额外的工作,或者如果想要记录到底创建了多少Soup对象(可能要限制其数量),这种做法将会是大有裨益的。
2)用到了设计模式。这种特定的模式被称为singleton,这是因为始终只能创建它的一个对象ps1。

posted @ 2007-04-22 20:24 ZelluX 阅读(232) | 评论 (0)编辑 收藏

2007-02-16 15:58:27
开始加工连连看。一点心得
1. 窗口设计时应先把所有的组件都加入,设置好大小,然后再setVisible(true);否则就得repaint();一下

posted @ 2007-04-22 20:24 ZelluX 阅读(204) | 评论 (0)编辑 收藏

2007-02-15 17:27:19
1. 每个编译单元只能有一个public类,且该类的名称必须与文件名相同。
2. 如果两个含有相同名称的类的程序库被导入,使用时应明确指出类的位置。
3. 不要错误地认为Java总是讲当前目录视作是查找行为的起点之一。如果你的CLASSPATH中缺少一个"."作为路径之一的话,Java就不会查找那里。
4. private 关键字的一个用处:阻止别人直接访问某个(或全部)构造器
class Sundae {
private Sundae() {}
static Sundae makeASundae() {
return new Sundae();
}
}

posted @ 2007-04-22 20:23 ZelluX 阅读(143) | 评论 (0)编辑 收藏


去某网站注册个帐号都要身份证,还检查得那么仔细,汗

18位身份证标准在国家质量技术监督局于1999年7月1日实施
的GB11643-1999《公民身份号码》中做了明确的规定。
GB11643-1999《公民身份号码》为GB11643-1989《社会保障
号码》的修订版,其中指出将原标准名称“社会保障号码”更名
为“公民身份号码”,另外GB11643-1999《公民身份号码》从实
施之日起代替GB11643-1989。
GB11643-1999《公民身份号码》主要内容如下:
一、范围
该标准规定了公民身份号码的编码对象、号码的结构和表现
形式,使每个编码对象获得一个唯一的、不变的法定号码。
二、编码对象
公民身份号码的编码对象是具有中华人民共和国国籍的公民。
三、号码的结构和表示形式
1、号码的结构
公民身份号码是特征组合码,由十七位数字本体码和一位校
验码组成。排列顺序从左至右依次为:六位数字地址码,八位数
字出生日期码,三位数字顺序码和一位数字校验码。
2、地址码
表示编码对象常住户口所在县(市、旗、区)的行政区划代码,
按GB/T2260的规定执行。
3、出生日期码
表示编码对象出生的年、月、日,按GB/T7408的规定执行,
年、月、日代码之间不用分隔符。
4、顺序码
表示在同一地址码所标识的区域范围内,对同年、同月、同
日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配
给女性。
5、校验码
(1)十七位数字本体码加权求和公式
S = Ai * Wi, i = 2, ... , 18
Y = mod(S, 11)
i: 表示号码字符从右至左包括校验码字符在内的位置序号
Ai:表示第i位置上的身份证号码字符值
Wi:表示第i位置上的加权因子
i: 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 1
(2)校验码字符值的计算
Y: 0 1 2 3 4 5 6 7 8 9 10
校验码: 1 0 X 9 8 7 6 5 4 3 2
四、举例如下:
广东省汕头市: 440524188001010014

posted @ 2007-04-22 20:23 ZelluX 阅读(193) | 评论 (0)编辑 收藏

2007-02-15 11:23:55
写连连看界面时把JButton.x JButton.y JButton.getX() JButton.getY() 给覆盖掉了,结果老是出现重影,汗啊汗 -,-
1. 初始化的顺序,以Dog类为例
1)首次创建类型为Dog的对象(构造器可以看成静态方法),或者Dog类的静态方法/静态字段被首次访问时,Java解释器必须查找类路径,以定位Dog.class文件。
2)载入Dog.class(这将创建一个Class对象),执行有关静态初始化的所有动作。因此,静态初始化只在Class对象首次加载的时候进行一次。
3)当用new Dog()创建对象的时候,首先在堆上为Dog对象分配足够的存储空间。
4)该存储空间清零,也就自动把Dog对象中的所有基本类型数据设置成了缺省值。
5)执行所有出现于字段定义处的初始化动作。
6)执行构造器。这里将会牵涉到很多动作。
2. 数组初始化
基本类型的数组在初始化时自动把元素设为“空”值,而对象的数组则设为了null。

posted @ 2007-04-22 20:23 ZelluX 阅读(89) | 评论 (0)编辑 收藏

仅列出标题
共39页: First 上一页 31 32 33 34 35 36 37 38 39 下一页 
posts - 403, comments - 310, trackbacks - 0, articles - 7
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

2007-02-19 19:47:20
开始学servlet/jsp,偶的网站:
不过当且仅当((笔记本在使用状态) && (在WinXP下))才能访问, Linux下安装花生壳动态郁闷出错,以后再试试

posted @ 2007-04-22 20:24 ZelluX 阅读(298) | 评论 (0)编辑 收藏

2007-02-18 22:08:25
2007-02-15 16:41:36