美文网首页
Think in Java 第十章(内部类)

Think in Java 第十章(内部类)

作者: 咱就一山里人 | 来源:发表于2018-10-28 12:44 被阅读0次
信仰

一个类的定义放在另一个定义内部,这就是内部类。

10.1 创建内部类
public class Parcel1{
 class Contents{
     private int i = 11;
     public int value (){ return i; }
 }
 class Destination {
     private String able;
     Destinaltion(String whereTo){
     label = whereTo;
  } 
     String readLabel (){ return label;} 
}
 public void ship(String dest){
     Contents c = new Contents();
     Destination d = new  Destination(dest);
     System.out.println(d.readLabel);
}
  public static void main(String[] args){
    Parcel1 p = new Parcel1();
    p.ship("Tasmainaaaaa");
 }
}

10.2 链接到外部类

内部类是一种名字隐藏和组织代码的模式,当生成内部类对象时,此对象可以用访问外围对象的所有成员


10.3 使用 .this与。new

对外部类的引用:外部类的名字紧跟this.
创建内部类对象:使用 .new语法


10.4 内部类与向上转型

内部类向上转型为基类或一个接口,所得到的是指向基类或接口的引用,隐藏实现细节

public interface Destination{
  String readLabel();
}
public interface Contents{
   int value();
}
//(接口的所有成员自动被设置成public)
class Parcel4{
    private class Pcontents implements Contenets {
      private int i =1;
      public int value(){return i;}
   }
   protected class PDestination implements Destination{
      private String label;
      private PDestination(String whereTo){ label = whereTo;}
      public String readLabel(){return label;}
   }
   public Destination destination(String s){
       return new PDestinations(s);
   }
   public Contents contents(){
       return new PContents();
  }
}
public class TestPracel{
   public static void main(String[] args){
      Pracel4 p = new Parcel4();
      Contents c = p.contents();
      Destriation d =  p.destination("tasmainaaa");
 }

内部类PContents是privae,只有Parcel4 可以访问, PDesination是protected只有Parcel4及子类可以访问
private内部类可以阻止任何依赖型的代码,隐藏实现细节。


10.5 在方法和作用域内的内部类

可以在方法或在作用域定义内部类。
理由

  • 1 实现某种类型的接口,可以创建并返回对其引用。
  • 2 创建一个类来辅助解决方案,但不希望这个类时公用的。

内部类的实现。

  • 1> 定义在方法中的内部类
  • 2>定义在作用域内的类,作用域的方法在内部
  • 3>一个实现接口的匿名类
  • 4>一个匿名类,它扩展了默认构造器的类
  • 5>一个匿名类,它执行字段初始化
  • 6>一个匿名类,它通过实例初始化实现构造(匿名类不可能有构造器)

10.6 匿名内部类
public class Parcel7{
   public Contents contents(){
       return new Contents(){
           private int i =11;
           public int value(){return i;}
     };
   }
    public static void main(String[] args){
     Parcel7 p = new Parcel7();
     Contents c = p.contents();
  }
}

匿名内部类末尾的分号,并不是用来标记内部类的结束,标记的是表达式的结束,这个表达式包含了匿名内部类。

匿名内部类使用外部对象(不包含基类使用)参数引用需要final修饰。
匿名内部类实例初始化的效果就是构造器,但受到了限制(不能重载实例初始化方法,匿名内部类可以扩展类,也可以实现接口,但不能两者兼备,如果是实现接口也只能实现一个接口)

  • 10.6.1 再访工厂方法
interface Service{
    void method1();
    void method2();
}
interface ServiceFactory{
     Service getService();
}
class Implementation1 implement Service{
      private Implementation1(){}
      public method1(){ print("Implementation1 method1")}
      public method2(){ print("Implementation1 method2")}
}
  public static ServiceFactory factory = 
       new ServiceFactory(){
           public Service getService(){
             return new Implementation1 (); 
  };
}
class Implementation2 implement Service{
      private Implementation2(){}
      public method1(){ print("Implementation2 method1")}
      public method2(){ print("Implementation2 method2")}
}
  public static ServiceFactory factory = 
      new ServiceFactory(){
          public Service getService(){
           return new Implementation2 (); 
  };
}
 public class Factories{
   public static void ServiceConsumer(ServiceFactory factory){
        Service s = factory.getService();
        s.method1();
        s.method2();
   }
   public static void main(String[] args){
        ServiceConsumer(Implementation1.factory);
        ServiceConsumer(Implementation2.factory);
   }
 }

由上构造器都可以是private,并没有创建工厂的类具名

优先使用类而不是接口。如果你的设计需要接口,你必须了解它。否则,不到迫不得已,不需要将它放到你的设计中


10.7 嵌套类

如果不需要内部类对象与外围类有联系,可以将内部类对象声明为static,这就是嵌套类。
普通内部类对象隐式保存了一个引用,指向创建它的外围类对象,而内部类是static时,嵌套类就意味着

  • 1 要创建嵌套类的对象,并不需要外围类对象。
  • 2 不能从嵌套类对象中访问费静态的外围类对象
    (注意普通类内部不能有static数据和static字段,也不能包含嵌套类,但嵌套类可以包含这些东西)

10.8 为什么需要内部类

Sun公司为什么会增加这个语言特性,一般来说,内部类继承某个类或实现某个接口,内部类的代码操作创建它的外围类的对象,内部类提供了某种进入外围类的窗口。

  • 1) 如果只是需要一个接口的引用,为什么不通过外围类实现那个接口
    答案是:“如果这能满足需求,那么就应该这样做”
  • 2) 内部类实现一个接口与外围类实现这个接口有什么区别
    答案是:后者不是总能享用到接口带来的方便,有时需要用到接口的实现,所以使用最吸引人的原因是:
    每个内部类都能独立继承一个接口的实现,所以无论外围类是否已经继承了某个接口的实现,对于内部类都没有影响

也就是说内部类允许继承多个非接口类型

内部类可以获得其他一些特性

  • 1)内部类可以有多个实例,每个实例都有自己的状态信息,并且与外围类的对象信息相互独立。

  • 2)在单个外围类中,可以让内部类以不同的方式实现同一个接口,或继承同一个类。

  • 3)创建内部类对象不依赖外围类对象的创建。

  • 4)内部类没有“is-a”关系,他就是一个独立的类

  • 10.8.1 闭包与回调
    通过内部类提供的闭包功能是优良的解决方案,它比指针更灵活,更安全。


10.9 内部类的继承

内部类的构造器不需连接到指向外围类对象的引用,所以在继承内部类的时候,事情会变得有点复杂,问题在于,那个指向外围类的对象的“秘密的”引用必须被初始化,而在导出类中不再存在可连接的默认对象。要解决这个问题,必须使用特殊的语法说明它们之间的关联。

class WithInner{
  class Inner{}
}
public class InheritInner extends WithInner.Inner{
InheritInner(WithInner wi){}
   wi.super();
}
public static void main(String[] args){
   WithInner wi = new WitnInner();
   InherItInner ii = new InheritInner(wi);
  }
}

10.10 内部类可以被覆盖吗

覆盖内部类就好像是它的一个方法,其实并不起什么作用


10.11 局部内部类

可以访问当前代码块内的常量,以及此外围类所有成员。
匿名内部类和局部内部类创建的比较

interface Counter{
  int next();
}
public class LocalInnerClass{
    private int count = 0;
    Counter getCounter(final String name){
       class LocalCounter implements Counter{
           public LocalCounter(){}
           public int next(){ 
           return   count++;              
      }
    }
  }

Counter getCounter2(final String name){
   return new Counter(){
           public int next(){
             return count++; 
         }
     };
  }
}

当需要一个已命名的构造器,或者需要重载构造器,使用局部内部类,匿名内部类只能用于实例初始化。
当需要不止一个内部类对象时,使用局部内部类。


10.12 内部类标识符

每个类都会产生一个.class文件,其中包含了如何创建该类型的全部信息(此信息产生一个“meta-class”,叫Class对象)内部类必须生成一个.class文件以包含它们的Class对象信息。这些文件的命名有严格的规定:外围类的名字,加上“$”再加上内部类的名字

相关文章

  • Think in Java 第十章(内部类)

    一个类的定义放在另一个定义内部,这就是内部类。 10.1 创建内部类 10.2 链接到外部类 内部类是一种名字隐藏...

  • 那为何要使用匿名内部类

    那为何要使用匿名内部类 Think in java上说:使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(...

  • java基础系列之内部类<三>

    接口中也可以有内部类声明, 我所知道,java 接口中不能有常量意外的声明出现. 但是从think in java...

  • Java 中的方法内部类

    Java 中的方法内部类 方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内...

  • PHP转JAVA的记录

    Java 数组 内部类 内部类的创建:内部类可以对包内其他类隐藏想实现一个接口时, 不想新建类文件 内部类可以访问...

  • Java内部类

    Java内部类,简单来说就是将一个类定义在另一个类或者方法里面,主要分为成员内部类,局部内部类,匿名内部类和静态内...

  • 非静态内部类中能不能拥有静态方法或属性?

    最近在重读 《Think in Java》的时候,发现了下面这段话: 普通内部类的字段和方法,只能放在类的外部层次...

  • 【闭包】你真的理解闭包和lambda表达式吗

    [toc] 1. 前言 在阅读Think in java时,关于内部类的作用中出现了闭包这个词。于是开始百度,了解...

  • Java内部类

    Java内部类 大纲: java内部类有什么特点?为什么需要内部类? 非静态内部类持有外部类的引用 内部类的分类。...

  • 内部类

    内部类可以分为:非静态内部类;静态内部类;匿名内部类。 一、内部类 首先要说,Java为什么要使用内部类?java...

网友评论

      本文标题:Think in Java 第十章(内部类)

      本文链接:https://www.haomeiwen.com/subject/ubuwzftx.html