1. 包(package)
对类文件进行分类管理,给类提供多层命名空间,类名的全称是包名.类名
包也是封装的一种体现
格式:package包名,全部小写,可以多级
写在程序第一行.(先package 再import 最后定义class或interface )
编译运行:(1)方式一:手动建包,自己建文件夹,然后java 包名.类名来
执行
(2)方式二:自动建包 javac –d . java文件 –d后面的“.”
代表当前目录
被访问的包中类的权限必须是public
2. 类的访问权限修饰符
(1)private 类访问权限:本类内部可以访问,不能继承到子类;
(2)default 什么都不写,包访问权限:本类内部可以访问,同包其他类也可以访问,同包可继承;
(3)protected 子类访问权限:本类内部可以访问,不同包的子类也可以访问,同包其他类也可以访问,能继承到子类;
(4)public 公共访问权限:任何地方都可以访问,能继承到子类;
3. import
当用到某个包中类的时候,用import关键字把包中的类导入,这样就不用每次写包名,方便了操作,简化了书写。
一个程序文件中只有一个package但是可以有多个import
4. 内部类
将一个类定义在另一个类的里面,里面的那个类就称为内部类(内置类、嵌套类)
(1)成员位置——成员内部类。可以被private、 static修饰,被static修饰的内部类只能访问外部类的静态成员出于安全性考虑,可以将内部类定义为private,然后在外部类中提供一个访问内部类方法的公共方法供外界调用。
/***************************************************************/
/*
内部类调用外部类成员:当成自己的成员来用
外部类调用内部类: 实例化一个内部类对象使用
内部类名 对象引用=new内部类名();
在测试类中直接调用内部类:
外部类名.内部类名 变量=外部类对象.内部类对象
成员内部类编译后.class文件的名字格式:外部类$内部类.class
*/
class Outer
{
private int num=10;
//定义一个内部类Inner
class Inner
{
//定义一个内部类方法
public void show()
{
System.out.println(num);
}
}
/*
若内部类中存在静态的方法,那么内部类也必须是静态的,
因为静态随着类的加载而加载,当外部类文件加载时,静态方法也需要被加载,
但是包含静态方法的那个内部类不是静态的,不会被加载,这就会产生冲突
因此,包含静态方法的内部类也需要是静态的,让他能随着外部类的加载而加载
*/
//定义一个静态内部类Inner2
public static class Inner2
{
public void show()
{
System.out.println("show");
}
//定义一个静态的内部类方法
public static void staticShow()
{
System.out.println("static method show");
}
}
//外部类的方法method
public void method()
{
Inner in=new Inner();
in.show();
}
}
class InnerTest
{
public static void main(String[] args)
{
Outer out=new Outer();//实例化外部类对象out
out.method();//调用外部类的method方法来调用内部类的show()
//直接使用内部类的方法
//格式:外部类名.内部类名 变量=外部类对象.内部类对象
Outer.Inner in=new Outer().new Inner();//实例化内部类
in.show();//调用内部类方法show();
//如果内部类是static修饰,调用格式为
//外部类名.内部类名 变量=new 外部类名.内部类名()
Outer.Inner2 in2=new Outer.Inner2();//实例化静态内部类
in2.show();//调用内部类的非静态方法show()
//由于静态方法可以通过类名调用,所以staticShow()调用为
Outer.Inner2.staticShow();
}
}
/***************************************************************/
(2)局部位置——局部内部类。也可以直接访问外部类中的成员,同时可以访问局部成员,但是必须是被final修饰的局部成员
/***************************************************************/
/*
局部内部类访问局部变量,该变量必须被final修饰。
原因:局部变量在栈内存,方法调用完毕就从栈中消失。而局部内部类
存储在堆中,随着对象消失而消失。为了延长局部变量的声明周期,所以要加final修饰
局部内部类可以看做方法中定义的局部变量,只有在方法中进行实例化操作并使用
局部内部类编译后.class文件的名字格式:外部类$1内部类.class
*/
class Outer
{
//外部类成员变量
private int num = 10;
public void method()
{
//局部变量
final int num2=100;
//定义局部内部类
class Inner
{
public void show()
{
System.out.println(num);
System.out.println(num2);
}
}
//创建内部类对象,调用show()方法
Inner in=new Inner();
in.show();
}
}
//测试类
class InnerTest2
{
public static void main(String[] args)
{
Outer out=new Outer();
out.method();
}
}
/***************************************************************/
(3)匿名内部类——没有名字的局部内部类。
前提:必须存在一个类,抽象类或者接口
格式:new 类名或者接口名()
{
重写类或者接口中的方法。
也可以自己定义新的方法。
};
/***************************************************************/
/*
匿名内部类
格式:new 类名或者接口名()
{
重写类或者接口类中的方法。
也可以自己定义新的方法。
};
理解:是一个继承了类或者实现了接口的匿名的子类对象。
什么情况下使用匿名内部类?
一般来说,当接口或者抽象类中的方法在3个以下的时候,
考虑使用匿名内部类。
以后当看到一个方法接收的形式参数是一个抽象类或者接口时,
就可以考虑用匿名内部类
*/
//定义一个接口,通过匿名内部类去实现它
interface Inner
{
public abstract void show();
}
//定义一个外部类
class Outer
{
public void method()
{
//定义匿名内部类实现Inner接口
//实质上,就是一个实现了Inner接口的子类的匿名对象
new Inner()
{
public void show()
{
System.out.println("show");
}
public void show2()
{
System.out.println("show2");
}
};
//调用方式
new Inner()
{
public void show()
{
System.out.println("show");
}
public void show2()
{
System.out.println("show2");
}
}.show();//调用show()方法
new Inner()
{
public void show()
{
System.out.println("show");
}
public void show2()
{
System.out.println("show2");
}
}.show2();//每次调用一次方法都需要以这种方式,太麻烦
//调用方式改进(多态的形式)
Inner in=new Inner()
{
public void show()
{
System.out.println("show");
}
};//定义父类引用指向子类对象
in.show();//调用子类的show()方法
}
}
//测试类
class InnerTest3
{
public static void main(String[] args)
{
Outer out=new Outer();
out.method();
}
}
/***************************************************************/
/******************匿名内部类使用情况示例**********************/
//定义一个接口Animal
interface Animal
{
public abstract void eat();
}
//一个实现了Animal接口的子类对象
class Dog implements Animal
{
public void eat()
{
System.out.println("Dog eat");
}
}
class Test
{
//定义一个形参是接口(或抽象类)的方法
public void show(Animal a)
{
a.eat();
}
}
class InnerTest4
{
public static void main(String[] args)
{
Test t=new Test();
//第一种调用方式,实例化接口的子类对象作为参数传递
Dog d=new Dog();
t.show(d);
//第二种方式,传递匿名内部类作为参数
t.show(new Animal()
{
public void eat()
{
System.out.println("匿名动物吃饭");
}
});//只使用一次的时候,第二种方式比较简便
}
}
|
|