zoukankan      html  css  js  c++  java
  • java内部类总结

    内部类是指在一个外部类的内部再定义一个类。
    内部类作为外部类的一个成员,并且依附于外部类而存在的。
    内部类可为静态,可用protected和private修饰。(而外部类不可以:外部类只能使用public和默认的)。

    内部类分为:成员内部类、局部内部类、静态内部类、匿名内部类

    几种内部类的共性:
    A、内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的.class文件,但是前面冠以外部类的类命和$符号,比如Outer.class和Outer$Inner.class
    B、内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的。

    成员内部类:

    成员内部类:形式如下

        class Outer {
            class Inner{}
        }   

     编译上述代码会产生两个文件:Outer.class和Outer$Inner.class。
    成员内部类内不允许有任何静态声明!下面代码不能通过编译。
      

      class Inner{
            static int a = 10;
        } 

    能够访问成员内部类的唯一途径就是通过外部类的对象!

    下面看一个成员内部类的例子:

    public interface Contents {
    	int value();
    }
    public interface Destination {
    	String readLabel();
    }
    public class Goods {
    	private class Content implements Contents {
    		private int i = 11;
    		public int value() {
    			return i;
    		}
    	}
    	protected class GDestination implements Destination {
    		private String label;
    		private GDestination(String whereTo) {
    			label = whereTo;
    		}
    		public String readLabel() {
    			return label;
    		}
    	}
    	public Destination dest(String s) {
    		return new GDestination(s);
    	}
    	public Contents cont() {
    		return new Content();
    	}
    }
    class TestGoods {
    	public static void main(String[] args) {
    		Goods p = new Goods();
    		Contents c = p.cont();
    		Destination d = p.dest("Beijing");
    	}
    }
    

      

    内部类的第一个好处就体现出来了 隐藏你不想让别人知道的操作,也即封装性。
    同时,我们也发现了在外部类作用范围之外得到内部类对象的第一个方法,那就是利用其外部类的方法创建并返回。上例中的cont()和dest()方法就是这么做的。那么还有没有别的方法呢?当然有,其语法格式如下:

    outerObject=new outerClass(Constructor Parameters);
    outerClass.innerClass innerObject=outerObject.new InnerClass(Constructor Parameters);

    注意在创建非静态内部类对象时,一定要先创建起相应的外部类对象。至于原因: 非静态内部类对象有着指向其外部类对象的引用。

    内部类的this引用:普通的类可以用this引用当前的对象,内部类也是如此。但是假若内部类想引用外部类当前的对象呢?用“外部类名”.this;的形式,如下例的Outer.this:

        class Outer {
            class Inner{
                public void seeOuter(){
                    System.out.println(this);
                    System.out.println(Outer.this);
                }
            }
        }

    对于普通的类,可用的修饰符有final、abstract、strictfp、public和默认的包访问。
    但是成员内部类更像一个成员变量和方法,他可用的修饰符有:final、abstract、public、private、protected、strictfp和static。
    不过一旦用static修饰内部类,它就变成静态内部类了。 

    静态内部类

    和非静态内部类相比,区别就在于静态内部类没有了指向外部的引用。除此之外,在任何非静态内部类中,都不能有静态数据,静态方法或者又一个静态内部类(内部类的嵌套可以不止一层)。不过静态内部类中却可以拥有这一切。这也算是两者的第二个区别吧。
    public class StaticInnerClassDemo {
    	protected int protected_k = 2;
    	public int public_n = 3;
    	public static int public_static_j;
    	
    	static class InnerClass{
    		void innerDisplay(){
    			//只能访问外部类的静态变量和静态方法
    			System.out.println(public_static_j);
    		}
    	}
    	public static void main(String[] args) {
    		new StaticInnerClassDemo();
    		InnerClass inner=new InnerClass();
    		inner.innerDisplay();
    	}
    }
    

    局部内部类

    Java内部类也可以是局部的,它可以定义在一个方法甚至一个代码块之内。

    public class PartInnerClassDemo {
    	private int private_m = 1;
    	protected int protected_k = 2;
    	public int public_n = 3;
    
    	public void function() {
    		final int num = 0;
    		class InnerClass {
    			public void innerDisplay() {
    				System.out.println(private_m);
    				System.out.println(protected_k);
    				System.out.println(public_n);
    				// 此处的num必须是final
    				System.out.println(num);
    			}
    		}
    		new InnerClass().innerDisplay();
    	}
    
    	public static void main(String[] args) {
    		PartInnerClassDemo outer = new PartInnerClassDemo();
    		outer.function();
    	}
    }
    

    A、局部内部类只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化。

    B、局部内部类对象不能使用该内部类所在方法的非final局部变量。
    因为方法的局部变量位于栈上,只存在于该方法的生命期内。当一个方法结束,其栈结构被删除,局部变量成为历史。但是该方法结束之后,在方法内创建的内部类对象可能仍然存在于堆中!例如,如果对它的引用被传递到其他某些代码,并存储在一个成员变量内。正因为不能保证局部变量的存活期和方法内部类对象的一样长,所以内部类对象不能使用它们。

    局部内部类的修饰符:与成员内部类不同,局部内部类更像一个局部变量。可以用于修饰局部内部类的只有final和abstract。

    静态方法内的局部内部类:
    静态方法是没有this引用的,因此在静态方法内的内部类遭受同样的待遇,即:只能访问外部类的静态成员。

    类匿名内部

      顾名思义,没有名字的内部类。表面上看起来它们似乎有名字,实际那不是它们的名字。

    继承式的匿名内部类

        class Car {
            public void drive(){
                System.out.println("Driving a car!");
            }
        }
        
        class Test{
            public static void main(String[] args) {
                Car car = new Car(){
                    public void drive(){
                        System.out.println("Driving another car!");
                    }
                };
                car.drive();
            }
        }
    

    结果输出了:Driving another car! Car引用变量不是引用Car对象,而是Car匿名子类的对象。
    建立匿名内部类的关键点是重写父类的一个或多个方法。再强调一下,是重写父类的方法,而不是创建新的方法。因为用父类的引用不可能调用父类本身没有的方法!创建新的方法是多余的。简言之,参考多态。

    接口式的匿名内部类

      interface  Vehicle {
            public void drive();
        }
        
        class Test{
            public static void main(String[] args) {
                Vehicle v = new Vehicle(){
                    public void drive(){
                        System.out.println("Driving a car!");
                    }
                };
                v.drive();
            }
        }
    

     上面的代码很怪,好像是在实例化一个接口。事实并非如此,接口式的匿名内部类是实现了一个接口的匿名类。而且只能实现一个接口。 

    参数式的匿名内部类

    class Bar{
        void doStuff(Foo f){}
    }
    
    interface Foo{
        void foo();
    }
    
    class Test{
        static void go(){
            Bar b = new Bar();
            b.doStuff(new Foo(){
                public void foo(){
                    System.out.println("foofy");
                }
            });
        }
    }
    

      

     

     


    ==============================================================================

    本博客已经废弃,不在维护。新博客地址:http://wenchao.ren


    我喜欢程序员,他们单纯、固执、容易体会到成就感;面对压力,能够挑灯夜战不眠不休;面对困难,能够迎难而上挑战自我。他
    们也会感到困惑与傍徨,但每个程序员的心中都有一个比尔盖茨或是乔布斯的梦想“用智慧开创属于自己的事业”。我想说的是,其
    实我是一个程序员

    ==============================================================================
  • 相关阅读:
    误删本地分支,两天的工作量差点毁于一旦,使用git reflog 有惊无险恢复
    单点登录SSO
    IdentityServer4介绍和使用
    常见的远程无线通信技术
    4G模块和DTU模块有何区别
    以太网IO控制器
    什么是无线网关,无线网关的功能
    什么是IOT网关,网关功能有哪些
    Modbus RTU和Modbus TCP的两种区别
    数据采集网关设备 如何选择数据采集网关
  • 原文地址:https://www.cnblogs.com/rollenholt/p/2790639.html
Copyright © 2011-2022 走看看