• java基础(二):java内部类


      内部类像寄生虫一样生存在其他类【外部类】的内部。定义在类的内部的类叫内部类,它缩小了可见性。根据内部类定义结构的不同,可以把内部类分为

    成员内部类和局部内部类。成员内部类定义的地方和外部类的成员变量和成员方法类似,就好像类的一个成员一样。局部类内部类则定义在方法体内,仅属于局部范围所有。

      成员内部类又可以分为:实例内部类和静态内部类。局部内部类有可以分为:普通局部内部类和匿名内部类。


    一:实例内部类

      1.定义

      和实例成员变量定义位置一样。可以用四种修饰符修饰。可以再实例内部类里面定义成员变量和成员方法【静态成员变量和静态成员方法除外】。

    实例内部类它属于一个具体的对象,只有外部类的实例创建出来了它才会被加载到JVM虚拟机。

    //外部类
    public
    class outer { private String path; //实例内部类 class Inner {      } }

      2.创建对象

      实例内部类的对象的创建比较特殊,必须先创建一个外部类的实例,通过外部类的实例创建。

      

    Outer out = new Outer();
    Inner in = out.new Inner();

       如果在外部类内部创建实例内部类对象可以直接new。

       3.访问

      (1):外部内访问实例内部类的变量和方法

        通过内部类的对象访问。

      (2):实例内部类访问外部类

        直接可以访问外部类的所有成员方法和成员变量。

       特殊情况:如果内部类有实例成员变量和实例成员方法和外部类同名怎么办?用代码说明:

    先定义外部类和内部类。

    package com.briup.bean;
    
    public class InstanceOuter {
    	
    	private String path = "outer";
    	
    	public void outer() {
    		System.out.println("outer function");
    	}
    	
    	public class Inner {
    		private String path = "inner";
    
    		public String getPath() {
    			return path;
    		}
    
    		public void nameLike() {
    			System.out.println(InstanceOuter.this.path);
    			System.out.println(this.path);
    		}
    		
    		public void inner() {
    			InstanceOuter.this.outer();
    			System.out.println("inner function");
    		}
    		
    	}
    
    	public String getPath() {
    		return path;
    	}
    
    	
    	
    }
    

     测试代码:

    package com.briup.jtest;
    
    import com.briup.bean.InstanceOuter;
    import com.briup.bean.InstanceOuter.Inner;
    
    public class Test1 {
    	public static void main(String[] args) {
    		InstanceOuter outer = new InstanceOuter();
    		Inner inner = outer.new Inner();
    		inner.nameLike();
    		inner.inner();
    	}
    }
    

     控制台输出结果:

    如果实例内部类要调用同名的外部类变量和方法,需要加"类名.this.变量或方法"。

    二:静态内部类

      1.定义

        静态内部类使用static修饰。静态内部类随外部类加载而被jvm虚拟机加载。它的完整类名是:"包名.外部类类名.静态内部类类名",编译后的文件为"外部类类名$静态内部类类名.class",由于静态内部类是静态的,它无法访问外部类的非静态成员变量和方法。静态内部类相对于外部类来说,几乎是独立的。可以在没有外部类对象的情况下创建一个内部类对象。

    //外部类
    public class Outter { //静态内部类 static class inner { } }

       2.创建

      通用公式:"内部类名称 对象名 = new 外部类类名.内部类类名()" ;

      外部类内部可以直接new 出来。

      

      3.访问

        (1):外部类访问静态内部类

          通过静态内部类对象访问,私有的也可以直接访问。

        (2):静态内部类访问内部类

          直接可访问外部类的静态成员方法和变量。

    三:普通的局部内部类

      1.定义

        普通局部内部类没有范围概念,仅在定义的方法里有效。

    public void init(String path) { //方法
      class Inner {} //普通的局部内部类
    }

         本质上说,局部内部类也是独立的类,不过它的使用受到了限制。列如:不能使用static修饰,只能用final 和 abstract关键字。仅可以访问方法中final关键字的局部变量【jdk1.8新特性:可以访问不带final的局部变量,当它是final的】。

      2.创建

        它的可见范围是方法体内,在方法体内可以像普通类一样创建。

      3.访问

        仅可以访问方法中final关键字的局部变量【jdk1.8新特性:可以访问不带final的局部变量,当它是final的】。可以访问任意的外部类的成员变量。

    四:匿名内部类

      1.定义

        如果一个局部类没有名称,它就是匿名内部类。

    public void init(
       new OneInterface {} //直接new 一个接口。 
    
    )

       匿名内部类编译后的class文件命名按照匿名内部类的排列顺序来进行的,直接在外部类后加上 '$' 和 序号。如:Outer$1.class。

      2.使用

        匿名内部类可以做什么呐?可以避免修改接口而实现同一个类中两种同名方法的调用。举一个列子说明:

      比如中国人见面问候是  "xxx,你吃饭了吗" ,美国人是 "hello,xxx"。

      接口:

    package com.briup.bean;
    
    public interface OneInterface {
        
        public abstract String say();
    }

        bean类:

    package com.briup.bean;
    
    public class People {
        
        private String name;
        //国家
        private String nation;
        
        public People(String name, String nation) {
            super();
            this.name = name;
            this.nation = nation;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getNation() {
            return nation;
        }
    
        public void setNation(String nation) {
            this.nation = nation;
        }
        
        public void say(OneInterface one) {
            System.out.println(one.say());
        }
    }

     测试类:

    package com.briup.jtest;
    
    import com.briup.bean.OneInterface;
    import com.briup.bean.People;
    
    public class Test3 {
    
        public static void main(String[] args) {
            //中国人
            People china = new People("小明", "中国");
            People america = new People("jack", "America");
            
            china.say(new OneInterface() {
                
                @Override
                public String say() {
                    return "你好,吃饭了吗? " + america.getName();
                }
            });
            
            america.say(new OneInterface() {
                
                @Override
                public String say() {
                    return "hello " + china.getName() ;
                }
            });
        }
    
    }

    总结:

      1.实例内部类可以和实例成员变量和实例成员方法类比,实例成员方法可以直接访问所有成员,实例内部类也可以。

       2.静态内部类访问可以总结成一句话:不能在静态上下文中访问非静态的成员方法和变量。静态内部类相对于外部类来说,仅仅是包含关系,缩小了命名空间,完整的类名多了一个外部类的类名。本质上是两个独立的类,JVM也不知道它们的包含关系。某种程度来说:公开的静态内部类就相当于一个普通的类。

      3.内部类的作用:

        (1):内部类可以很好的实现隐藏

           一般的非内部类,是不允许有 private 与protected权限的,但内部类可以

        (2):内部类拥有外围类的所有元素的访问权限

        (3):可是实现多重继承

        (4)可以避免修改接口而实现同一个类中两种同名方法的调用。

     

  • 相关阅读:
    扫雷!!!!!!
    各种版本的flash player下载
    酷炫3d投影
    CodeSmith连接Access,Sql,Oracle,mysql
    处理模型——使用加速度控制速度
    处理模型——缩放模型
    处理2D图像和纹理——创建一个3D爆炸效果,简单的粒子系统
    处理模型——对不同对象设置不同的世界矩阵,组合世界矩阵
    处理模型——使用BasicEffect类载入模型
    处理模型——使用自定义Effects和纹理绘制模型
  • 原文地址:https://www.cnblogs.com/yangji0202/p/10554594.html
Copyright © 2020-2023  润新知