Java教程

Java 面向对象高级部分(内部类)

本文主要是介绍Java 面向对象高级部分(内部类),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

类的五大成员:属性, 方法, 构造器, 代码块, 内部类

内部类的分类:

1.定义在外部类局部位置上((方法中,代码块中)): ① 局部内部类(有类名) ② 匿名内部类(无类名)

2.定义在外部类的成员位置上 :①成员内部类(没用static修饰) ②静态内部类(用static修饰)

局部内部类

说明:局部内部类 是定义在外部类内的局部位置,(方法中,代码块中),有类名

1. 可以直接访问外部类的所有成员,包含私有的。

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

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

4. 局部内部类 ---  访问 --- 》外部类的成员【访问方式:直接访问】

5.外部类要 访问 局部内部类的成员    【访问方式:创建内部类对象再访问】

6.外部其他类不能访问局部内部类【因为局部内部类本质上属于一个局部变量】

7.如果外部类和局部内部类的成员重名,默认就近原则,如果想要访问外部类的成员可以使用(外部类名.this.成员)去访问

8. 局部内部类只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化。

 

匿名内部类

本质: 类    内部类     该类没有名字    同时还是一个对象

基于接口的匿名内部类

 

基于类的匿名内部类

public class AnonymousInnerClass {
    public static void main(String[] args) {
        Outer04 outer04 = new Outer04();
        outer04.method();
    }
}

class Outer04 { //外部类
    private int n1 = 10;//属性

    public void method() {
        //基于接口的匿名内部类
        // 3.老韩需求是 Tiger/Dog 类只是使用一次,后面再不使用
        // 4. 可以使用匿名内部类来简化开发
        // 5. tiger 的编译类型 ? IA
        // 6. tiger 的运行类型 ? 就是匿名内部类 Outer04$1
        /* 我们看底层 会分配 类名 Outer04$1
        class Outer04$1 implements IA {
            @Override public void cry() {
                System.out.println("老虎叫唤...");
            }
        } */
        //7. jdk 底层在创建匿名内部类 Outer04$1,立即马上就创建了 Outer04$1 实例,
        // 并且把地址 // 返回给 tiger
        //8. 匿名内部类使用一次,就不能再使用
        IA tiger = new IA() {
            @Override
            public void cry() {
                System.out.println("老虎叫唤...");
            }
        };
        System.out.println("tiger 的运行类型=" + tiger.getClass());

        //基于类的匿名内部类
        //1. father 编译类型 Father //2. father 运行类型 Outer04$2
        //3. 底层会创建匿名内部类
        /*
        class Outer04$2 extends Father{
            @Override public void test() {
                System.out.println("匿名内部类重写了 test 方法");
            }
        } */
        //4. 同时也直接返回了 匿名内部类 Outer04$2 的对象
        // 5. 注意("jack") 参数列表会传递给 构造器
        Father father = new Father("jack") {
            @Override
            public void test() {
                System.out.println("匿名内部类重写了 test 方法");
            }
        };
        System.out.println("father 对象的运行类型=" + father.getClass());//Outer04$2

        father.test();
    }
}

interface IA{
    public void cry();
}

class Father{
    private String name;

    public Father(String name) {
        this.name = name;
    }

    public void test(){
        System.out.println("KK");
    }
}

细节:

匿名内部类在底层实现中,要么是返回实现了接口的类的实例,要么返回继承了某类的子类实例

1.匿名内部类可以直接调用外部类的全部成员,包括私有

2. 不能添加访问修饰符,因为本质是个局部变量

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

4.外部其他类不能访问匿名内部类,理由同局部内部类

5..如果外部类和局部内部类的成员重名,默认就近原则,如果想要访问外部类的成员可以使用(外部类名.this.成员)去访问

最佳实践:

① 当作实参直接传递

public class InnerClass {
    public static void main(String[] args) {
        f1(new IL(){

            @Override
            public void show() {
                System.out.println("hah");
            }
        });
    }
    //形参是接口类型
    public static void f1(IL il){
        il.show();
    }
}


interface IL{
    public void show();
}

 

成员内部类

直接定义在外部类的成员位置,而不是再方法或者代码块中,并且没有static修饰

public class InnerClass {
    public static void main(String[] args) {
        AA aa = new AA();
        aa.kk();
    }
}


class AA{
    private int n1 = 10;
    public String name = "zaz";

    class BB{//可以直接调用外部类的全部成员包括私有
        public void say(){
            System.out.println("haha");
        }
    }

    public void kk(){
        BB bb = new BB();
        bb.say();
    }
}

因为其地位是一个类的成员,因此可以用(public privated protected 默认)的访问修饰符修饰,

细节:

可以直接访问外部类全部成员, 外部类要先创建对象才能访问

外部其他类可以访问成员内部类,有二种方式:

public class InnerClass {
    public static void main(String[] args) {
        AA aa = new AA();
        //普通成员是实例层面, 因此要确定是哪个对象创建内部类对象,因此是XX外部类对象名.new 成员内部类名()
        AA.BB bb = aa.new BB();
    }
}

在外部类中定义一个方法用于返回内部类对象

public class InnerClass {
    public static void main(String[] args) {
        AA aa = new AA();

        AA.BB bb = aa.getBB();
        bb.say();
    }
}


class AA{
    private int n1 = 10;
    public String name = "zaz";

    class BB{
        public void say(){
            System.out.println("haha");
        }
    }

    public BB getBB(){
        return new BB();
    }

}

静态内部类

与成员内部类相比他的定义前需要用static修饰,因此它属于类,是个类变量,而不是普通的成员变量,只能访问外部类全部的静态成员

外部类访问要先创建对象,在访问

class AA{
    private int n1 = 10;
    public String name = "zaz";

    static class BB{
        public void say(){
            System.out.println("haha");
        }
    }

    public void kk(){
        BB bb = new BB();
        bb.say();
    }
}

外部其他类访问静态内部类:

public class InnerClass {
    public static void main(String[] args) {
        AA.BB bb = new AA.BB();//但是该静态内部类仍然要满足访问权限,使用private 修饰不可以创建
        bb.say();
    }
}
//第二种方法就是定义一个返回静态内部类对象的方法

 

这篇关于Java 面向对象高级部分(内部类)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!