目录
一.内部类
内部类分为:成员内部类,静态内部类,局部内部类和匿名内部类
1.概念:在一个类的内部再定义一个完整的类.
2.特点
-
编译之后可生成独立的字节码文件
-
内部类可直接访问外部类的私有成员,而不破坏封装
-
可为外部类提供必要的内部功能组件.
二.成员内部类
概念:在类的内部定义,与实例变量,实例方法同级别的类
-
外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象
-
Outer out = new Outer();
-
Outer.Inner in =out.new Inner();
-
当外部类.内部类存在重名属性时,会优先访问内部类属性
-
成员内部类不能定义静态成员,因为成员内部类不能脱离外部类对象而独立存在
package InnerClass; /** * 1.成员内部类(实例内部类) */ public class TestClass { public static void main(String[] args) { Outer outer = new Outer(); // Outer.Inner in = new Outer.Inner(); Outer.Inner in = outer.new Inner(); System.out.println(in.b);//20 in.m2(); } } //类级别,对象级别 class Outer{ private int a =10;//外部类实例变量 //实例方法 public void m1(){ } //成员内部类(实例层级) class Inner{ int a =20;//内部类实例变量 int b=20; public void m2(){ //内部类访问外部类实例变量 System.out.println(Outer.this.a);//10 System.out.println(a);//20 System.out.println(b);//20 System.out.println("Class inner m2()"); } } }
三.静态内部类
-
不依赖外部类类对象,可直接创建或通过类名访问, 可声明静态成员
-
package staticinnerclass;
public class TestStaticClass { public static void main(String[] args) { System.out.println(Outer.a); System.out.println(Outer.Inner.b); Outer.Inner in =new Outer.Inner(); in.m2(); } } class Outer{ static int a =10; //静态内部类 static class Inner{ static int b=20; public void m2(){ System.out.println("Inner m2()"); } } }
-
-
只能直接访问外部类的静态成员(实例成员需实例化外部类对象)
-
Outer.Inner.in= new Outer .Inner();
-
OUter.Inner.show();
-
package staticinnerclass;
/**
* 不依赖外部类类对象,可直接创建或通过类名访问, 可声明静态成员
*/
public class TestStaticClass1 {
public static void main(String[] args) {
System.out.println(Out.In.b);
Out.In in =new Out.In();
in.m2();
}
}
class Out{
static int a =10;
String s ="hello";
//静态内部类
static class In{
static int b=20;
public void m2(){
System.out.println(Out.a);
System.out.println("Inn.m2()");
// System.out.println(Out.s);
}
}
}
四.局部内部类
-
定义在外部类方法中,作用范围和创建对象范围仅限于当前方法.
package TestLocalInner;
/**
* 基础版本
*/
public class TestLocalInner {
public static void main(String[] args) {
//外部类当中的实例方法执行
Outer outer = new Outer();
outer.m1();
}
}
class Outer{
int a =10;
//外部类实例方法
public void m1(){
/*final*/ int b =20;//局部变量
// b=88;//赋值
System.out.println(b);
class Inner{//局部内部类
int c =30;
public void m2(){
System.out.println(Outer.this.a);//访问外部类的实例成员
System.out.println(this.c);//访问内部类的实例成员
System.out.println("Inner m2()");
// b=30;//必须是final修饰的常量
// System.out.println(b);//局部内部类访问外部类的局部变量,必须要final,jdk8自动添加
}
}
//局部内部类的实例方法
Inner in= new Inner();
System.out.println(in.c);
in.m2();
}
}
//30
//10
// 30
//Inner m2()
-
局部内部类访问外部类当前方法中的局部变量时,无法保障变量的生命周期与自身相同,变量必须修饰为final
package TestLocalInner;
/**
* 高级版本
*/
public class TestLocalInnerTallest {
public static void main(String[] args) {
//外部类当中的实例方法执行
Out outer = new Out();
outer.m1();
outer.p.print();
}
}
class Out {
printable p = null;
int a = 10;
//外部类实例方法
public void m1() {
/*final*/
int b = 20;//局部变量
// b=88;//赋值
class Inner implements printable {
@Override
public void print() {
System.out.println(b);
}//局部内部类
}
p = new Inner();
}
}
interface printable{
public void print();
}
//30
//10
// 30
//Inner m2()
-
限制类的使用范围
-
package TestLocalInner; public class TestLocal { public static void main(String[] args) { //学校开设新班 //需要高级的老师 // Teacher teacher =new TallTeacher(); // teacher.teach(); //校方没有这么多的高级老师,校方出台了一个规则 //按照奇数偶数的来分,奇数为初级,偶数为高级 Teacher t= School.getTeacher(1); t.teach(); } } class School{ public static Teacher getTeacher(int classNo){ //初级老师 class DiTeacher extends Teacher{ public void teach(){ System.out.println("老师在上课"); } } //高级老师 class TallTeacher extends Teacher{ public void teach(){ System.out.println("高级老师在上课"); } } Teacher currentTeacher =null;//返回值 if(classNo%2!=0){ currentTeacher= new DiTeacher(); }else{ currentTeacher= new TallTeacher(); } return currentTeacher; } } abstract class Teacher{ public abstract void teach(); }
五.匿名内部类
-
概念:没有类名的局部内部类(一切特征都与局部内部类相同)
-
必须继承一个父类或者实现一个接口
-
定义类,实现类,创建对象的语法合并,只能创建一个该类的对象
-
优点:减少代码量
-
缺点:可读性较差
package NiMIngCLass;
/**
* 局部内部类限制类的使用
*/
/**
* 局部内部类限制类的使用
*/
public class TestLocal {
public static void main(String[] args) {
//学校开设新班
//需要高级的老师
// Teacher teacher =new TallTeacher();
// teacher.teach();
//校方没有这么多的高级老师,校方出台了一个规则
//按照奇数偶数的来分,奇数为初级,偶数为高级
Teacher t = School.getTeacher(1);
t.teach();
}
}
class School {
public static Teacher getTeacher(int classNo) {
//初级老师(局部内部类)
class DiTeacher extends Teacher {
public void teach() {
System.out.println("老师在上课");
}
}
// //高级老师(匿名内部类)
// class TallTeacher extends Teacher {
// public void teach() {
// System.out.println("高级老师在上课");
// }
// }
Teacher currentTeacher = null;//返回值
if (classNo % 2 != 0) {
currentTeacher = new DiTeacher();
} else {
//匿名内部类
//创键了一个高级老师对象,是Teacher的子类.实现了teacher()方法
currentTeacher = new Teacher(){
public void teach() {
System.out.println("高级老师在上课");
}
};
}
return currentTeacher;
}
}
abstract class Teacher {
public abstract void teach();
}