类包
在Java中,我们可以使用class关键字来进行定义一个类,在程序被编译后就会产生一个.class文件。类的定义是规定类名不能重复的,如果程序内只定义了少量的类,那自然不用担心这个问题。
但是,随着类的数量增多,那么难免会出现这个问题,如果根据需求需要定义两个名字相同但是程序逻辑不同的类时,那么该如何解决呢,最好的方法就是将这个两个类放置在不同的包下面。
类的定义规定,在同一个类包下面不允许出来同名的类,但是在不同类包下面就允许出现这种情况,相当于将两个同名的类放入了不同的盒子内,避免出现这个问题。
如果一个程序内存在多个同名不同包的max类,那么该如何使用指定包的类呢?
在使用该类时使用该类的类路径,也成为绝对路径
指定包名(package)
在进行创建包的时候需要注意的是,Java包的命名规则建议使用全小写字母进行命名。
需要了解的是如果一个类没有被定义在一个指定的包内,那么该类就被归纳到默认包(default package)中。
在某个包下面创建一个类的话,需要在这个类的开头加上表达式 package 包名,该表达式需要放置在程序的第一行,使用package关键字指定包名之后,包名也会成为类名的一部分,在不同包下使用该类的话,需要使用 import 包名.类名 的格式。
导包
在Java中,如果需要使用到其它包内的类的话,除了使用该类的绝对路径之外,我们还可以使用Java中 import 关键字来指定。例如,如果在其它包内也定义了一个Math,那么假如我们只想使用该Math类的话,那么我们可以使用import关键字进行导包。、】
package test;
import Number_5.Math; //导包,导入其它包内的Math类
public class Demo_4 {
public static void main(String[] args) {
int max = Math.max(4, 6); // 进行导包后,再使用时,直接使用包名.类名的方法进行使用
System.out.println(max);
}
}
需要注意的是,如果使用import导入某个包下的所有类时,这些类并不包括该包下的子包的类。如果需要使用子包中的类时,需要对子包进行单独引用。
导入静态方法或静态成员
使用import关键字还可以对静态方法与静态变量进行导包。
import java.lang.max;
import java.lang.System.out;
public class Demo{
public static void main(String[] args){
out.println("较大值为:"+(max(1,4))); // 导入后可直接使用
}
}
成员内部类
定义在一个类成员位置的内部类,称为成员内部类,在成员内部类中可以使用外部类的的任意成员变量与成员方法,即使该外部类成员变量被private所修饰。
package test;
public class Demo_4 {
private int num;
static int i=0;
// 内部类
class test{
public void show(){
// 内部类调用外部类的成员变量
System.out.println(num);
System.out.println(i);
}
}
}
因为private等权限修饰符是针对外界的调用而进行权限判断的,但是成员内部类定义在该类的内部,那么相对于该类的一部分,就像该类的方法也是可以调用被private修饰的成员变量一般,成员内部类属于外部类的成员之一。
内部类是依赖于外部类的存在而存在。除非程序中已经有了一个外部类的对象,否则内部类一般不会单独存在。
两种方法:
对外部类编写get方法,对外提供内部类的对象
如果内部类没有被private修饰,那么可以在外界创建一个内部类的对象;
外部类与内部类之间也可使用this关键字,如果在内部类中需要使用到外部类的成员变量,那么可以使用外部类.this.变量名的方式使用。
public class Demo_4{
public static void main(String[] args) {
W.N a=new W().new N();
a.show();
}
}
class W {
private int i=10;
class N {
private int i=20;
public void show(){
int i=30;
System.out.println(i); // 方法内的i
System.out.println(this.i); // 内部类的i
System.out.println(W.this.i); // 外部类的i
}
}
}
匿名内部类
匿名内部类本质是一个隐藏了名字的内部类。匿名类是只有在创建时才会编写类体的一种写法
public class Demo_4{
public static void main(String[] args) {
// 匿名内部类
new Swit(){
@Override
public void swit(){
System.out.println("重写了swit方法");
}
};
}
}
interface Swit{
public void swit();
}
匿名内部类编译后会产生一个以 “外部类名$序号“ 为名称的 .class文件,序号以1-n排列,分别代表1-n个匿名内部类。那么我们可以找到这个.class文件,并对其进行反编译来查看我的结论是否正确。
上述反编译的结果可以说明,使用匿名内部类的格式创建的是一个匿名内部类的对象,而大括号内{}的才是匿名内部类的类体。
1.匿名内部类的对象如果没有赋值给任何引用变量的话,该对象会在使用后被Java虚拟机自动销毁。
2.匿名类不能写构造方法。
3.匿名类不能定义静态的成员。
那么匿名内部类对象可以赋值给那些引用变量呢?可以被赋值给被继承的接口或者父类对象。形成多态
public class Demo_4{
public static void main(String[] args) {
Swit s=new Swit(){
public void swit(){
System.out.println("重写了swit方法");
}
};
s.swit(); // 父类对象调用子类重写的方法
}
}
interface Swit{
public void swit();
}