黑马程序员——————> 使用内部类

------- android培训、java培训、期待与您交流! ----------

定义类的主要作用就是定义变量,创建实例和作为父类被继承。定义内部类的主要作用也是如此,但使用内部类定义变量和创建实例则与外部类存在一些小小的差异。下面分三种情况讨论内部类的用法。

1:在外部类内部类使用内部类

在外部类内部使用内部类时,与平常使用普通类没太大区别。一样可以直接通过内部类类名来定义变量,通过new调用内部类构造器来创建实例。

唯一存在的区别是:不要在外部类的静态成员(包括静态方法和静态初始化块)中使用非静态内部类,因为静态成员不能访问非静态成员。

在外部类内部定义内部类的子类与平常定义子类也没有太大区别。

 

2:在外部类以外使用非静态内部类

如果希望在外部类以外的地方访问内部类(包括静态和非静态两种),则内部类不能使用private访问控制权限,privat修饰的内部类只能在外部类内部使用,对于其他访问控制符修饰的内部类,则能在访问控制符对应凡人访问权限内使用。

(1)省略访问控制符的内部类,只能被与外部类处于同一个包中的其他类所访问。

(2)使用protrcted修饰的内部类,可被与外部类处于同一个包中凡人其他类和外部类的子类所访问。

(3)使用public修饰的内部类,可以在任何地方被访问。

在外部类以外的地方定义内部类(包括静态和非静态两种)变量的语法格式如下:

OuterClass.InnerClass varName

可以看出,在外部类以外的地方使用内部类时,内部类完整的类名应该是OuterClass.InnerClass 如果外部类有包名,则还应该增加包名前缀。

由于非静态内部类的对象必须寄生在外部类的对象里,因此创建非静态内部类对象之前,必须先创建其外部类对象。在外部类以外的地方创建非静态内部类实例的语法如下:

OuterInstance.new InnerConstructor()

可以看出,在外部类以外的地方创建非静态内部类的实例必须使用外部类实例和new来调用非静态内部类的构造器。下面程序示范了如何在外部类以外的地方创建非静态内部类的对象,并把它赋给非静态内部类类型的变量。

 1 class Out
 2 {
 3     //定义一个内部类,不使用访问控制符
 4     //即只有同一个包中的其他类可以访问该内部类
 5     class In
 6     {
 7         public In(String msg)
 8         {
 9             System.out.println(msg);
10         }
11     }
12 }
13
14 public class CreateInnerInstance
15 {
16     public static void main(String[] args)
17     {
18         Out.In in = new Out().new In("测试信息");
19
20         /**
21          *     上面的代码可以改为如下三行代码
22          *    使用OuterClass.InnerClass 的形式定义内部类变量
23          *    Out.In in;
24          *    创建外部类实例,非静态内部类实例将寄生在该实例中
25          *    Out out = new Out();
26          *    通过外部类实例和new来调用内部类构造器创建非静态内部类实例
27          *    in = out.new In("测试信息");
28          */
29     }
30 }

上面程序中创建了一个非静态内部类的对象。可以看出,非静态内部类的构造器必须使用外部类对象来调用。
如果需要在外部类以外的地方创建非静态内部类的子类,则尤其要注意上面的规则:非静态内部类的构造器必须通过其外部类对象来调用。当创建一个子类时,子类构造器总会调用父类的构造器,因此在创建非静态内部类的子类时,必须保证让子类构造器可以调用非静态内部类的构造,调用非静态内部类的构造器时,必须存在一个外部类对象。下面程序定义了一个子类继承了Out类的非静态内部类In类。

class SubClass extends Out.In
{

    public SubClass(Out out)
    {
        //通过传入的Out对象显式调用In的构造器
        out.super("hello");
    }

}

非静态内部类In类的构造器必须使用外部类对象来调用,代码中的super代表调用In类的构造器,而out则代表外部类对象。

如果要创建SubClass对象时,必须先创建一个Out对象。这是合理的,因为SubClass是非静态内部类In类的子类,非静态内部类In对象里必须有一个对Out对象的引用,其子类SubClass对象里也应该持有对Out对象的引用。当创建SubClass对象时传给该构造器的Out对象,就是SubClass对象里Out对象引用所指向的对象。

非静态内部类In对象和SubClass对象都必须持有指向Out对象的引用,区别是创建两种对象时传入Out对象的方式不同:当创建非静态内部类In对象时,必须通过Out对象来调用new关键字;当创建SubClass类的对象时,必须使用Out对象作为调用者来调用In构造器。

非静态内部类的子类不一定是内部类,它可以是一个外部类。但非静态内部类的子类实例一样需要保留一个引用,该引用指向其父类所在外部类的对象。也就是说,如果有一个内部类子类的对象存在,则一定存在与之对应的外部类对象。

 

在外部类以外使用静态内部类

因为静态内部类是外部类类相关的,因此创建静态内部类对象时无须创建外部类对象。在外部类以外的地方创建静态内部类实例的语法如下:

new OuterClass.InnerConstructor()

下面程序示范了如何在外部类以外的地方创建静态内部类的实例。

 1 class StaticOut
 2 {
 3     //定义一个静态内部类,不使用访问控制符
 4     //即同一个包中的其他类可访问该内部类
 5     static class StaticIn
 6     {
 7         public StaticIn()
 8         {
 9             System.out.println("静态内部类的构造器");
10         }
11     }
12 }
13
14 public class CreateStaticInnerInstance
15 {
16
17     public static void main(String[] args)
18     {
19         StaticOut.StaticIn in = new StaticOut.StaticIn();
20
21         /**
22          *     上面的代码可该为如下两行代码
23          *    使用OuterClass.InnerClass的形式定义内部类变量
24          *    StaticOut.StaticIn in;
25          *    通过new来调用内部类构造器创建静态内部类实例
26          *    in = new StaticOut.StaticIn();
27          */
28     }
29
30 }

可以看出,不管是静态内部类还是非静态内部类,它们声明变量的语法完全一样。区别知识在创建内部类对象时,静态内部类只需要使用外部类即可调用构造器,而非静态内部类必须使用外部类对象来调用构造器。

因为调用静态内部类的构造器时无须使用外部类对象,所以创建静态内部类的子类也比较简单。

class StaticSubClass extends StaticOut.StaticIn{}

当定义一个静态内部类时,其外部类非常像一个包空间。

相比之下,使用静态内部类比使用非静态内部类要简单很多,只要把外部类当成静态内部类的包空间即可。因此当需要使用内部类时,应该优先考虑静态内部类。

时间: 2024-12-18 18:56:54

黑马程序员——————> 使用内部类的相关文章

黑马程序员——————> 局部内部类&匿名内部类

------- android培训.java培训.期待与您交流! ---------- 如果把一个内部类放在方法里定义,则这个内部类就是一个局部内部类,局部内部类仅在该方法里有效.由于局部内部类不能在外部类的方法以外的地方使用,因此局部内部类也不能使用访问控制符和static修饰符修饰. 对于局部成员而言,不管是局部变量还是局部内部类,它们的上一级程序单元都是方法,而不是类,使用static修饰它们没有任何意义.因此,所有的局部成员都不能使用static修饰.不仅如此,因为局部成员的作用域是所在

黑马程序员——面向对象--内部类

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 内部类: 内部类的访问规则: 1.内部类可以直接访问外部类中的成员,包括私有 之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式: 外部类名.this 2.外部类要访问内部类,必须建立内部类对象. class outer{ int num = 5; class inner{ System.out.println("num="+num);//可以直接调用外部成

黑马程序员_内部类与匿名内部类

??内部类分为普通内部类(有名)和匿名内部类.普通内部类分为成员内部类.局部内部类.静态内部类(嵌套内部类).顾名思义,内部类就是定义在一个类内部的类.什么时候都会使用内部类呢?当我们定义一个类,发现内部还有类时,比如我们定义人体body时,内部还有心.肝.皮.肺.肾,他们既属于body,又是一个独立的器官,这是为了更加方便的描述人体就会选择内部类来实现. 普通类 1.定义 讲一个类定义在另一个类的里面,对里面那个类就叫做内部类,或者嵌套类. 2.成员内部类 ????2.1形式: ???????

黑马程序员——java基础——内部类

 黑马程序员--java基础--内部类 ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 内部类 如果A类需要直接访问B类中的成员,而B类又需要建立A类的对象.这时,为了方便设计和访问,直接将A类定义在B类中.就可以了.A类就称为内部类.内部类可以直接访问外部类中的成员.而外部类想要访问内部类,必须要建立内部类的对象. 内部类的访问规则 1,内部类可以直接访问外部类中的成员,包括私有. 之所以可以直接访问外部类中的成员,是因为内部类中持有

黑马程序员 内部类 Java

内部类:将一个类定义在另一个类里面,对里面那个类就叫做内部类(内置类,嵌套类). 访问特点:内部类可以直接访问外部类中的成员,包括私有成员.而外部类要访问内部类中的成员必须要建立内部类的对象. class Outer{ private int  x=3; class Inner{ void function(){ function1(); System.out.println("内部类"+x); } } void function1(){ System.out.println(&quo

黑马程序员-内部类、 抽象类、接口

java面向对象中比较重要的知识还有内部类,抽象类.接口,这些和封装.继承.多态一起赋予java强大的面向对象的能力 1.抽象类 在面向对象的领域一切都是对象,同时所有的对象都是通过类来描述的,但是并不是所有的类都是来描述对象的.如果一个类没有足够的信息来描述一个具体的对象,而需要其他具体的类来支撑它,那么这样的类我们称它为抽象类. 创建抽象类和抽象方法非常有用,因为他们可以使类的抽象性明确起来,并告诉用户和编译器打算怎样使用他们.抽象类还是有用的重构器,因为它们使我们可以很容易地将公共方法沿着

黑马程序员_Java抽象类和内部类

- - - - - android培训.java培训.期待与您交流! - - - - - - 类(class) 类是相似对象中共同属性和方法的集合体 在面向对象中定义类,就是在描述事物,就是在定义属性(变量)和行为(方法).属性和行为共同成为类中的成员(成员变量和成员方法). 封装.继承和多态 面向对象方法中软件设计的主体是类,类是相同属性和方法的封装体,因此类具有封装性 子类可以在继承父类所有属性和方法的基础上,再增加自己特有的属性和方法,因此类具有继承性 在一个类层次中,定义为根类的对象可被

黑马程序员_关于黑马java班入学测试技术分享-后五(二)

??????????????????????????????????????????????????????????????????????????-----Java培训.Android培训.iOS培训..Net培训.期待与您交流! 作为本人首篇黑马技术博客有必要交代一下背景.个人理解博客的用作在于于己在于交流,于他在于学习,在交流学习中共同成长.下面进入正题.本文主要是介绍在做黑马入门测试时的一些问题(这个应该不是泄露题库吧). 本文只要是讲述黑马程序员基础测试题的6-10题,回过头来分析明显

黑马程序员_JAVA 基础加强学习笔记

一.面向对象 (一)继承  1.继承的好处: (1) 提高了代码的复用性. (2) 让类与类之间产生了关系,提供了另一个特征多态的前提. 注意: 子类中所有的构造函数都会默认访问父类中的空参数的构造函数,因为每一个子类构造内第一行都有默认的语句super();  如果父类中没有空参数的构造函数,那么子类的构造函数内,必须通过super语句指定要访问的父类中的构造函数. 如果子类构造函数中用this来指定调用子类自己的构造函数,那么被调用的构造函数也一样会访问父类中的构造函数. 2.final特点