内部类能覆盖吗?内部类解决了什么问题?

180

在Java 1.1 中,可将一个类定义置入另一个类定义中。这就叫作“内部类”。内部类对我们非常有用,因为利用它可对那些逻辑上相互联系的类进行分组,并可控制一个类在另一个类里的“可见性”。然而,我们必须认识到内部类与以前讲述的“合成”方法存在着根本的区别。
通常,对内部类的需要并不是特别明显的,至少不会立即感觉到自己需要使用内部类。在本章的末尾,介绍完内部类的所有语法之后,大家会发现一个特别的例子。通过它应该可以清晰地认识到内部类的好处。
创建内部类的过程是平淡无奇的:将类定义置入一个用于封装它的类内部(若执行这个程序遇到麻烦,请参见第3 章的3.1.2 小节“赋值”):

public class Parcel1 {
    class Contents {
        private int i = 11;
        public int value() { return i; }
    }
    class Destination {
        private String label;
        Destination(String whereTo) {
            label = whereTo;
        }
        String readLabel() { return label; }
    }
    // Using inner classes looks just like
    // using any other class, within Parcel1:
    public void ship(String dest) {
        Contents c = new Contents();
        Destination d = new Destination(dest);
    }
    public static void main(String[] args) {
        Parcel1 p = new Parcel1();
        p.ship("Tanzania");
    }
} ///:~

当我们写代码时,有时候我们会想要把一些东西放在另外一些东西里面。就像你把玩具放进玩具箱里一样。在这个例子里,我们有一个叫做“Parcel1”的盒子,而盒子里面有两个小盒子,一个叫做“Contents”(内容),另一个叫做“Destination”(目的地)。

“Contents”盒子里装着一个数字。我们可以通过这个盒子里的一个特殊的门来看到这个数字是什么。

“Destination”盒子里装着一个标签,标签告诉我们这个盒子要送到哪里去。我们可以通过这个盒子里的一个特殊的门来看到标签上写了什么。

在我们的盒子里有一个特别的方法叫做“ship”(发货)。当我们想要把盒子送出去的时候,我们就会打开“Contents”盒子和“Destination”盒子,然后把它们准备好,最后将盒子寄出去。

在我们的故事结束时,我们创造了一个Parcel1盒子,并告诉它要送到坦桑尼亚。 Parcel1盒子就打开了“ship”门,把货物送出去了。

总之,这个故事告诉我们,内部类就像是一个盒子里的盒子,它们帮助我们把一些东西组织得井井有条,方便我们使用。

若在ship()内部使用,内部类的使用看起来和其他任何类都没什么分别。在这里,唯一明显的区别就是它的名字嵌套在 Parcel1 里面。但大家不久就会知道,这其实并非唯一的区别。
更典型的一种情况是,一个外部类拥有一个特殊的方法,它会返回指向一个内部类的句柄。就象下面这样:

public class Parcel2 {
 class Contents {
 private int i = 11;
 public int value() { return i; }
 }
 class Destination {
 private String label;
 Destination(String whereTo) {
 label = whereTo;
 }
 String readLabel() { return label; }
 }
 public Destination to(String s) {
 return new Destination(s);
 }
 public Contents cont() { 
 return new Contents(); 
 }
 public void ship(String dest) {
 Contents c = cont();
 Destination d = to(dest);
 } 
 public static void main(String[] args) {
 Parcel2 p = new Parcel2();
 p.ship("Tanzania");
 Parcel2 q = new Parcel2();
 // Defining handles to inner classes:
 Parcel2.Contents c = q.cont();
 Parcel2.Destination d = q.to("Borneo");
 }
} ///:~

若想在除外部类非 static 方法内部之外的任何地方生成内部类的一个对象,必须将那个对象的类型设为“外部类名.内部类名”,就象 main()中展示的那样。

将内部类的对象类型设为“外部类名.内部类名”有几个好处:

1. **明确性和可读性:** 通过使用外部类名作为限定符,明确指出了内部类是外部类的一部分,这样在代码中就能清晰地看到它们之间的关系。

2. **避免命名冲突:** 如果在外部类和内部类中都定义了同名的类,使用外部类名作为限定符可以避免命名冲突。这样做可以确保代码的可维护性和可扩展性。

3. **代码组织和结构清晰:** 使用外部类名作为限定符可以使代码的组织结构更加清晰。当其他开发者阅读代码时,可以更容易地理解内部类是属于外部类的,而不是独立存在的。

4. **提高代码的可维护性:** 如果需要对内部类进行修改或者重构,使用外部类名作为限定符可以减少对其他部分代码的影响。这样做有助于降低代码的耦合度,提高代码的可维护性。

总之,将内部类的对象类型设为“外部类名.内部类名”可以增强代码的清晰度、可读性和可维护性,避免命名冲突,并有助于更好地组织和结构化代码。

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值