Java常用类(1)- 内部类

内部类的概念

概念:在一个类的内部再定义一个完整的类

特点:

//外部类Menber
public class Member {
    private String name;

    public static void main(String[] args) {
        new Member().new body().getName();
    }


    //内部类body
    class body{
        public void getName(){
            System.out.println(name);
        }
    }
}
  • 编译之后可以生成独立的字节码文件

  • 内部类可直接访问外部类的私有属性,从而不破坏封装

  •  可为外部类提供必要的内部功能组件

 

内部类的分类

成员内部类

  • 在类的内部定义,与实例变量、实例方法同级别的类

  • 外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象

package commonclass.innerclass;

import java.lang.reflect.Method;

//外部类Menber
public class Member {

    //实例变量
    private String name;

    //内部类body
    public class body{
        //内部类方法
        public void getName(){
            System.out.println(name);
        }
    }
}
import commonclass.innerclass.Member;

public class Application {
    public static void main(String[] args) {

        //调用内部类方法

        //方式一
        //1.创建外部类对象
        Member member = new Member();
        //2.创建内部类对象
        Member.body body = member.new body();

        //方式二
        Member.body body1 = new Member().new body();

        //方式三直接调用
        new Member().new body().getName();

        //3.调用内部类方法
        body.getName();//方式一调用
        body1.getName();//方式二调用
    }
}
  • 当外部类、内部类存在重名属性时,会优先访问内部类属性

  • 当外部类、内部类存在重名属性时,想要访问外部类属性怎么办? 外部类.this.外部类属性 

 

 

  • 成员内部类不能定义静态成员,但是可以定义静态常量

 

静态内部类

  • 不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员

  •  只能直接访问外部类的静态成员,访问非静态成员需要先实例化外部类,再访问

  • 当外部类、静态内部类存在重名静态属性时,想要访问外部类属性怎么办? 外部类.外部类属性 

package commonclass.innerclass;

//外部类
public class StaticClass {
    static String name = "李四";
    static int age = 14;
    double score = 99.9;

    //静态内部类,它的级别和外部类一样;
    //静态内部类存在的意义就是供外部类使用
    public static class Inner{

        //静态成员
        static String name = "张三";
        public void getName(){
            StaticClass staticClass = new StaticClass();
            System.out.println(name);
            System.out.println(age);
            System.out.println(staticClass.score);
            System.out.println(staticClass.name);
            System.out.println(StaticClass.name);

        }
    }
}
import commonclass.innerclass.Member;
import commonclass.innerclass.StaticClass;

public class Application {
    public static void main(String[] args) {
        StaticClass.Inner inner = new StaticClass.Inner();
        inner.getName();
    }
}

 

局部内部类

  • 定义在外部类方法中,作用范围和创建对象范围仅限于当前方法
  • 局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自动相当(简单来讲就是加载的方法和类加载的问题),方法中的变量必须为常量,jdk1.8之后默认在局部内部类中,将变量设置为常量
  • 使用范围只有在当前方法中使用
  • 局部内部类方法,最后需要将局部内部类实例化,在外部类的当前方法中调用。局部内部类才有意义
//外部类
public class LocalClass {

    //外部类参数
    private String name = "张三";

     public void print(){
         //方法参数
         int age = 20;

         //局部内部类
         class Inner{
             //局部内部类参数
             double score = 99.9;

             //局部内部类方法
             public void show(){
                 System.out.println(name);
                 System.out.println(age);
                 System.out.println(score);
             }
         }
         //实例化局部内部类
         Inner inner = new Inner();
         //调用局部内部类
         inner.show();
     }
}
import commonclass.innerclass.LocalClass;

public class Application {
    public static void main(String[] args) {
        //局部内部类只需要new外部类即可,调用外部类的方法,从而实现调用方法中的局部内部类
        LocalClass localClass = new LocalClass();
        localClass.print();
    }
}

 

 

 

 

匿名内部类

  • 没有类名的局部内部类(一切特征都与局部内部类相同),可有理解为匿名内部类是局部内部类的简写方式
  • 匿名内部类存在的前提是必须继承一个父类或者实现一个接口
  • 定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
  • 优点:减少代码量
  • 缺点:可读性比较差

前置

package commonclass.innerclass;

//接口
public interface UserService {
    void print();
}
package commonclass.innerclass;

//父类
public class Person {
    public void printFather(){
    }
}

局部内部类重写接口以及父类的方法

package commonclass.innerclass;

//外部类
public class AnonymousClass {

    //main方法
    public static void main(String[] args) {

        //局部内部类-接口
        class UserServiceImp implements UserService{
            @Override
            public void print() {
                System.out.println("接口重写");
            }
        }
        UserServiceImp userServiceImp = new UserServiceImp();
        userServiceImp.print();
        
        //局部内部类-父类
        class Student extends Person{
            //Alt+Insert选择Over.. Method重写父类方法
            @Override
            public void printFather() {
                System.out.println("继承父类,父类方法重写");
                super.printFather();
            }
        }
        Student student = new Student();
        student.printFather();
    }
}

 

匿名内部类重写接口以及父类的方法

package commonclass.innerclass;

//外部类
public class AnonymousClass {

    //main方法
    public static void main(String[] args) {

//匿名内部类-接口 UserService userService
= new UserService(){ @Override public void print() { System.out.println("匿名内部类重写接口"); } }; userService.print();
//匿名内部类-父类 Person person
= new Person(){ @Override public void printFather() { System.out.println("匿名内部类重写父类方法"); super.printFather(); } }; person.printFather(); } }

 

匿名内部类和局部内部类的比较

 

 

posted @ 2021-10-25 18:00  葛老头  阅读(57)  评论(0编辑  收藏  举报