资讯专栏INFORMATION COLUMN

java内部类总结

xiaodao / 3297人阅读

摘要:每个内部类都能独立地继承一个接口,而无论外部类是否已经继承了某个接口。因此,内部类使多重继承的解决方案变得更加完整。内部类中的与其他类一样是指的本身。但是静态内部类却没有。

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

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.为何要用内部类?

内部类可以访问外部类的所有成员,包括私有属性。

方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏。

每个内部类都能独立地继承一个接口,而无论外部类是否已经继承了某个接口。因此,内部类使多重继承的解决方案变得更加完整。

7.内部类的使用场景:
详情查看:http://blog.csdn.net/hivon/ar...
场景一:当某个类除了它的外部类,不再被其他的类使用时
场景二:解决一些非面向对象的语句块
场景三:一些多算法场合
场景四:适当使用内部类,使得代码更加灵活和富有扩展性

一、什么是内部类?(一般)

在一个类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、匿名内部类
匿名内部类其实就是一个没有名字的方法内部类,所以它符合方法内部类的所有约束,初次之外,还有一些地方需要注意:

匿名内部类是没有访问修饰符的。
匿名内部类必须继承一个抽象类或者实现一个接口
匿名内部类中不能存在任何静态成员或方法
匿名内部类是没有构造方法的,因为它没有类名。

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

代码来自[https://www.cnblogs.com/CodingAndRiding/p/7441438.html][2]
 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)外部类访问静态内部类成员:可以直接访问,内部类名.属性(方法)

参考:
https://www.cnblogs.com/latte...
http://blog.csdn.net/hivon/ar...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/68600.html

相关文章

  • Java知识点总结(三个步骤)

    摘要:对于一个名为的外围类和一个的内部类,在编译成功后,会出现这样两个文件和。 Java知识点总结(三个步骤) @(Java知识点总结)[Java, Java面向对象] [toc] 1-定义类 修饰符 访问修饰符: public protected default private 其他修饰符 abstract:抽象类不能实例化,专门用于继承的类final:最终类不能被继承 类名(驼峰命名...

    syoya 评论0 收藏0
  • Android 面试题合集 - 收藏集 - 掘金

    摘要:面试时,你被问到过协议吗掘金前言精通,熟练使用进行网路编程。面试的公司很多,其中有新浪微博面试题掘金年月新浪微博面试题及面试流程。 面试时,你被问到过 TCP/IP 协议吗? - 掘金前言: 精通 TCP/IP,熟练使用 Socket 进行网路编程。 看到这句话,有没有感到很熟悉呀?相信很多人在投递简历的时候都看到过这条要求,很多人会觉得我们在实际开发中一般用不到这些知识,所以对这些东...

    Jingbin_ 评论0 收藏0
  • Java系列之内部

    摘要:方法内部类就是局部内部类,一般定义在类的局部位置,它可以访问当前代码块及外部类的所有变量。 今天温习一下 Java 中的内部类,内部类一般有如下几种:静态内部类、成员内部类、匿名内部类和方法内部类,下文中将主要介绍静态内部类和成员内部类,主要内容如下: 概述 静态内部类 成员内部类 匿名内部类和方法内部类 总结 概述 顾名思义内部类就是在一个类内部定义的类,它是内部类是一个独立的类...

    Ververica 评论0 收藏0
  • Java系列之内部

    摘要:方法内部类就是局部内部类,一般定义在类的局部位置,它可以访问当前代码块及外部类的所有变量。 今天温习一下 Java 中的内部类,内部类一般有如下几种:静态内部类、成员内部类、匿名内部类和方法内部类,下文中将主要介绍静态内部类和成员内部类,主要内容如下: 概述 静态内部类 成员内部类 匿名内部类和方法内部类 总结 概述 顾名思义内部类就是在一个类内部定义的类,它是内部类是一个独立的类...

    crelaber 评论0 收藏0
  • 后台开发常问面试题集锦(问题搬运工,附链接)

    摘要:基础问题的的性能及原理之区别详解备忘笔记深入理解流水线抽象关键字修饰符知识点总结必看篇中的关键字解析回调机制解读抽象类与三大特征时间和时间戳的相互转换为什么要使用内部类对象锁和类锁的区别,,优缺点及比较提高篇八详解内部类单例模式和 Java基础问题 String的+的性能及原理 java之yield(),sleep(),wait()区别详解-备忘笔记 深入理解Java Stream流水...

    spacewander 评论0 收藏0

发表评论

0条评论

xiaodao

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<