JAVA内部类

内部类就是在一个类中定义一个类

java中的内部类主要分为两类四种:

第一类:定义在外部类局部位置上,分为局部内部类( 有 类名)、匿名(没有类名)。

第二类:定义在外部类的成员位置上,分为成员内部类(没有static修饰)、静态内部类(使用static修饰)。

a.成员内部类的创建需要依赖于外部类对象-(成员方法必须通过对象调用),在没有外部类实例之前无法创建成员内部类对象

b.内部类与外部类相对独立,不是is a 的关系(发动机-汽车)

c.私有属性的互相访问,内部类可以直接访问外部类,而外部类访问内部类需要内部类的对象来访问

格式:

/*
    class 外部类名{
    	修饰符 class 内部类名{
    	
    	}
    }
*/

class Outer {
    public class Inner {
        
    }
}

内部类访问特点

1.内部类可以直接访问外部类的成员,包括私有的

2.外部类要访问内部类的成员,必须创建对象

1.成员内部类

成员内部类是定义在外部类的成员位置上,并且没有static修饰

成员内部类的使用

1.可以直接访问外部类的所有成员,包括私有的。外部类访问成员内部类访问方式:创建对象,再访问;

2.可以添加任意访问修饰符,因为它的地位就是一个成员;

3.作用域和外部类的其他成员一样,为整个类体

4.如果外部类和内部类的成员重名时,内部类访问的话,遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问。

5.外部其他类访问成员内部类有三种方式:第一种实例化外部类,然后访问;第二种将内部类作为外部类的成员实例化然后访问;第三种在外部类里面编写一个方法,可以返回内部类对象。
成员内部类语法

1.在外部类内部创建内部类对象

2.在外部类外部创建内部类对象,格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;

例:Outer.Inner oi = new Outer().new Inner();

成员内部类的推荐使用方案:将一个类,设计为内部类的目的,大多数都是不想让外界去访问,所以内部类的定义应该私有化,私有化之后,再提供一个可以让外界调用的方法,方法内部创建内部类对象并调用。

class Outer {
    private int num = 10;
    private class Inner {
        public void show() {
            System.out.println(num);
        }
    }
    public void method() {
        Inner i = new Inner();
        i.show();
    }
}
public class InnerDemo {
    public static void main(String[] args) {
		//Outer.Inner oi = new Outer().new Inner();
		//oi.show();
        Outer o = new Outer();
        o.method();
    }
}

2.静态内部类

   定义在外部类的内部,使用static修饰,类比静态方法,静态内部类不需要外部类对象产生就能使用,不能访问外部类的成员域,但能访问静态域

静态内部类的使用

1.可以直接访问外部内的所有静态成员,包含私有的,但不能直接访问非静态的成员 

2.可以添加任意访问修饰符,因为它的地位就是一个成员;

3.作用域和外部类的其他成员一样,为整个类体

4.如果外部类和内部类的成员重名时,内部类访问的话,遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问。

5.私有成员内部类访问,在自己所在的外部类中创建访问对象

静态内部类的语法

1.外部类内部:与成员内部类一样

2.外部类外部:外部类名.内部类名  对象名=new 外部类名.内部类名();

例:Outer.Inner oi = new Outer. Inner();

3.局部内部类

局部内部类是定义在外部类的局部位置,比如方法中,并且有类名。

1.局部内部类可以直接访问外部类的所有成员,包含私有的,也可以访问方法内的局部变量,访问方式——直接访问。

2.不能添加访问修饰符,因为它的地位就是一个局部变量,局部变量是不能使用修饰符的。但是可以使用final修饰,因为局部变量也可以使用final。

3.作用域仅仅在定义它的方法或代码块中

4.外部类访问局部内部类,访问方式:创建对象,在访问(注意:必须在作用域内)

5.局部内部类,外界是无法直接使用,需要在方法内部创建对象并使用

class Outer {
    private int num = 10;
    public void method() {
        int num2 = 20;
        class Inner {
            public void show() {
                System.out.println(num);
                System.out.println(num2);
            }
        }
        Inner i = new Inner();
        i.show();
    }
}
public class OuterDemo {
    public static void main(String[] args) {
        Outer o = new Outer();
        o.method();
    }
}

4.匿名内部类(重要)

概述:匿名内部类本质上是一个特殊的局部内部类(定义在方法内部)

前提:a.必须继承一个抽象类或者实现一个接口  b.没有构造方法

本质:是一个继承了该类或者实现了该接口的子类匿名对象

匿名内部类里面只能重写父类中的方法,然后调用。 

理解:匿名内部类是将(继承/实现),(方法重写),(创建对象)三个步骤,放在了一步进行

匿名内部类格式

格式:new 类名 ( ) { 重写方法 }  new 接口名 ( ) { 重写方法 }

new Inter(){
    @Override
    public void method(){}
} 

匿名内部类可以通过多态的形式接受

Inter i = new Inter(){
  @Override
    public void method(){
        
    }
}

匿名内部类直接调用方法:

interface Inter{
    void method();
}

class Test{
    public static void main(String[] args){
        new Inter(){
            @Override
            public void method(){
                System.out.println("我是匿名内部类");
            }
        }.method();	// 直接调用方法
    }
}

 匿名内部类在开发中的使用

当方法的形式参数是接口或抽象类时可以将匿名内部类作为实际参数进行传递

匿名内部类既是一个类,又是一个对象,既有定义类的特征,又有创建对象的特征。所以可以调用匿名内部类中的方法。

interface Jumpping {
    void jump();
}
class Cat implements Jumpping {
    @Override
    public void jump() {
        System.out.println("猫可以跳高了");
    }
}
class Dog implements Jumpping {
    @Override
    public void jump() {
        System.out.println("狗可以跳高了");
    }
}
class JumppingOperator {
    public void method(Jumpping j) { //new Cat();   new Dog();
        j.jump();
    }
}
class JumppingDemo {
    public static void main(String[] args) {
        //需求:创建接口操作类的对象,调用method方法
        JumppingOperator jo = new JumppingOperator();
        Jumpping j = new Cat();
        jo.method(j);

        Jumpping j2 = new Dog();
        jo.method(j2);
        System.out.println("--------");

        // 匿名内部类的简化
        jo.method(new Jumpping() {
            @Override
            public void jump() {
                System.out.println("猫可以跳高了");
            }
        });
		// 匿名内部类的简化
        jo.method(new Jumpping() {
            @Override
            public void jump() {
                System.out.println("狗可以跳高了");
            }
        });
    }
}