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

      1、内部类   

    /*
     * 内部类:声明在一个类的内部的类。之前没有声明
     * 在另外一个类的内部的类,称之为顶层类。包含内部
     * 类的类,称为外围类。
     * 
     * 顶层类可以声明为public,默认访问权限。
     * 内部类可以是任意的访问权限。
     * 
     * 内部类的作用:
     * 1 可以令内部类与外围类关系更在紧密。
     * 2 内部类可以提供更好地访问权限的控制。
     * 
     * 内部类与外围类可以自由的访问彼此的成员。(
     * 包括声明为private的成员。)
     * 
     * 内部类可以分为以下几种:
     * 1 静态成员类
     * 2 实例成员类
     * 3 局部类
     * 4 匿名类
     * 
     * 
     */
    package day10;
    
    public class Inner {
    	private int x;
    
    	public void k() {
    		T t = new T();
    		t.y = 2;
    	}
    
    	class T {
    		private int y;
    
    		public void f() {
    			x = 1;
    		}
    	}
    }
    

      2、静态成员类

    /*
     * 静态成员类
     * 静态成员类使用static修饰。
     * 静态成员类类似于类中声明的静态成员变量。
     * 静态成员类不依赖于外围类的对象而存在。在访问静态成员类时,
     * 不需要创建外围类的对象。
     * 在外围类的内部,可以直接通过静态成员类的名字对静态成员类
     * 进行访问。
     * 在外围类的外部,需要使用外围类.静态成员类来访问静态成员类。
     * 静态成员类不能访问外围类的实例成员。(类似于静态方法不能
     * 访问实例成员)
     */
    package day10;
    
    public class StaticInner {
    	static int x;
    	int y;
    	
    	
    	
    	//静态成员类
    	public static class T {
    		public void f() {
    			//错误,不能访问外围类的实例成员。
    			//y = 1;
    		}
    	}
    	
    	public static void f() {
    		//StaticInner.x = 1;
    		x = 1;
    		T t = new T();
    		//StaticInner.T t = new StaticInner.T();
    	}
    }
    
    class Outer {
    	public void f() {
    		//x = 3;
    		StaticInner.x = 3;
    		StaticInner.T t = new StaticInner.T();
    		t.f();
    	}
    }
    

      3、实例成员类

    /*
     * 实例成员类
     * 实例成员类作为外围类的成员,不使用static修饰。
     * 实例成员类类似实例成员变量。
     * 实例成员类依赖于外围类的对象,如果我们要创建实例
     * 成员类的对象,则必须首先创建外围类的对象。
     * 实例成员类可以访问外围类的实例成员。(静态成员类不能)
     * 实例成员类不能声明任何静态上下文环境。(静态成员变量,
     * 静态方法,静态初始化块)	(静态成员类可以)
     * 例外:实例成员类可以声明静态编译时常量。(final)
     * 因为在编译过后,字节码直接使用的是静态final的常量值。
     * 而不存在该静态成员变量。
     */
    package day10;
    
    public class InstanceInner {
    	int x = 1;
    
    	// 实例成员类
    	public class T {
    		//错误,实例成员类不能声明静态成员。
    		//static int staX = 5;
    		//例外,可以声明静态的编译时常量。
    		static final int staX = 5;
    		
    		public void kk() {
    			x = 5;
    			System.out.println(staX * 2);
    			//System.out.println(5 * 2);
    		}
    	}
    
    	public void f() {
    		x = 2;
    		T t = new T();
    	}
    
    	public static void g() {
    		// x = 2;
    		// T t = new T();
    	}
    }
    
    class Outer2 {
    	public void f() {
    		// InstanceInner i = new InstanceInner();
    		// InstanceInner.T t = i.new T();
    		// 如果不需要外围类的引用,可以这样写:
    		InstanceInner.T t = new InstanceInner().new T();
    	}
    }
    

      4、案例

    /*
     * 
     */
    package day10;
    
    public class Shadow {
    	int x = 50;
    
    	class Inner {
    		int x = 100;
    
    		public void f() {
    			int x = 200;
    			// 访问局部变量x。
    			System.out.println(x);
    			// 访问实例成员类的成员变量x。
    			System.out.println(this.x);
    			// 如何访问外围类的x?
    			// 访问外围类的成员变量x。
    			System.out.println(Shadow.this.x);
    		}
    	}
    
    	public static void main(String[] args) {
    		Shadow s = new Shadow();
    		Inner i = s.new Inner();
    		i.f();
    	}
    }
    

      5、局部类

    /*
     * 局部类:声明在方法,语句块等局部范围内的类。
     * 局部类类似于方法中声明的局部变量。
     * 局部类不能使用static修饰,也不能使用访问修饰符修饰
     * (因为局部变量不能使用以上关键字修饰)。
     * 局部类不能声明静态成员。
     * 如果局部类处于静态的上下文环境中,则局部类不能访问
     * 外围类的实例成员。(可以访问静态成员。)
     * 如果局部类处于实例的上下文环境中,则局部类可以访问
     * 外围类静态与实例的成员。
     */
    package day10;
    
    public class Local {
    	int x = 1;
    	static int y = 1;
    
    	public void f() {
    		// 局部类
    		class Inner2 {
    			public void g() {
    				System.out.println(x);
    				System.out.println(y);
    			}
    		}
    		Inner2 i = new Inner2();
    	}
    
    	public void k() {
    		//Inner2 i = new Inner2();
    	}
    
    	public static void staticF() {
    		class Inner {
    			public void g() {
    				// System.out.println(x);
    				System.out.println(y);
    			}
    		}
    	}
    }
    

      6、局部类

    /*
     * 局部类仅在声明的位置开始,到其所在的最小语句块结束。
     * 局部类的对象在局部范围(声明局部类的范围,即局部类的作用域)
     * 之外不能使用,为了能够让局部对象存活在局部范围之外,通过
     * 令局部类实现一个接口,然后在方法中返回接口类型。也就是
     * 将局部类的对象作为接口类型返回。
     * 
     */
    package day10;
    
    public class Local2 {
    	public Mobile get() {
    		class Inner implements Mobile {
    			@Override
    			public void call() {
    				System.out.println("打电话");
    			}
    		}
    		// Inner i = new Inner();
    		// return i;
    		return new Inner();
    	}
    
    	public static void main(String[] args) {
    		Local2 l = new Local2();
    		Mobile m = l.get();
    		m.call();
    	}
    }
    
    interface Mobile {
    	void call();
    }
    
    class UseMobile {
    	public void use() {
    		Local2 l = new Local2();
    		Mobile m = l.get();
    		m.call();
    	}
    }
    

      

    /*
     * 局部类对局部变量的访问
     * 在JavaSE 8之前,局部类只能访问声明为final的
     * 局部变量。
     * 从JavaSE 8开始,局部类也能访问声明为非final的
     * 局部变量,前提是,该局部变量的值,没有发生更改。
     * (final等效的局部变量)
     */
    package day10;
    
    public class Local3 {
    	public void f() {
    		int x = 1;
    		// x = 2;
    		class Inner {
    			public void g() {
    				System.out.println(x);
    			}
    		}
    	}
    }
    

      7、匿名类

    /*
     * 当局部类只用到一次,并且局部类的类体相对较短时,
     * 我们可以使用匿名类来代替局部类,这样可以是程序
     * 更加简洁。
     */
    package day10_2;
    
    public class Anonymous2 {
    	public Mobile getMobile() {
    		// class T implements Mobile {
    		// @Override
    		// public void call() {
    		// System.out.println("打电话");
    		// }
    		// }
    		// return new T();
    		return new Mobile() {
    			@Override
    			public void call() {
    				System.out.println("匿名类打电话");
    			}
    		};
    		//T t = new T();
    		//T t2 = new T();
    	}
    }
    
    interface Mobile {
    	void call();
    }
    

      

    /*
     * 匿名类
     * 匿名类就是没有名字的类。
     * 匿名类集类的声明与创建对象为一体,即在声明类的同时
     * 创建匿名类的对象。
     * 
     * 对于匿名类的语法,new T() {}创建的并不是T类型的对象,
     * 而是T的子类型的对象(匿名类类型的对象)。如果T是一个类,
     * 则匿名类继承T。如果T是一个接口,则匿名类实现接口T。
     * 
     * 在匿名类中,不能声明构造器。因为匿名类没有名字。
     */
    package day10_2;
    
    public class Anonymous {
    	public void f() {
    		T t = new T();
    		//匿名类
    		T t2 = new T() {
    			int x;
    			public void g() {
    				
    			}
    		};
    		Inter inter = new Inter() {
    			
    		};
    		A a = new A() {
    			
    		};
    		//inter = new Inter();
    		//a = new A();
    	}
    }
    
    class T {
    
    }
    
    interface Inter {
    	
    }
    
    abstract class A {
    	
    }
    

      8、

    内部类的字节码文件命名

     * 与顶层类一样,在编译过后,内部类也会生成字节码文件(.class)。

     * 对于成员类(静态成员类与实例成员类),生成的class文件名

     * 为--外围类$成员类.class

     * 对于局部类,生成的class文件名为--外围类$数字局部类.class

     * 对于匿名类,生成的class文件名为--外围类$数字.class

        9、函数式接口   

    /*
     * 函数式接口
     * 如果接口中有且仅有一个抽象的方法(这里的抽象方法不包括
     * 从Object类中继承的方法),则这样的接口
     * 称为函数式接口。对于默认方法与静态方法,没有要求。
     * 
     * 我们可以使用@FunctionalInterface来对一个接口进行标记,
     * 表示该接口为函数式接口。
     */
    package day10_2;
    
    @FunctionalInterface
    public interface Function {
    	void f();
    }
    
    //@FunctionalInterface
    interface Function2 {
    	void f();
    	void g();
    }
    @FunctionalInterface
    interface Function3 {
    	void f();
    	String toString();
    }
    
    class Function3Impl  implements Function3 {
    	@Override
    	public void f() {
    		
    	}
    }
    

      10、Lambda表达式

    /*
     * Lambda表达式的结果类型称为目标类型。
     * Lambda表达式的目标类型为函数式接口类型。
     * Lambda表达式的结果值就是一个实现了函数式接口类型的对象。
     * Lambda表达式在形式上类似于一个匿名的方法。
     * 
     * Lambda表达式的语法:
     * (参数列表) -> {方法体}
     * 1 参数列表的类型可以省略。
     * 2 当参数个数只有一个时,可以省略小括号。
     * 3 当方法含有返回值,并且方法体只有一条语句时,
     * 可以将return与{}一同省略。
     * 4 当方法没有返回值,并且方法体只有一条语句是,
     * 可以省略{}。
     */
    package day10_2;
    
    public class Lambda {
    	public Mobile getMobile() {
    		/*
    		 * return new Mobile() {
    		 * 
    		 * @Override public void call() { System.out.println("打电话"); } };
    		 */
    		// Mobile m = () -> System.out.println("Lambda的实现");
    		// return m;
    		return () -> System.out.println("Lambda的实现");
    	}
    	
    	public void f() {
    		Value v = new Value() {
    			@Override
    			public int get(int k) {
    				return 0;
    			}
    		};
    		
    		//Value v2 = (int k) -> {return 0;};
    		//省略参数列表的类型。
    		//Value v2 = (k) -> {return 0;};
    		//省略小括号
    		//Value v2 = k -> {return 0;};
    		//省略{}与return。
    		Value v2 = k -> 0;
    	}
    }
    
    @FunctionalInterface
    interface Value {
    	int get(int k);
    }
    

      11、方法引用

    /*
     * 方法引用
     * 当Lambda表达式中仅仅调用一个已经存在的方法时,
     * 我们就可以使用方法引用来代替Lambda表达式,
     * 这样能够使程序更加简洁。
     * 
     * 方法引用可以分为以下四类:
     * 1 引用静态方法
     * 2 通过对象引用实例方法
     * 3 通过类型引用实例方法
     * 4 引用构造器
     */
    
    package day10_2;
    
    public class MethodReference {
    	public void test() {
    		Friend f = (p1, p2) -> {
    			Person.makeFriend(p1, p2);
    		};
    		/*
    		 * 引用静态方法。抽象方法中的参数会依次传递 给所引用方法。
    		 */
    		f = Person::makeFriend;
    		// f.makeFriend(p1, p2);
    		Tool tool = new Tool();
    		f = (p1, p2) -> {
    			tool.makeFriend(p1, p2);
    		};
    		/*
    		 * 通过对象引用实例方法,抽象方法中的参数会依次传递 给所引用的方法。
    		 */
    		f = tool::makeFriend;
    		f = (p1, p2) -> {
    			p1.makeFriend2(p2);
    		};
    		/*
    		 * 通过类型引用实例方法。抽象方法的第一个参数作为 调用方法(所引用的方法)的对象(引用),从第二个 参数起,依次传递给所引用的方法。
    		 */
    		f = Person::makeFriend2;
    		Create c = (n, a, h, w) -> {
    			return new Person(n, a, h, w);
    		};
    		/*
    		 * 引用构造器。抽象方法的参数会依次传递给构造器。
    		 */
    		c = Person::new;
    	}
    }
    
    @FunctionalInterface
    interface Friend {
    	void makeFriend(Person p1, Person p2);
    }
    
    @FunctionalInterface
    interface Create {
    	Person get(String name, int age, int height, int weight);
    }
    
    class Tool {
    	public void makeFriend(Person p1, Person p2) {
    		// 实现交朋友操作
    	}
    }
    

      12、Lambda表达式  案例(第十天第二部分)

  • 相关阅读:
    HTML5 模板推荐
    OpenCV初探
    微信开放框架-UCToo
    ProFTPD 初探
    移动开发者服务平台-友盟
    线程原理理解
    JVM参数及性能调优
    GC——垃圾回收
    JVM内存模型
    php常用 随机数
  • 原文地址:https://www.cnblogs.com/liuwei6/p/6572262.html
Copyright © 2011-2022 走看看