首页 > 代码库 > Java面向对象程序设计--与C++对比说明:系列2(类机制)

Java面向对象程序设计--与C++对比说明:系列2(类机制)

1. Java中的包机制(Package):

1.1   Java容许将一系列的类组合到一个叫package的集合中。package机制是一种非常好的管理工作的方式并可以将你自己的工作和系统或第三方提供的代码分开。

一个类(class)可以使用其本身所在包中的任何类和其他包中的任何public类。

注意:只能使用*号来导入一个单独的包中的所有的类。像这种java.*或java.*.*形式的包的导入都是错误的。

例如:有两个包com.a.b和com.a.b.c,那么com.a.b.*导入的类将不包括com.a.b.c下面的类。要想导入com.a.b.c下面的类,可以使用这样的形式import com.a.b.c.*;

原因在于:从语法上讲,com.a.b和com.a.b.c之间毫无关系。

如何解决类名冲突问题?


import java.util.*;
import java.sql.*;

public class Sleep
{
    public static void main(String[] args) throws InterruptedException
    {
        Date today = new Date();
    }
}

上面这段代码中java.util包和java.sql包中都有一个名为Date的类,那么就会产生下面的编译错误:


Sleep.java:8: 错误: 对Date的引用不明确
        Date today = new Date();
        ^
  java.sql 中的类 java.sql.Date 和 java.util 中的类 java.util.Date 都匹配
Sleep.java:8: 错误: 对Date的引用不明确
        Date today = new Date();
                         ^
  java.sql 中的类 java.sql.Date 和 java.util 中的类 java.util.Date 都匹配
2 个错误

 


 

 解决上面问题的办法是:

1)如果只使用两个Date类中的一个,比如java.sql.Date那么在上面两个import语句的基础上加入import java.sql.Date; 语句。

2) 如果两个Date类都要被使用,那么在使用类的时候带上类的路径全名:

    java.util.Date date1 = new java.util.Date();

    java.sql.Date  date2 = new java.util.Date(); 

 可以将Java中的import看成是C++中namespace和using的类似!

 

1.2   Java SE 5.0 之后引入了静态导入机制(static import)

import static java.lang.System.*;
public class ImportTest
{
    public static void main(String[] args)
    {
        out.println("This is a static import!");
    }
}

 当使用静态导入时,导入的包中的各个类的静态方法和静态域也会被导入,而不仅仅是类的导入。

 静态导入机制的两个重要场景是:

1)使得数学函数以一种更加自然的方式被调用:

import static java.lang.Math.*;
public class ImportTest
{
    public static void main(String[] args)
    {
        int x = 2;
        int y = 3;
        System.out.println(sqrt(pow(x,2)+pow(y,2)));
    }
}

 上面的例子中,我们使用了静态导入,那么我们就不用每次繁琐的使用Math.sqrt和Math.pow了。

 

2)处理一些笨重繁琐的常数;

 

1.3   将一个类添加到一个包中:

要将类放入到一个包中,需要将包的名称放到类所在的源文件的开始位置。如果没有在开始位置添加这个包名,那么这个类将会放入到默认包中,

而在Java的最新版本中,默认包下的类是无法通过import来进行导入的。

在测是包的路径时遇到了一些问题:


package com.jiangheng.Test;

public class TestPackage
{
    public static void main(String[] args)
    {
        System.out.println("This is the end of the world!");
    }
}

 不管编译结果如何,最终形成的.class文件一定要放在 ./com/jiangheng/Test/ 目录下,这样java com.jiangheng.Test.TestPackage 才能正确执行。

 

2.一些类的设计原则:

   a. 除非有特别需要,否者将所有的字段都定义为private。

   b. 尽量对数据进行初始化。

   c. 在一个类中尽量避免使用太多的基本类型的情况!这一条的核心意思就是要以对象的思考方式去思考问题,而不是以一种“心中无对象”的的心态直接跳入细节设计之中。

   d. 并不是所有的字段都需要访问器和修改器(有需要就定义,没有需要就不定义).

   e.以一种形式化的方式来对类进行定义:

   尽量以这样的方式来展开类的内容:

       1) 公共特性;  (public features)

       2) 包范围的特性; (package features)

       3) 私有特性; (private features)

   对于上面的每一个特性又可以通过一下方式展开:

      -----实例方法(instance methods)

      -----静态方法(static methods)

      -----实例域(instance fields)

      -----静态域(static fields)

   

    f.将一个具有复杂功能的类分解成多个具有简单功能的简单类:

    下面是表示一副牌的类:


public class CardDeck
{
    public CardDeck(){...};
    public void shuffle(){...};
    public int getTopValue(){...};
    public int getTopSuit(){...};

    private int[] value;  //大小
    private int[] suit;   //花色
}

 显然上面的这个类是一个不好的实际,将对牌的表示和在牌上的操作混合在一起,可以将上面的类分解成下面的两个类:


public class CardDeck
{
     public CardDeck() {...}
     public void shuffle() {...}
     public Card getTop() {...}
     public void draw() {...}     

     private Card[] cards;       
}

public class Card
{
    public Card(int aValue,int aSuit) {...}   
    public int getValue() {...}
    public int getSuit() {...}

    private int value;       
}

     g. 让你所建立的类名和方法名尽量的反应类和方法的特性: