java编程思想第四版第十章总结

前端之家收集整理的这篇文章主要介绍了java编程思想第四版第十章总结前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

1. 内部类的特性

  • 他允许你把一些逻辑相关的类组织在一起。

2. 使用.this

  • 如果你需要在内部类中堆外部类进行应用,可以使用外部类的名字后面加.this。下面展示了如何使用 .this
    package net.mindview.innerclasses;
    
    public class DotThis {
        void f(){
            System.out.println("DotThis.f()");
        }
        
         Inner {
            public DotThis outer() {
                System.out.println(DotThis.this);
                return DotThis.;
            }
        }
        
         Inner inner(){
            return new Inner();
        }
        
        static  main(String[] args) {
            DotThis dt =  DotThis();
            DotThis.Inner di = dt.inner();
            di.outer().f();
        }
    
    }

     

 3.使用.new

  • 如果想要创建某个外部类的内部类,可以使用外部类对象.new 内部类:
  • 如果想new一个内部类,不能使用外部类.new 内部类。必须使用外部类的对象来创建内部类的对象。    用法如下:
     DotNew {
        
         Inner {
            
        }
         main(String[] args) {
            DotNew dn =  DotNew();
            DotNew.Inner di = dn. Inner();
        }
    }

     

4. 方法的内部类

  • 这里只说两点:
    • 方法的内部类有效作用域是在方法内,方法外部可以调用
    • 方法的内部类,并不是说方法调用的时候才创建了,实际上,这个类和其他类没有什么不同,他们在使用之前,已经经过编译了.
      /**
       * 方法内部类的作用域就在方法内,方法外不可以访问.
       * @author samsung
       *
       */
       Parcel5 {
           Destination destination(String s){
              //方法里定义了一个内部类
               PDestination implements Destination{
                  private String label;
                   PDestination(String label){
                      System.out.println();
                      this.label = label;
                  }
                  @Override
                   String readLabel() {
                      return label;
                  }
              }
              
               PDestination(s);
          }
           main(String[] args) {
              Parcel5 p =  Parcel5();
              System.out.println(p.destination(上海).readLabel());
              System.北京).readLabel());
          }
      
          *
           * 注意:PDestination定义在方法里面,并不是说只有调用方法的时候,这个类才被创建.
           * 实际上,这个类和其他类一样,已经经过编译了.
           */
      }

       

5. 定义在作用域内的内部类,此作用域在方法的内部.

  • 定义在方法作用域内部的类,只在作用域内部有效
 Parcel6 {
    private  internalTracking(boolean b){
        if(b){
             TrackingSlip{
                 String id;
                TrackingSlip(String s){
                    id = s;
                } 
                
                String getSlip(){
                     id;
                }
            }
            
            TrackingSlip ts = new TrackingSlip(100);
            String s = ts.getSlip();
        }
        作用域外不可使用
        TrackingSlip ts = new TrackingSlip("100");
    }
    
     track(){
        internalTracking(true main(String[] args) {
        Parcel6 p =  Parcel6();
        p.track();
    }
}

 

6.匿名内部类

  • 默认构造器匿名内部类
     Parcel7 {
         Contents contents(){
            定义了一个匿名内部类.将返回值和创建类放在了一起
             Contents(){
                int i = 11;
                @Override
                int value() {
                     i;
                }
            };
        }
         main(String[] args) {
            Parcel7 p =  Parcel7();
            Contents c = p.contents();
            System.out.println(c.value());
    
        }
    
    }

     

  • 代参数构造器的匿名内部类
     Wrapping {
        
         i;
        public Wrapping( x){
            this.i = x;
        }
         value(){
             i;
        }
    }
     Parcel8 {
        public Wrapping wrapping( Wrapping(x){
                @Override
                 value(){
                    return super.value()*47;
                }
            };
        }
        
         main(String[] args) {
            Parcel8 p =  Parcel8();
            Wrapping w = p.wrapping(20);
            System..println(w.value());
        }
    
    }

    这里需要注意的是,虽然Wrapping是一个导出类,却依然被当成了一个接口来使用.

  • 匿名内部类中使用外部对象,这外部的这个对象必须是final的
     Parcel9 {
         Destination destination(final String x){
            final String m = null;
            匿名内部类
             Destination(){
                在内部类中使用到了外部的对象
                private String label = m;
                private String abc = x;
                @Override
                 label;
                }
            };
        }
         main(String[] args) {
            Parcel9 p =  Parcel9();
            System.20).readLabel());
        }
        
        *
         * 定义一个匿名内部类,如果希望在匿名内部类中使用外部的对象,* 那么编译器要求外部类的这个参数必须是final的. 如果你没有将这个类定义为final
         * 编译器会报错
         
    
    }

     

  • 在匿名内部类中使用类似构造器的行为. 我们知道匿名内部类没有类名,因此他不可能有命名构造器. 但通过实例初始化可,就鞥够达到为匿名内部类创建一个构造器的效果
    abstract  Base{
        public Base( i){
            System.Base构造器,i=" + i);
        }
        
         f();
    }
     AnonymousConstructor {
        *
         * 此处的i不要求是final的,因为这个i只是传递给了匿名
         * 变量的构造器,并没有在匿名内部类内部使用.
         */
        static Base getBase( i){
             Base(i){
                {
                    System.这里可以类似构造器进行初始化);
                }
                @Override
                 f() {
                    System.匿名函数f());
                }
                
            };
        }
         main(String[] args) {
            AnonymousConstructor amc =  AnonymousConstructor();
            amc.getBase(100).f();
        }
    
    }

     

 7. 再谈工厂设计模式.

  再上一章中说了工厂设计模式. 本书中的案例是对象工厂设计模式. 来看看是怎么写的

package net.mindview.innerclasses.factory.MethodFactory;
*
 * 服务类
 interface Service{
     method1();
     method2();
}

*
 * 工厂类
  ServiceFactory {
    Service getService();
}

 Implementation1 implements Service{

    @Override
     method1() {
        System.Implementation1 method1);
    }

    @Override
     method2() {
        System.);
    }
    
}

 Implementation2 implements Service{

    @Override
    Implementation2 method1 ImplementationFactory1 implements ServiceFactory{
    @Override
     Service getService() {
         TODO Auto-generated method stub
         Implementation1();
    }
}

 ImplementationFactory2 implements ServiceFactory{
    @Override
     Implementation2();
    }
}

 Factories {
     serviceSustomer(ServiceFactory factory){
        factory.getService().method1();
        factory.getService().method2();
    }
     main(String[] args) {
        serviceSustomer( ImplementationFactory1());
        serviceSustomer( ImplementationFactory2());
    }

}

  我们还可以将这种方式以内部类的方式来实现

package net.mindview.innerclasses.factory.methodFactoryInnerClass;
*
 * 每一种服务,提供一种工厂. 这种工厂专门创建这种服务.
  Implementation1 implements Service{
     Implementation1(){}
    @Override
    让工厂在内部实现
    static ServiceFactory factory =  ServiceFactory(){
        @Override
         Service getService() {
             Implementation1();
        }
        
    };
    
}

);
    }

     Implementation2();
        }
        
    };
    
}

 main(String[] args) {
        serviceSustomer(Implementation1.factory);
        serviceSustomer(Implementation2.factory);
    }
}

 

  我的理解是: 第一种工厂的含义是: 我现在需要一种服务,然后我找到对应的工厂,为我提供服务. 工厂再去找对应这种服务的实体.

  而第二种方式呢,我现在需要服务. 直接就去找这种服务对应的工厂就可以了. 也就是工厂内置了. 就像大公司下有多个子公司,每个子公司都有自己的工厂.我要那种类型的东西,他就自己给生产了

8. 嵌套类

  如果内部类对象预期外围类对象之间不需要有联系,那么可以将内部类声明为static的。这种累通常称为嵌套类。要想理解static定义的内部类的含义,就必须记住,普通的内部类对象隐式地保存了一个引用,指向创建他的外围类对象。然而,当内部类是static的时候, 就不是这样了。嵌套类意味着:

  1. 要创建嵌套类的对象, 并不需要外围类的对象。
  2. 不能从嵌套类的对象中访问非静态的对象
  3. 普通的内部类不能有static数据和static字段,也不能包含嵌套类,但是嵌套类可以有这些东西
     Parcel11 {
        ParcelContent被定义为static的,所以是一个嵌套类
         ParcelContent implements Contents {
            ;
            @Override
             value() {
                 i;
            }
        }
        
        ParcelDestination 是一个嵌套类. 被定义为static的.所以,它内部可以的有static的成员和方法
         ParcelDestination implements Destination {
             String label;
             ParcelDestination(String label){
                 label;
            }
            @Override
             String readLabel() {
                 label;
            }
            
             f(){
                System..println(AnotherLabel.x);
                b()方法是访问不到的
                AnotherLabel.b();
            }
            int x = 10他是嵌套在嵌套类内部的嵌套类.
             AnotherLabel{
                内部定义了两个和外部一样的成员方法,竟然不冲突
                 f(){
                    System.这时静态类的静态方法);
                }
                ;
                嵌套类中的非静态方法不能被外部访问到. 所以这个方法没有任何意义
                 b(){
                    System.这时静态类中的静态方法b());
                }
            }
        }
        
        static Contents getContents(){
             ParcelContent();
        }
        
         Destination getDestination(String s){
             ParcelDestination(s);
        }
        
         main(String[] args) {
            System..println(getContents().value());
            System.out.println(getDestination().readLabel());
            
            嵌套类中,不能访问非静态方法
            ParcelDestination.readLabel();
            但是可以方法静态方法
            ParcelDestination.f();
            
            嵌套类的使用方式是,类似于静态方法. 将其作为静态方法来使用.
            ParcelDestination.AnotherLabel.x=1;
            System..println(ParcelDestination.AnotherLabel.x);
            
            ParcelDestination.AnotherLabel.f();
            下面这样写是不对的
            ParcelDestination.AnotherLabel.b();
        }
    
    }

    观看上面说的文字,会有些难以理解,所以, 将这段代码敲一遍,就理解什么意思了。动手很重要啊

9. 接口内部的类

  • 首先,接口里不能放置任何代码,但是嵌套类可以.
  • 你放到接口中的任何类都自动式public static的.
  • 你可以在内部类中实现外围类的接口. 示例如下:
    package net.mindview.innerclasses;
    *
     * 定义在接口内部的类
      ClassInInterface {
         howdy();
        这里static必须是显示标记出来的,否则这个类将不能运行
         Test implements ClassInInterface {
    
            @Override
             howdy() {
                System.Howdy!);
            }
    
             main(String[] args) {
                Test t =  Test();
                t.howdy();
            }
        }
    }

    注意,如果想运行main方法,这里的嵌套类必须是static的.

 

  • 如果想创建某些公共代码,使得他们可以被某个接口的所有实现类所共用,那么使用接口内部的嵌套类会显得很方便.
  • 例如: 我们可以在每个类中写一个mian方法用来测试这个类,这样做有一个缺点,那就是要写好多遍,而且,必须通过编译器的编译,我们可以使用嵌套类改善
     TestBed {
        f() Testers{
             main(String[] args) {
                TestBed t =  TestBedTest();
                t.f();
            }
        }
    }

    再说的白话一点,就是在接口中定义一个这样的嵌套类. 然后定义mian方法,在main方法中使用嵌套类. 当有一个新的对象继承了这个类的时候,就在这个类中的main方法进行测试就好了. 这样的好处是,当我打包发布到正式环境的时候,我想删除所有的main方法,因为他们的存在也会被编译器编译,降低效率. 如果只有一个接口的嵌套类中定义的main方法,那么删起来就方便很多了。不明白的话,在看下面这个例子,就懂了

     main(String[] args) {
                测试第一个实现了接口的类
                ClassInInterface t =  Test();
                t.howdy();
                测试第二个实现了接口的类
                ClassInInterface t1 =  ClassInInterfaceTest();
                t1.howdy();
            }
        }
    }
     ClassInInterfaceTest implements ClassInInterface{
    
        @Override
         howdy() {
            System.hhhh);
        }
    }

     

  • 接口中嵌套类如何创建实例化对象。 参考习题20
    package net.mindview.innerclasses.test20;
     InnerInInterface{
         Inner{
             Inner(){
                System.嵌套类构造方法);
            }
        }
    }
    
     Test20 {
         main(String[] args) {
            直接使用  new 外围类.嵌套类
            InnerInInterface.Inner inner =  InnerInInterface.Inner();
        }
    }

     

10. 从多层嵌套类中访问外部类的成员

  注意下面这个例子是如何创建内部类的。

*
 * 多层嵌套类访问外部成员
 */

 A{
     f(){};
     B{
         b(){};
         C {
             c(){
                f();
                b();
            };
        }
    }
}
 MutliNestingAccess {

     main(String[] args) {
        A a =  A();
        A.B b = a. B();
        A.B.C c = b. C();
        c.c();
    }

}

iooo

 

猜你在找的Java相关文章