java内部类总结 问题:内部类、静态内部类区别、使用场景?

问题:内部类、静态内部类区别、使用场景?
1.静态内部类可以有静态成员(方法,属性),而非静态内部类则不能有静态成员(方法,属性)。
2.静态内部类只能够访问外部类的静态成员,而非静态内部类则可以访问外部类的所有成员(方法,属性)。
3.实例化方式不同:
(1)实例化成员内部类“”
通过外部类对象创建
OutClassTest oc1 = new OutClassTest();
OutClassTest.InnerClass no_static_inner = oc1.new InnerClass();
(2)实例化静态内部类:
OutClassTest.InnerStaticClass inner = new OutClassTest.InnerStaticClass();

3.访问内部类成员属性不同:
(1)外部类访问内部类属性和方法:
外部类可以通过内部类引用间接访问内部类元素 类似:new IN().inMessage()
(2)外部类访问静态内部类:
调用内部静态类的方法或静态变量,通过类名直接调用
OutClassTest.InnerStaticClass.static_value
OutClassTest.InnerStaticClass.getMessage()
6.为何要用内部类?

内部类可以访问外部类的所有成员,包括私有属性。
方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏。
每个内部类都能独立地继承一个接口,而无论外部类是否已经继承了某个接口。因此,内部类使多重继承的解决方案变得更加完整。
一、什么是内部类?(一般)
在一个类Out的内部定义一个类in,这个类就是内部类,相应的Out就成为外部类。

二、内部类与外部类的联系
1、内部类是一个编译时概念,编译后外部类及其内部类会生成两个独立的class文件: OuterClass.class和OuterClass$InnerClass.class
2、内部类可以直接访问外部类的元素,但是外部类不可以直接访问内部类的元素

3、外部类可以通过内部类引用间接访问内部类元素

4、对于静态内部类来说,静态内部类是不依赖于外部类的,也就说可以在不创建外部类对象的情况下创建内部类的对象。另外,静态内部类是不持有指向外部类对象的引用的

三、内部类的分类
成员内部类、局部内部类、匿名内部类、静态内部类。

1、成员内部类
成员内部类就是普通的内部类,内部类可以声明public、protected、private等访问限制,可以声明 为abstract的供其他内部类或外部类继承与扩展,或者声明为static、final的,也可以实现特定的接口。
如果成员内部类用private修饰,则只能在外部类的内部访问,如果用public修饰,则任何地方都能访问;如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问;
如果是默认访问权限,则只能在同一个包下访问。这一点和外部类有一点不一样,外部类只能被public和包访问两种权限修饰。

外部类按常规的类访问方式使用内部类,唯一的差别是外部类可以访问内部类的所有方法与属性,包括私有方法与属性。

内部类中的this与其他类一样是指的本身。创建内部类对象时,它会与创造它的外围对象有了某种联系,于是能访问外围类的所有成员,不需任何特殊条件,可理 解为内部类链接到外部类。 用外部类创建内部类对象时,此内部类对象会秘密的捕获一个指向外部类的引用,于是,可以通过这个引用来访问外围类的成员。

2、局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。

3、匿名内部类
匿名内部类其实就是一个没有名字的方法内部类,所以它符合方法内部类的所有约束,初次之外,还有一些地方需要注意:
匿名内部类是没有访问修饰符的。
匿名内部类必须继承一个抽象类或者实现一个接口
匿名内部类中不能存在任何静态成员或方法
匿名内部类是没有构造方法的,因为它没有类名。

一般使用匿名内部类的场景是,要继承或实现的接口只有一个抽象方法:

 public class Test {
    public static void main(String[] args) {
        //4.匿名内部类
        //主要是针对那些不能直接创建对象的抽象类和接口而来的
        Student stu=new Student();
        System.out.println(stu.getClass());//class com.aowin.noname.Student
        //4.1.通过实体类创建匿名内部类对象
        //相当于创建该类的一个子类对象
        Person p=new Person(){
            public void eat(){
                System.out.println("吃八元套餐");
            }
        };
        p.eat();
        System.out.println(p.getClass());//class com.aowin.noname.Test$1//系统自动为子类命名Test$1
        
        Dog dog=new Dog();
        dog.bark();
        //4.2.通过抽象类创建匿名内部类对象
        //相当于定义了该抽象类的一个子类对象,并重写了抽象类中所有的抽象方法
        Animal an=new Animal(){
            public void bark(){
                System.out.println("汪汪汪...");
            }
        };
        an.bark();
        //返回的是包名加类名
        System.out.println(an.getClass());//class com.aowin.noname.Test$2
        
        //4.3.通过接口创建匿名内部类对象
        //相当于定义了该接口的一个实现类对象,并重写了接口中所有的抽象方法
        Sportable s=new Sportable(){
            public void sport(){
                System.out.println("打篮球");
            }
        };
        s.sport();
        System.out.println(s.getClass());//class com.aowin.noname.Test$3
        
    }
}
//实体类
class Person{
    public void eat(){
        System.out.println("吃饭");
    }
}
class Student extends Person{
    public void eat(){
        System.out.println("吃八元套餐");
    }
}
//抽象类
abstract class Animal{
    public abstract void bark();
}
class Dog extends Animal{
    public void bark() {
        System.out.println("汪汪...");
    }
}
//接口
interface Sportable{
    public abstract void sport();
}
4、静态内部类
关键字static可以修饰成员变量、方法、代码块,其实它还可以修饰内部类,使用static修饰的内部类我们称之为静态内部类。
静态内部类与非静态内部类之间存在一个最大的区别,我们知道非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围内。
但是静态内部类却没有。没有这个引用就意味着:
静态内部类的创建是不需要依赖于外围类,可以直接创建
静态内部类不可以使用任何外围类的非static成员变量和方法,而内部类则都可以

    private static String outerName;
    public  int age;
 
    static class InnerClass1{
        /* 在静态内部类中可以存在静态成员 */
        public static String _innerName = "static variable";
        public void display(){
            /*
             * 静态内部类只能访问外部类的静态成员变量和方法
             * 不能访问外部类的非静态成员变量和方法
             */
            System.out.println("OutClass name :" + outerName);
        }
    }
    class InnerClass2{
        /* 非静态内部类中不能存在静态成员 */
        public String _innerName = "no static variable";
        /* 非静态内部类中可以调用外部类的任何成员,不管是静态的还是非静态的 */
        public void display(){
            System.out.println("OuterClass name:" + outerName);
            System.out.println("OuterClass age:" + age);
        }
    }
    public void display(){
        /* 外部类能直接访问静态内部类静态元素 */
        System.out.println(InnerClass1._innerName);
        /* 静态内部类可以直接创建实例不需要依赖于外部类 */
        new InnerClass1().display();
        /* 非静态内部的创建需要依赖于外部类 */
        OuterClass.InnerClass2 inner2 = new OuterClass().new InnerClass2();
        /* 非静态内部类的成员需要使用非静态内部类的实例访问 */
        System.out.println(inner2._innerName);
        inner2.display();
    }
 
    public static void main(String[] args) {
        OuterClass outer = new OuterClass();
        outer.display();
    }
}
四、内部类和外部类的相互访问
1、内部类访问外部类成员

当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:

外部类.this.成员变量 
外部类.this.成员方法
但是静态内部类,只能访问外部类的静态成员
2、外部类访问内部类成员
外部类可以通过内部类引用间接访问内部类元素

外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问:

外部类访问内部类:
new In().inMessage();  //必须先创建内部类的对象,再访问
 
    class In{     //内部类
        public void inMessage() {
            System.out.println("外部类访问");  //外部类的private成员
        }
    }  
3、静态内部类与外部类的访问(相当于嵌套类)

(1)静态内部类访问外部类: 只能访问外部类的静态成员,不能访问非静态成员!
(2)外部类访问静态内部类成员:可以直接访问,内部类名.属性(方法)

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 基础核心总结Java 概述 什么是 Java2 Java 的特点Java 开发环境 JDK JRE Java 开发环境配置 Java 基本语法 数据类型基础语法运算符 Java 执行控制流程条件语句 if 条件语句 if...else 条件语句if...else if 多分支语句switch 多分支语句 循环语句 while 循环语句do...while 循环for 循环语句 跳转语句 break 语句 continue 语句面向对象 类也是-种对象对象的创建 属性和方法 构造方法 方法重载 方法的重写 初始化 类的初始化 成员初始化 构造器初始化初始化顺序 数组初始化 对象的销毁 对象作用域 this 和 super 访问控制权限继承 多态组合代理 向上转型static final 接口和抽象类接口 抽象类异常 认 识 Exception 什么是 Throwable 常见的 Exception 与 Exception 有关的 Java 关键字 throws 和 throw try 、finally 、catch 什么是 Error 内部类 创建内部类集合 Iterable 接口顶层接口 ArrayList Vector LinkedList 类Stack HashSet TreeSet LinkedHashSet 类 PriorityQueue HashMap TreeMap 类 LinkedHashMap 类 Hashtable 类IdentityHashMap 类WeakHashMap 类 Collections 类集合实现类特征图 泛形 泛型的使用 用泛型表示类 用泛型表示接口泛型方法 泛型通配符 反射 Class 类Field 类Method 类ClassLoader 类 枚举 枚举特性 枚举和普通类-样枚举神秘之处 枚举类 I/O File 类 基础 IO 类和相关方法InputStream OutputStream Reader 类Writer 类 InputStream 及其子类 OutputStream 及其子类Reader 及其子类Writer 及其子类 注解 关于 null 的几种处理方式大小写敏感 null 是任何引用类型的初始值 null 只是-种特殊的值使用 Null-Safe 方法null 判断 关于思维导图 Java.IO Java.lang Java.math Java.net Java 基础核心总结 V2.0 IO 传统的 BIO BIO NIO 和 AIO 的区别什么是流 流的分类 节点流和处理流 Java IO 的核心类 File Java IO 流对象 字节流对象InputStream OutputStream 字符流对象Reader Writer 字节流与字符流的转换新潮的 NIO 缓冲区(Buffer)通道(Channel) 示例:文件拷贝案例 BIO 和 NIO 拷贝文件的区别操作系统的零拷贝 选择器(Selectors) 选择键(SelectionKey) 示例:简易的客户端服务器通信 集合 集合框架总览 -、Iterator Iterable ListIterator 二、Map 和 Collection 接口Map 集合体系详解 HashMap LinkedHashMap TreeMap WeakHashMap Hashtable Collection 集合体系详解 Set 接口 AbstractSet 抽象类SortedSet 接口HashSet LinkedHashSet TreeSet List 接口 AbstractList 和 AbstractSequentialList Vector Stack ArrayList LinkedList Queue接口Deque 接口 AbstractQueue 抽象类LinkedList ArrayDeque PriorityQueue 反射的思想及作用 反射的基本使用 获取类的 Class 对象构造类的实例化对象获取-个类的所有信息 获取类中的变量(Field) 获取类中的方法(Method) 获取类的构造器(Constructor) 获取注解 通过反射调用方法反射的应用场景 Spring 的 IOC 容器反射 + 抽象工厂模式 JDBC 加载数据库驱动类反射的优势及缺陷 增加程序的灵活性破坏类的封装性 性能损耗 代理模式 静态代理与动态代理常见的动态代理实现JDK Proxy CGLIB JDK Proxy 和 CGLIB 的对比动态代理的实际应用 Spring AOP 变量 变量汇总实例变量 实例变量的特点全局变量 静态变量 静态变量的特点类变量 局部变量

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值