包除了具有普通的特性,还具有一些高级特性,如包,内部类等。包在整个管理过程中起到了非常重要的作用,使用包可以有效地管理繁杂的类文件,解决类重名的问题。在类中应用包与权限修饰符,可以控制其他人对类成员的访问。
一个程序中同时使用到java.util.Date类与java.sql.Date类,如果在程序中不指定完整的类路径,编译器不会知道这段代码使用是java.util类包中的Date类还是java.sql类包中的Date类,所以需要在指定代码中给出完整的类路径。
例如,在程序中使用俩个不同Date类完整类的路径,可以使用如下代码:
java.util.Date date=new java.util.Date();
java.sql.Date date2=new java.sql.Date(1000);
在Java中采用类包机制非常重要,类包不仅可以解决类名冲突问题,还可以在开发庞大的应用程序时,帮助开发人员管理庞大的应用程序组件,方便软件复用。
package 包名
在类中指定包名时,需要将package表达式放置在程序的第一行,他必须是文件中的第一行非注释代码。使用package关键字为类指定包名之后,包名将会成为类名中的一部分,预示着这个类必须指定全名。例如,在使用位于com.mr包下的Dog.java类时,需要使用形如com.mr.Dog这样的表达式。
package com.mr; //指定包名
public class Math {
public static void main(String[] args) {
// TODO 自动生成的方法存根
System.out.println("不是java.lang.Math类,而是com.mr.Math");
}
}
使用import关键字导入包
如果某个类中需要使用Math类,那么如何告知编译器当前应该使用哪一个包中的Math类,是java.lang.Math类还是com.mr.Math类?这是一个令人困扰的问题。此时,可以使用Java中的import关键字指定。例如,如果在程序中使用import关键字导入com.mr.Math类,在程序中使用Math类时就会自动选择com.mr.Math类。import关键字的语法如下:
import com.mr.*; //导入com.mr包中的所有类
import com.mr.Math //导入com.mr包中的Math
在使用import关键字时,可以指定类的完整描述,如果为了使用包中更多的类,可以在使用import关键字指定时在包指定后加上*,这表示可以在程序中使用该包中所有类
使用import导入静态成员
import关键字除导入包外,还可以导入静态成员,这是JDK5.0以上版本提供的功能。导入静态成员可以使编程更为方便。使用import导入静态成员的语法如下
import static 静态成员
package com.mr;
import static java.lang.Math.max; //导入静态成员方法
import static java.lang.System.out; //导入静态成员变量
public class ImportTest {
public static void main(String[] args) {
// TODO 自动生成的方法存根
out.println("1和4的较大值为:"+max(1,4));//主方法中可以直接使用这些静态成员
}
}
内部类
成员内部类
在一个类中使用内部类,可以在内部类中直接存取其所在类的私有成员变量。成员内部类的语法如下:
class OuterClass{ //外部类
class innerClass{ //内部类
}
}
在成员内部类中可以随意使用外部类的成员方法及成员变量,尽管这些类成员被修饰为private。
内部类的实例一定要绑定在外部类的实例上,如果从外部类中初始化一个内部类对象,那么内部类对象就会绑定在外部类对象上。内部类初始化方式与其他类的初始化方式相同,都是使用new关键字。下面来看一个实例。
public class Car { //创建汽车类
private String brand; //汽车品牌
public Car(String brand) { //汽车类的构造方法,参数为汽车品牌
this.brand=brand; //给汽车品牌赋值
}
//成员内部类
class Engine{ //发动机类(内部类)
//成员变量
String model; //发动机型号
//成员方法
public Engine(String model) { //发动机类的构造方法,参数为发动机型号
this.model=model; //给发动机型号赋值
}
public void ignite() { //(发动机)点火方法
System.out.println("发动机"+this.model+"点火");
}
}
public void start() { //启动(汽车)方法
System.out.println("启动"+this.brand);
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
Car car=new Car("大众朗行"); //创建汽车类对象,并为汽车品牌赋值
car.start(); //汽车类对象调用启动(汽车)方法
//创建发动机类(内部类)对象,并为发动机型号赋值
Car.Engine engine=car.new Engine("EA211");
engine.ignite(); //发动机类对象调用(发动机)点火方法
}
}
外部类 outer=new 外部类();
外部类。内部类inner=outer。new 内部类();
public class TheSameName {
private int x=7; //外部类的x
private class lnner{
private int x=9; //内部类的x
public void doit() {
int x=11; //局部变量x
x++;
this.x++; //调用内部类的x
TheSameName.this.x++; //调用外部类的x
}
}
}
匿名内部类
匿名类是只在创建对象时才会编写类体的一种写法。匿名类的特点是“现用现写”,其语法如下:
new 父类/父接口(){
子类实现的内容
};
abstract class Dog{
String Color;
public abstract void move();
public abstract void call();
}
public class Demo {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Dog maomao=new Dog() {
public void move() {
System.out.println("四腿狂奔");
}
public void call() {
System.out.println("嗷呜~");
}
};
maomao.Color="灰色";
maomao.move();
maomao.call();
}
}
匿名类不能写构造方法
匿名类不能定义静态的成员
如果匿名类创建的对象没有赋值给任何引用变量,会导致该对象用完一次就会被Java虚拟机销毁。