java-内部类详解

一、内部类的定义和使用

1、内部类定义:

所谓内部类就是在一个类的内部又定义其他类,在结构上形成嵌套关系。

下面定义一个简单的内部类:

class Outter{
    private int count = 100;
    //定义一个内部类Inner
    class Inner{
        public void print(){    //定义一个普通方法
            System.out.println(count);    //调用外部类私有属性
        }
    }
    //在外部类中定义一个方法
    public void fun(){
        Inner in = new Inner(); //产生内部类对象
        in.print(); // 使用内部类提供的print()方法
    }
}
public class Demo2{
    public static void main(String[] args) {
        Outter out = new Outter(); //产生外部类对象
        out.fun(); //调用外部类方法
    }
}

可以看到,内部类虽然可以方便的调用外部类的私有属性,但是,引入内部类后,程序的结构有些混乱。

2、如何创建类对象:

     1) 在使用内部类的时候创建内部类对象:

           外部类.内部类 内部类对象 = new 外部类().new 内部类();

           Outter.Inner in = new Outter().new Inner();

     2) 在外部类内部创建内部类对象:

            Inner in = new Inner();

     3) 在外部类的外部创建对象:

            外部类.内部类 内部类对象 = new 外部类.内部类();

            Outter.Inner in = new Outter.Inner();

3、为什么使用内部类:

     1) 内部类方法可以访问该类定义所在作用域中的属性,包括被 private 修饰的私有属性

     2) 内部类对同一包中的其他类来说是隐藏的

     3) 内部类可以解决 java 单继承的缺陷

     4) 当想要定义一个回调函数却不想写大量代码的时候,我们可以选择使用匿名内部类来实现

示例:使用内部类实现多继承

class A{
    public void funcA() {
        System.out.println("类A的方法");
    }
}
class B{
    public void funcB() {
        System.out.println("类B的方法");
    }
}
class Outter{
    class InnerClassA extends A{
        public void printA(){
            super.funcA();
        }
    }
    class InnerClassB extends B{
        public void printB(){
            super.funcB();
        }
    }
    public void print(){
        new InnerClassA().printA();
        new InnerClassB().printB();
    }
}
public class Demo2{
    public static void main(String[] args) {
        Outter out = new Outter();
        out.print();   
    }
}

4、内部类与外部类有什么关系:

     1) 对于非静态内部类,内部类的创建依赖外部类的实例对象,在没有外部类实例之前是无法创建内部类的。

     2) 内部类是一个相对独立的实体,与外部类不是is-a关系。

     3) 内部类可以直接访问外部类的属性(包含私有属性),但是外部类不可以直接访问内部类的属性。

     4) 外部类可以通过内部类引用,间接访问内部类属性。

5、java中内部类的分类:

      1) 实例内部类(成员内部类)

      2) 静态内部类

      3) 局部内部类(方法内部类)

      4) 匿名内部类


二、内部类详解

1、实例内部类(成员内部类):

需要注意两点:

     1)成员内部类中不能存在任何static的变量和方法。

     2)成员内部类是依附于外部类的,所以只有先创建外部类后才能够创建内部类。

2、静态内部类:

使用static修饰的内部类我们称之为静态内部类。

静态内部类与非静态内部类之间最大的区别,在于非静态内部类在编译完成之后会隐含地保存一个引用,该引用是指向创建它的外部类,但是静态内部类却没有,因此:

     1)静态内部类对象的创建不需要依赖于外部类,可以直接创建

     2)静态内部类不可以使用任何外部类的非static成员属性和方法

示例:创建静态内部类

class Outter{
    static class Inner{
        public void print(){
            System.out.println("内部类print方法");
        }
    }
    public void func(){
        //静态内部类对象的创建不需要依赖于外部类
        Inner inner = new Inner();  
        inner.print();
    }
}
public class Demo2{
    public static void main(String[] args) {
        Outter out = new Outter();
        out.func();    //外部类对象调用静态内部类方法
    }
}

3、局部内部类(方法内部类):

方法内部类定义在外部类的方法中,方法内部类和成员内部类基本一致,只是它们的作用域不同,方法内部类只能在该方法中被使用,出了该方法就会失效。

     1) 方法内部类不允许使用访问权限修饰符, public private protected 等均不允许。

     2) 方法内部类对外完全隐藏,除了创建这个类的方法可以访问它,其他均不允许访问。

     3) 方法内部类如想要使用方法形参,该形参必须用final声明(JDK8形参变为隐式final声明)。

4、匿名内部类:

匿名内部类其实就是一个没有名字的方法内部类,所以它符合方法内部类的所有约束。另外需要注意:

     1)匿名内部类是没有访问修饰符的。
     2)匿名内部类必须继承一个抽象类或者实现一个接口
     3)匿名内部类中不能存在任何静态成员或方法
     4)匿名内部类是没有构造方法的,因为它没有类名
     5)与方法内部类相同,匿名内部类也可以引用方法形参。此形参也必须声明为 final


三、总结:

1、内部类的使用暂时不作为设计的首选,内部类具有如下特点:

     1)内部类的使用破坏了程序的结构。

     2)内部类能方便的访问外部类私有属性。(外部类也可以访问内部类的私有属性)

     3)如果发现类名称上出现了 . 符号,应当立即想到是使用了内部类的概念。

2、内部类相关问题:

      问题1:实例内部类对象能否定义static的数据成员?

                   能,使用final的数据成员,是可以在编译期间确定的值。

      问题2:实例内部类对象是否有额外的内存消耗?

                   有,实例内部类拥有外层类的this引用。

      问题3:静态内部类能否访问外部类的实例数据成员?

                   能,外部类拿到对象,传给内部类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值