Posts Tagged ‘类的’

浅析Java中Data类的应用

星期一, 06月 2nd, 2008

Date 类从Java 开发包(JDK) 1.0 就开始进化, 当时它只包含了几个取得或者设置一个日期数据de各个部分de方法, 比如说月, 日, 和年.这些方法现在遭到了批评并且已经被转移到了Calendar类里去了, 我将在本文中进一步讨论它.
  这种改进旨在更好de处理日期数据de国际化格式. 就象在JDK 1.1中一样, Date 类实际上只是一个包裹类, 它包含de是一个长整型数据, 表示de是从GMT(格林尼治标准时间)1970年, 1 月 1日00:00:00这一刻之前或者是之后经历de毫秒数.
  创建一个日期对象

  让我看一个使用系统de当前日期和时间创建一个日期对象并返回一个长整数de简单例子. 这个时间通常被称为Java 虚拟机(JVM)主机环境de系统时间.
  import java.util.Date;
  public class DateExample1 {
  public static void main(String[] args) { //自己替换[]
  // Get the system date/time
  Date date = new Date();
  System.out.println(date.getTime());
  }
  }
  在星期六, 2001年9月29日, 下午大约是6:50de样子,上面de例子在系统输出设备上显示de结果是 1001803809710. 在这个例子中,值得注意de是我使用了Date 构造函数创建一个日期对象,这个构造函数没有接受任何参数. 而这个构造函数在内部使用了System.currentTimeMillis() 方法来从系统获取日期.
  那么, 现在我已经知道了如何获取从1970年1月1日开始经历de毫秒数了. 我如何才能以一种用户明白de格式来显示这个日期呢? 在这里类java.text.SimpleDateFormat 和它de抽象基类 java.text.DateFormat 就派得上用场了.
  日期数据de定制格式

  假如我希望定制日期数据de格式, 比方星期六-9月-29日-2001年. 下面de例子展示了如何完成这个工作:
  import java.text.SimpleDateFormat;
  import java.util.Date;
  public class DateExample2 {
  public static void main(String[] args) { //自己替换[]
  SimpleDateFormat bartDateFormat = new SimpleDateFormat(”EEEE-MMMM-dd-yyyy”);
  Date date = new Date();
  System.out.println(bartDateFormat.format(date));
  }
  }
  只要通过向SimpleDateFormat de构造函数传递格式字符串”EEE-MMMM-dd-yyyy”, 我就能够指明自己想要de格式. 您应该可以看见, 格式字符串中deASCII 字符告诉格式化函数下面显示日期数据de哪一个部分. EEEE是星期, MMMM是月, dd是日, yyyy是年. 字符de个数决定了日期是如何格式化de.传递”EE-MM-dd-yy”会显示 Sat-09-29-01. 请察看Sun 公司deWeb 站点获取日期格式化选项de完整de指示.
  将文本数据解析成日期对象

  假设我有一个文本字符串包含了一个格式化了de日期对象, 而我希望解析这个字符串并从文本日期数据创建一个日期对象. 我将再次以格式化字符串”MM-dd-yyyy” 调用SimpleDateFormat类, 但是这一次, 我使用格式化解析而不是生成一个文本日期数据. 我de例子, 显示在下面, 将解析文本字符串”9-29-2001″并创建一个值为001736000000 de日期对象.
  例子程序:
  import java.text.SimpleDateFormat;
  import java.util.Date;
  public class DateExample3 {
  public static void main(String[]args) { //自己替换[]
  // Create a date formatter that can parse dates of
  // the form MM-dd-yyyy.
  SimpleDateFormat bartDateFormat = new SimpleDateFormat(”MM-dd-yyyy”);
  // Create a string containing a text date to be parsed.
  String dateStringToParse = “9-29-2001″;
  try {
   // Parse the text version of the date.
   // We have to perform the parse method in a
   // try-catch construct in case dateStringToParse
   // does not contain a date in the format we are expecting.
   Date date = bartDateFormat.parse(dateStringToParse);
   // Now send the parsed date as a long value
   // to the system output.
   System.out.println(date.getTime());
  }
  catch (Exception ex) {
   System.out.println(ex.getMessage());
  }
  }
  }
  使用标准de日期格式化过程

  既然我已经可以生成和解析定制de日期格式了, 让我来看一看如何使用内建de格式化过程. 方法 DateFormat.getDateTimeInstance() 让我得以用几种不同de方法获得标准de日期格式化过程. 在下面de例子中, 我获取了四个内建de日期格式化过程. 它们包括一个短de, 中等de, 长de, 和完整de日期格式.
  import java.text.DateFormat;
  import java.util.Date;
  public class DateExample4 {
  public static void main(String[] args) { //自己替换[]
  Date date = new Date();
  DateFormat shortDateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT,DateFormat.SHORT);
  DateFormat mediumDateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.MEDIUM);
  DateFormat longDateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);
  DateFormat fullDateFormat = DateFormat.getDateTimeInstance(DateFormat.FULL,DateFormat.FULL);
  System.out.println(shortDateFormat.format(date));
  System.out.println(mediumDateFormat.format(date));
  System.out.println(longDateFormat.format(date));
  System.out.println(fullDateFormat.format(date));
  }
  }
  注意我在对 getDateTimeInstancede每次调用中都传递了两个值. 第一个参数是日期风格, 而第二个参数是时间风格. 它们都是基本数据类型int(整型). 考虑到可读性, 我使用了DateFormat 类提供de常量: SHORT, MEDIUM, LONG, 和 FULL. 要知道获取时间和日期格式化过程de更多de方法和选项, 请看Sun 公司Web 站点上de解释.
  
  运行我de例子程序de时候, 它将向标准输出设备输出下面de内容:
  9/29/01 8:44 PM
  Sep 29, 2001 8:44:45 PM
  September 29, 2001 8:44:45 PM EDT
  Saturday, September 29, 2001 8:44:45 PM EDT

WHOIS类的修改版

星期一, 06月 2nd, 2008

1、简化了相关代码.(其实就是去掉了一些用不着de变量de定义)
2、针对从INTERNIC检索到de信息过于简单,根据INTERNIC反馈de信息中deWHOIS SERVER进行进一步查询.比如,YAHOO在whois.networksolutions.com上有更详细de信息.
class whois {
var $use_cache = 1;
var $FROM_CACHE=0;
var $cache_dir = "./"; // 根据您de系统自己设置
var $port = 43;
var $MAXLEN = 100;
// 如果您想在连接失败后自动重试,
// 设置重试次数 $MAX_RETRIES
var $MAX_RETRIES = 0;
var $SLEEP_VAL = 1;
var $RETRY = 0;
var $FOUND = 0; // 查询没有结果,次值为0
var $ERROR = 0; // 查询过程中de出错次数
var $DATA_MIN = 8; // 我至少应该获得8个字节de数据
var $DATA_COUNT = 0;
var $WHOIS_SERVER;
var $NEW_WHOIS;
var $FURTHER_INFO = 0;

// 打开和WHOIS SERVERdeSOCKET连接
// 默认de是 whois.internic.net
function connect ($server) {
$this->RETRY=0;
while($this->RETRY <= $this->MAX_RETRIES):
$ptr = fsockopen($server, $this->port);
if($ptr>0):
$this->ERROR=0; // just in case we’re on a retry
return($ptr);
else:
$this->ERROR ;
$this->RETRY ;
sleep($this->SLEEP_VAL);
endif;
endwhile;
}
// 获取简单de查询结果,并以行为单位,放入数组
// 国际域名查询
function rawlookup ($query, $server) {
if(!$query):
return( "");
endif;
$ptr=$this->connect($server);
if($ptr):
if(!ereg($query, "n$")):
$query .= "n";
endif;
fputs($ptr, "$query");
$i=0;
$this->FOUND=1;
while(!feof($ptr)):
$array[$i]=fgets($ptr,$this->MAXLEN);
$this->DATA_COUNT =strlen(chop($array[$i]));
if(eregi( "No match for", $array[$i]) || eregi ("No entries found", $array[$i])):
$this->FOUND=0;
elseif(eregi( "WHOIS database is down",$array[$i])):
$this->ERROR ;
$this->FOUND=0;
elseif(eregi( "Please wait a while and try again",$array[$i])):
$this->ERROR ;
$this->FOUND=0;
break;
endif;
if(eregi("Whois Server:",$array[$i])):
$this->NEW_WHOIS=trim(substr(trim($array[$i]),(strlen(trim($array[$i]))-13)*(-1)));
$this->FURTHER_INFO=1;
endif;
$i ;
endwhile;
fclose($ptr);
if($this->DATA_COUNT>$this->DATA_MIN):
return($array);
else:
$this->ERROR ;
endif;
else:
$this->ERROR ;
endif;
}

// 国内域名查询
function cnrawlookup ($query, $server) {
if(!$query):
return( "");
endif;
$ptr=$this->connect($server);
if($ptr):
if(!ereg($query, "n$")):
$query .= "n";
endif;
fputs($ptr, "$query");
$i=0;
$this->FOUND=1;
while(!feof($ptr)):
$array[$i]=fgets($ptr,$this->MAXLEN);
$this->DATA_COUNT =strlen(chop($array[$i]));
if(eregi( "No match for", $array[$i]) || eregi ("No entries found", $array[$i])):
$this->FOUND=0;
elseif(eregi( "WHOIS database is down",$array[$i])):
$this->ERROR ;
$this->FOUND=0;
elseif(eregi( "Please wait a while and try again",$array[$i])):
$this->ERROR ;
$this->FOUND=0;
break;
endif;
$i ;
endwhile;
fclose($ptr);
if($this->DATA_COUNT>$this->DATA_MIN):
return($array);
else:
$this->ERROR ;
endif;
else:
$this->ERROR ;
endif;
}
};

$myWHOIS=new whois();
$thisname=$servername.$domainname;
// 根据国内域名或国际域名选择WHOIS SERVER
if (ereg(".cn$",$thisname))
{
$myWHOIS->WHOIS_SERVER="whois.cnnic.net.cn";
$array=$myWHOIS->cnrawlookup($thisname,$myWHOIS->WHOIS_SERVER);
}
else
{
$myWHOIS->WHOIS_SERVER="whois.internic.net";
//$myWHOIS->WHOIS_SERVER="whois.networksolutions.com";
$array=$myWHOIS->rawlookup($thisname,$myWHOIS->WHOIS_SERVER);
}

echo "
".$thisname."
";
echo "";
$x=0;
while ($x {
echo " $x ";
echo " $array[$x] ";
$x ;
}
echo "
";
if (!ereg(".cn$",$thisname))
{
echo "
Furth infomation
";
$array_further=$myWHOIS->rawlookup($thisname,$myWHOIS->NEW_WHOIS);
echo "";
$x=0;
while ($x {
echo " $x ";
echo " $array_further[$x] ";
$x ;
}
echo "
";
}
?>

类的另类用法–数据的封装

星期一, 06月 2nd, 2008

类de另类用法–数据de封装
一般de情况下,如果使用classname::property是不能访问到类de属性de,但可以用classname::method()使用类de方法.同样de也不能用objectname->property访问到类de方法里de变量.利用这一特点,我可以将一些数据保存于类中,有点象c de私有属性.
<?
class data {
function value($var) {
static $d = array();
if(func_num_args() > 1) {
$d[$var] = func_get_arg(1);
}else {
return $d[$var];
}
}
}
//测试:
data::value("a",1);
data::value("b",2);
echo data::value("a");
echo data::value("b");
?>

第十二节 类的自动加载 [12]

星期一, 06月 2nd, 2008

当您尝试使用一个未定义de类时,PHP会报告一个致命错误. 解决方法就是添加一个类,可以用include包含一个文件. 毕竟您知道要用到哪个类. 但是,PHP提供了类de自动加载功能, 这可以节省编程de时间. 当您尝试使用一个PHP没有组织到de类, 它会寻找一个__autoloadde全局函数. 如果存在这个函数,PHP会用一个参数来调用它,参数即类de名称.
例子6.15说明了__autoload是如何使用de. 它假设当前目录下每个文件对应一个类. 当脚本尝试来产生一个类Userde实例,PHP会执行__autoload. 脚本假设class_User.php中定义有User类.. 不管调用时是大写还是小写,PHP将返回名称de小写.
Listing 6.15 Class autoloading

<?php
//define autoload function
function __autoload($class)
{
include(”class_” . ucfirst($class) . “.php”);
}
//use a class that must be autoloaded
$u = new User;
$u->name = “Leon”;
$u->printName();
?>

第七节 类的静态成员 [7]

星期一, 06月 2nd, 2008

类de静态成员与一般de类成员不同: 静态成员与对象de实例无关,只与类本身有关. 他们用来实现类要封装de功能和数据,但不包括特定对象de功能和数据. 静态成员包括静态方法和静态属性.
静态属性包含在类中要封装de数据,可以由所有类de实例共享. 实际上,除了属于一个固定de类并限制访问方式外,类de静态属性非常类似于函数de全局变量
我在下例中使用了一个静态属性Counter::$count. 它属于Counter类,而不属于任何Counterde实例.您不能用this来引用它,但可以用self或其它有效de命名表达. 在例子中,getCount方法返回self::$count,而不是Counter::$count.
静态方法则实现类需要封装de功能,与特定de对象无关. 静态方法非常类似于全局函数. 静态方法可以完全访问类de属性,也可以由对象de实例来访问,不论访问de限定语是否是什么.
在6.3例中,getCount是一个普通de方法,用->来调用. PHP建立一个this变量,尽管方法没有使用到.但是,getCount不属于任何对象.在有些情况下,我甚至希望在不存在有效de对象时调用它,那么就应该使用静态方法. PHP将不在静态方法内部建立this变量,即使您从一个对象中调用它们.
例子6.7由6.3改变getCount为静态方法而来. Static关键字不能阻止一个实例用->运算符来调用getCount,但PHP将不在方法内部建立this变量.如果您使用this->来调用,将会出错.
//6.3例指第四节–构造函数和析构函数中de例子(参看前文),通过两个例子de比较,您可以很好掌握
//static方法与普通方法之间de区别.
您可以写一个方法通过判断this是否建立来显示是否它被静态地或者非静态地调用. 当然,如果您用了static 关键字,不管它怎样被调用,这个方法总是静态de.
您de类也可以定义常量属性,不需要使用public static,只需要用const关键字即可. 常量属性总是静态de.它们是类de属性,而不是实例化该类de对象de属性.
Listing 6.7 Static members

<?php
class Counter
{
private static $count = 0;
const VERSION = 2.0;
function __construct()
{
self::$count ;
}
function __destruct()
{
self::$count–;
}
static function getCount()
{
return self::$count;
}
};

//创建一个实例,则__construct()将执行
$c = new Counter();
//输出 1
print(Counter::getCount() . “<br>n”);
//输出类de版本属性
print(”Version used: ” . Counter::VERSION . “<br>n”);
?>