Java学习-看完这一篇文章,了解内部类

今天给大家分享一下内部类的知识,内部类是Java中比较难理解的一部分内容。但如果理清楚了,其实很简单。
内部类的分类
内部类分为四类

  • 成员内部类
  • 静态成员内部类
  • 局部内部类
  • 匿名内部类

内部类是什么,就是类里面的类

成员内部类

成员内部类,和成员方法,成员变量的"地位"相似

public class Outer {
    /**
     * 成员变量
     */
    public int Num = 100;
    /**
     * 成员方法 
     */
    public void f(){
        System.out.println("外部类的成员方法被调用");
    }
    /**
     * 成员内部类
     */
    public class Inner{
        public void method(){
            System.out.println(Num);
            f();	//这里可以看到,在内部类的成员方法中可以直接使用外部类的成员方法,
            		//也可以使用外部类的成员变量
        }
    }

    public static void main(String[] args) {
        /*
            成员内部类的实例化
            外部类.内部类 oi = new 外部类().new 内部类();
         */
        Outer.Inner oi = new Outer().new Inner();
        //调用内部类的成员方法
        oi.method();
        实例化的内部类对象只能调用内部类自己的成员变量成员方法,无法调用外部类的
    }
}

成员内部类实例化
/*
成员内部类的实例化
外部类.内部类 oi = new 外部类().new 内部类();
*/

静态成员内部类

就是在成员内部类的前面加上static关键字

public class Outer {
    /**
     * 静态成员变量
     */
    public static int number = 10;
    /**
     * 静态成员方法
     */
    public static void staticMethod(){
        System.out.println("静态方法被调用");
    }

    /**
     * 静态成员类只能调用外部类的静态方法和静态变量
     */
    public static class Inner{
        public void method(){
            System.out.println(number);
            staticMethod();
        }
    }
    public static void main(String[] args) {
        /**
         * 创建格式:外部类.内部类 oi = new 外部类.内部类();
         */
        Outer.Inner oi = new Outer.Inner();
        oi.method();
    }
}

局部内部类

局部内部类是指在类的方法中创建类

public class Outer {
    /**
     * 成员变量
     */
    public int Num = 100;

    /**
     * 成员方法
     */
    public void f(){
        System.out.println("外部类的成员方法被调用");
    }

    /**
     *成员方法中定义一个成员内部类
     */
    public void findInner(){
        //局部内部类
        class Inner{
            //局部内部类的成员变量
            int number;
            //局部内部类的成员方法
            public void method(){
                //可以随便调用外部类的成员变量和方法
                System.out.println(Num);
                f();
            }
        }
        /** 因为是局部内部类,只在方法中有用,所以不加修饰符
         *  创建对象时,需要在方法内部创建
         */
        Inner inner = new Inner();
        inner.method();

    }

    public static void main(String[] args) {
        Outer outer = new Outer();
        /**
         * 调用局部内部类,需要创建外部类对象,然后调用方法
         */
        outer.findInner();
    }
}

匿名内部类

匿名内部类也就是没有名字的内部类

正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写

但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口

  • 基于抽象类的内部类
基于抽象类的内部类
abstract class AbstractType {
    abstract public void test();
}

class TypeA extends AbstractType {

    @Override
    public void test() {
        System.out.println("一个类继承abstract修饰的类,完成abstract方法");
    }
}

public class Demo1 {
    public static void main(String[] args) {
        TypeA typeA = new TypeA();
        typeA.test();

        /*
        new AbstractType() {
            // 这里是类的本体
        }
        这里不存在类名,但是该类的本体是一个类继承了abstract修饰的类可以
        实现的类的本体。这里可以认为定义了的是一个abstract的一个子类
        并且创建了一个abstract的子类对象,赋值给了abstract修饰的类的
        引用数据类型变量
         */
        AbstractType at = new AbstractType() {
            @Override
            public void test() {
                System.out.println("匿名内部类的对象,调用方法");
            }
        };

        at.test();

        new AbstractType() {

            @Override
            public void test() {
                System.out.println("匿名内部类的匿名对象。可以调用方法");
            }
        }.test();

        testInnerType(typeA);

        testInnerType(new AbstractType() {
            @Override
            public void test() {
                System.out.println("匿名内部类对象,直接作为方法的参数使用!!!");
            }
        });
    }

    public static void testInnerType(AbstractType at) {
        at.test();
    }
}

  • 基于接口的内部类
2.基于接口的内部类
import java.util.Arrays;
import java.util.Comparator;

interface A {
    public void testA();
}

public class Demo2 {
    public static void main(String[] args) {
        /*
        这里定义的是一个接口A 的引用,指向的是一个接口的匿名内部类的对象
        new A() 之后的大括号内容是一个类遵从接口A之后完成的代码
         */
        A a = new A() {
            @Override
            public void testA() {
                System.out.println("接口的匿名内部类对象");
            }
        };

        a.testA();

        new A() {

            @Override
            public void testA() {
                System.out.println("接口匿名内部类的匿名对象,直接调用方法");
            }
        }.testA();

        test(new A() {
            @Override
            public void testA() {
                System.out.println("接口匿名内部类的匿名对象,直接作为方法的参数使用");
            }
        });

        Person p1 = new Person(1, "无双剑姬");
        Person p2 = new Person(2, "无极剑圣");
        Person p3 = new Person(3, "疾风剑豪");
        Person p4 = new Person(4, "影流之主");
        Person p5 = new Person(5, "刀锋意志");
        Person p6 = new Person(6, "瑞文");

        Person[] arr = {p2, p1, p5, p4, p3, p6};

        Arrays.sort(arr, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                return o2.getId() - o1.getId();
            }
        });

        System.out.println(Arrays.toString(arr));
    }

    public static void test(A a) {
        a.testA();
    }
}
//Person类
class Person {
    private int id; //id
    private String name;  //姓名

	//构造方法
    public Person() {
    }
    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }
	//成员变量的get和set方法
    public int getId() {	return id;	}
    public void setId(int id) {	this.id = id;	}
    public String getName() { return name;	}
    public void setName(String name) {	this.name = name;	 }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object obj) {
        System.out.println("equals被调用");
        if (this == obj) {
            return true;
        }

        if (!(obj instanceof Person)) {
            return false;
        }

        Person p = (Person) obj;
        return p.name.equals(this.name) && this.id == p.id;
    }

    @Override
    public int hashCode() {
        System.out.println("hashCode被调用");
        return id;
    }
}


这些代码希望大家可以自己动手敲一遍,有不懂得可以留言

内部类可以写链表,简化代码等作用

一道面试题…
Java学习-看完这一篇文章,了解内部类_第1张图片

下一篇分享一下接口和抽象类的区别

面试题答案,有其他方法的小伙伴在评论区留言

Java学习-看完这一篇文章,了解内部类_第2张图片

你可能感兴趣的:(Java学习之路)