内部类的定义:在类内部进行其他类结构嵌套操作
一、存在意义(优点):
1、内部类与外部类可以方便的访问彼此的私有域(包含私有方法和私有属性)
eg:内部类
class Outter{
private String msg = "Outter中字符串";
//内部类
class Inner{
private String inMsg = "Inneer中字符串";
public void fun(){
//直接调用外部类的私有属性
System.out.println(msg);
}
}
public void test(){
//生产内部类对象
Inner in = new Inner();
in.fun();
}
}
public class Study{
public static void main (String[] args){
Outter out = new Outter();
out.test();
}
}
两个互相独立的类实现上述功能:(明显更加复杂)
class Outter{
private String msg = "Outter中字符串";
public String getMsg(){ //8
return this.msg;
}
public void test(){ //2.1
//this表示当前对象 即“Outter out = new Outter();”中的out
Inner in = new Inner(this); //3
in.fun(); //5
}
}
class Inner{
private String inMsg = "Inneer中字符串";
private Outter out;
//构造注入
public Inner (Outter out){ //3.1
this.out = out; //为Inner中的out变量初始化 //4
}
public void fun(){ //6
//直接调用外部类的私有属性
System.out.println(out.getMsg()); //7
}
}
public class Study{
public static void main (String[] args){
Outter out = new Outter(); //1 表示第一步
out.test(); //2
}
}
2、内部类是另外一种封装(保护性),对外部的其他类隐藏 (eg:心脏包在人身体内部)
3、内部类可以实现JAVA单继承的局限(如下代码)
class A{
private String msg = "test";
public String getMsg(){
return msg;
}
}
class B{
private int age = 20;
public int getAge(){
return age;
}
}
class C{
class InnerClassA extends A{
public String name(){
return super.getMsg();
}
}
class InnerClassB extends B{
public int age(){
return super.getAge();
}
}
public String name(){
return new InnerClassA().name();
}
public int age(){
return new InnerClassB().age();
}
}
public class Study{
public static void main (String[] args){
C c = new C();
System.out.println(c.name());
System.out.println(c.age());
}
}
二、缺点
结构复杂!
三、内部类与外部类的关系
1、对于非静态内部类,内部类的创建需要依赖外部类对象,在没有外部类实例化之前无法创建非静态内部类。
2、内部类只一个相对独立的个体,与外部类没有is-a关系。
3、内部类可以直接访问外部类的元素(包含私有域),但是外部类不可以直接访问内部类元素,需要通过内部类的引用间接访问。
在创建内部类的时候外部类的对象就会传进来
内部类可以直接访问外部类的元素(包含私有域):
class Outter{
private String msg;
private int age;
class Inner{
public void display(){
msg = "test"; //相当于Outter.this.msg = "test";
age = 20; //相当于Outter.this.age = 20;
System.out.println(msg);
System.out.println(age);
}
}
public void test(){
Inner in = new Inner();
in.display();
}
}
public class Study{
public static void main (String[] args){
Outter out = new Outter();
out.test();
}
}
外部类不可以直接访问内部类元素,需要通过内部类的引用间接访问:
class Outter{
class Inner{
private String msg = "InnerClass";
}
public void test(){
Inner in = new Inner();
System.out.println(in.msg);
}
}
public class Study{
public static void main (String[] args){
Outter out = new Outter();
out.test();
}
}
四、创建内部类语法(在外部类外部创建)
1、创建非静态内部类
外部类.内部类 内部类引用 = new 外部类().new 内部类();
Outter.Inner in = new Outter().new Inner();
2、创建静态内部类
外部类.内部类 内部类引用 = new 外部类.内部类();
Outter.Inner in = new Outter.Inner();
3、在外部类的内部创建内部类与在主方法中创建普通对象一样
eg:Inner in = new Inner();
五、内部类的分类
1、成员内部类(类比成员方法)
1.1成员内部类不能存在任何static变量或方法,但是可以访问外部类的静态域。
class Outter{
private String name = "test";
private static int age = 20;
class Inner{
private static int age = 50; //错误
public void fun(){
System.out.println(name);
System.out.println(age);
}
}
}
public class Study{
public static void main (String[] args){
Outter.Inner in = new Outter().new Inner();
in.fun();
}
}
就像在普通方法中不能只用static变量,因为static不依赖于对象而普通方法依赖于对象
class Outter{
private String name = "test";
private static int age = 20;
public void test(){
static int age = 5; //错
}
}
public class Study{
public static void main (String[] args){
Outter.Inner in = new Outter().new Inner();
in.fun();
}
}
1.2成员内部类依附外部类,所以只有创建的外部类才能创建内部类。
class Outter{
private String name = "test";
private static int age = 20;
class Inner{
public void fun(){
System.out.println(name);
System.out.println(age);
}
}
}
public class Study{
public static void main (String[] args){
Outter.Inner in = new Outter().new Inner();
in.fun();
}
}
2、静态内部类(类比静态方法)
2.1静态内部类的创建不需要依赖外部类,可以直接创建。
2.2静态内部类不可以使用任何外部类的非static域(包含属性和方法),但是可以存在自己的成员变量。
静态内部类不可以使用任何外部类的非static域:
class Outter{
private String name = "test";
private static int age = 20;
static class Inner{
public void fun(){
System.out.println(name); //错
System.out.println(age);
}
}
}
public class Study{
public static void main (String[] args){
Outter.Inner in = new Outter.Inner();
in.fun();
}
}
静态内部类不可以使用外部类的static变量,属性:
class Outter{
private String name = "test";
private static int age = 20;
static class Inner{
public void fun(){
System.out.println(age);
}
}
}
public class Study{
public static void main (String[] args){
Outter.Inner in = new Outter.Inner();
in.fun();
}
}
但是可以存在自己的成员变量:
class Outter{
private String name = "test";
private static int age = 20;
static class Inner{
private String name;
public void fun(){
System.out.println(age);
}
}
}
public class Study{
public static void main (String[] args){
Outter.Inner in = new Outter.Inner();
in.fun();
}
}
3、方法内部类
3.1方法内部类不允许使用访问权限修饰符public private protected均不允许
3.2方法内部类对外部完全隐藏,除了创建这个类的方法可以访问它以外,其他地方均不能访问
3.3方法内部类如果想使用方法形参,该形参必须使用final声明(JDK8将形参变为隐式final声明)l
class Outter{
private int num = 5;
public void display(int temp){
//方法内部类
class Inner{
public void fun(){
System.out.println(num); //普通方法可以访问类中的属性
System.out.println(temp);
}
}
new Inner().fun(); //在方法中
}
}
public class Study{
public static void main (String[] args){
Outter out = new Outter();
out.display(20);
}
}
如何证明形参被final修饰了:
class Outter{
private int num = 5;
public void display(int temp){
//方法内部类
class Inner{
public void fun(){
System.out.println(num); //普通方法可以访问类中的属性
temp++; //证明形参被final修饰
System.out.println(temp);
}
}
new Inner().fun(); //在方法中
}
}
public class Study{
public static void main (String[] args){
Outter out = new Outter();
out.display(20);
}
}
4、匿名内部类(lamdba表达式前身)
匿名内部类就是一个没有名字的方法内部类,因此特点与方法内部类完全一样,除此之外,还有:
4.1匿名内部类必须继承一个抽象类或者实现一个接口。
interface MyInterface{
void test();
}
class Outter{
private int num = 5;
public void display(int temp){
//匿名内部类,匿名的实现了MyInterface的接口
new MyInterface(){
public void test(){
System.out.println("匿名的实现了MyInterface的接口");
System.out.println(temp);
}
}.test();
}
}
public class Study{
public static void main (String[] args){
Outter out = new Outter();
out.display(20);
}
}
4.2匿名内部类没有构造方法,因为它没有类名。
------------------------------------------------------------------------------------------------------------------------终于写完了----------------------------------
------------------------------------------------------------------------------------------------------------------------THE END-----------------------------------