内部类,实际开发中的应用体现
定义:放在一个类的内部的类我们就叫内部类。
在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号。
内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现outer.class和outer$inner.class两类。所以内部类的成员变量/方法名可以和外部类的相同。
内部类可以是静态static的,也可用public,default,protected和private修饰。(而外部顶级类即类名和文件名相同的只能使用public和default
分类:1.成员内部类 2.静态内部类 3.匿名内部类 4.方法内部类(几乎不用)
作用:间接解决多重继承的问题(内部类继承一个类,外部类继承一个类,实现多继承。最重要的作用);
内部类拥有外围类的所有元素的访问权限;
成员内部类,顾名思义,就是在一个类的内部定义一个类,作为类的一个成员属性(成员字段),类的成员内部类可以访问该类的属性和方法,因为他也是该类的一个成员。
要注意的是,成员内部类不能含有static的变量和方法。因为成员内部类需要先创建了外部类,才能创建它自己的,了解这一点,就可以明白更多事情,在此省略更多的细节了。
上代码:
package 内部类.成员内部类; public class Person { public void sayPerson(){ System.out.println("hello Person"); } }
package 内部类.成员内部类; public class Student extends Person { private int age; public int getAge(){ return age; } public void say(){ System.out.println("hello Student"); } private Grade1 getGrade1() { return new Grade1(); //建议用这种方式实例化 } private class Grade1{ public void say(){ Student.this.sayPerson();//内部类调用外部类的成员 Student.this.say(); System.out.println(Student.this.getAge()); System.out.println("hello Grade1"); } } public static void main(String[] args) { Student stu = new Student(); Student.Grade1 grade1 = stu.getGrade1(); //Student.Grade1 grade2 = stu.new Grade1();两种实例化内部类的方式 grade1.say(); } }
静态内部类:顾名思义内部类是静态的,这样的好处是不用拿到外部类对象就可以实例化内部类了,但是这样的话,内部类就不能引用外部类的非静态成员了(人无完人啊)
上代码 eg:HashMap 中的 Entry
package 内部类.静态内部类; public class Test { public int age=1; public static String name="shaolin"; static class Baby{ //静态内部类 public void say() { //System.out.println(age);不能访问age属性,只能访问静态属性(很容易理解) System.out.println("hello "+name); } } public static void main(String[] args) { Test.Baby temp=new Test.Baby(); //实例化静态内部类 temp.say(); } }
匿名内部类,顾名思义就是没有名字的内部类
上代码
package 内部类.匿名内部类; public class Test { public static void main(String[] args) { //相当继承Mother类并实现抽象方法 Person person=new Person(){ @Override public void say() { System.out.println("hello,匿名内部类"); } }; person.say(); } } abstract class Person{ //也可以是一个interface的 public abstract void say(); }