Java 内部类
Posted 棍子哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 内部类相关的知识,希望对你有一定的参考价值。
一: 内部类 定义在类体部,方法体部,甚至比方法体更小的代码块内部的类(if 语句里面等) 1.静态内部类(内部类中最简单的形式) 1.声明在类体部,方法体外,并且使用static修饰的内部类 2.访问特点可以类比静态变量和静态方法 3.脱离外部类的实例独立创建 在外部类的外部构建内部类的实例 new Outer.Inner(); 在外部类的内部构建内部类的实例 new Inner(); 4.静态内部类体部可以直接访问外部类中所有的静态成员,包含私有 /** * @author gress *静态内部类 */ public class StaticInnerTest { public static void main(String[] args) { StaticOuter.StaticInner si = new StaticOuter.StaticInner(); si.test2(); //StaticOuter.StaticInner.test(); System.out.println("si.b = "+si.b); System.out.println("si.a = "+si.a); // System.out.println("StaticOuter.b = "+StaticOuter.b); 这里报错 } } class StaticOuter { private int a = 100; private static int b = 150; public static void test(){ System.out.println("Outer static test ..."); } public void test2(){ System.out.println("Outer instabce test ..."); } static class StaticInner { public int a = 200; static int b =300; public static void test(){ System.out.println("Inner static test ..."); } public void test2(){ System.out.println("Inner instance test ..."); StaticOuter.test(); new StaticOuter().test2(); System.out.println("StaticOuter.b = "+StaticOuter.b); } } } 2.成员内部类(实例内部类) 1.没有使用static修饰的内部类。 2.在成员内部类中不允许出现静态变量和静态方法的声明。 static只能用在静态常量的声明上。 3.成员内部类中可以访问外部类中所有的成员(变量,方法),包含私有成员,如果在内部类中定义有和外部类同名的实例变量,访问: OuterClass.this.outerMember; 4.构建内部类的实例,要求必须外部类的实例先存在 外部类的外部/外部类的静态方法:new Outer().new Inner(); 外部类的实例方法: new Inner(); this.new Inner(); ** * @author gress * 实例内部类 * */ class MemberOuter{ private String s1 = "Outer InstanceMar"; private String s2 = "OuterStatic s2"; public void setS1(String s1) { this.s1 = s1; new MemberOuter().new MemberInner(); this.new MemberInner(); //此时MemberOuter已经实例化完成,所以可以使用this new MemberInner().test2(); } public static void test2 (){ new MemberOuter().new MemberInner(); /*this.new MemberInner(); * 此时MemberOuter没有实例化完成,所以不可以使用this * static 是在MemberOuter构造器前使用,所以此时this不能使用 * */ } class MemberInner{ String s1= "Inner instanceMae "; static final String s4 = "static final MemberInner"; void test2(){ System.out.println(" s1 =" + s1); System.out.println(" Outter MemberOuter.this.s1 =" + MemberOuter.this.s1); System.out.println("s2 = "+s2); } } } public class MemberInnerTest { public static void main (String args []){ /* MemberOuter.MemberInner mm = new MemberOuter().new MemberInner(); mm.test2();*/ MemberOuter mo = new MemberOuter(); mo.setS1(""); } }
不过要注意的是,当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。
如果要访问外部类的同名成员,需要以下面的形式进行访问:
外部类.
this
.成员变量
外部类.
this
.成员方法
虽然成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随心所欲了。在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问
3.局部内部类: 1.定义在方法体,甚至比方法体更小的代码块中 2.类比局部变量。 3.局部内部类是所有内部类中最少使用的一种形式。 4.局部内部类可以访问的外部类的成员根据所在方法体不同。 如果在静态方法中: 可以访问外部类中所有静态成员,包含私有 如果在实例方法中: 可以访问外部类中所有的成员,包含私有。 局部内部类可以访问所在方法中定义的局部变量,但是要求局部变量必须使用final修饰。 ** * @author gress 局部内部类 * */ public class LocalInnerTest { private int a = 1; private static int b = 2; public void test() { final int c = 3; class LocalInner { public void add1() { System.out.println("a= " + a); System.out.println("b= " + b); System.out.println("c= " + c); } } new LocalInner().add1(); } static public void test2() { final int d = 5; class LocalInner2 { public void add1() { // System.out.println("a= " + a); System.out.println("b= " + b); System.out.println("c= " + d); } } new LocalInner2().add1(); } public static void main(String args[]) { // LocalInnerTest() lc = new LocalInnerTest(); new LocalInnerTest().test2(); new LocalInnerTest().test(); } } 4.匿名内部类 1.没有名字的局部内部类。 2.没有class,interface,implements,extends关键字 3.没有构造器。 4.一般隐式的继承某一个父类或者实现某一个接口 5.吃货老师讲的一个很生动的例子 /** * @author gress 匿名内部类,我只会使用一次的类 * 假如我想吃一个泡面,但我不可能建一个厂,制造一个流水线,生产一包泡面之后就在也不去使用这个泡面厂了 * 所以这里引申出匿名内部类 ,而我们建立的泡面厂就像这里构建的一个类Pencil 铅笔类一样 */ ** * @author gress 匿名内部类,我只会使用一次的类 * * 就假如我想吃一个泡面,但我不可能建一个厂,制造一个流水线,生产一包泡面之后就在也不去使用这个泡面厂了 * 所以这里引申出匿名内部类 ,而我们建立的泡面厂就像这里构建的一个类Pencil 铅笔类一样 */ interface Pen { public void write(); } class Pencil implements Pen { @Override public void write() { //铅笔 的工厂 } } class Person { public void user(Pen pen) { pen.write(); } } public class AnyInnerTest { public static void main(String args[]) { Person guo = new Person(); guo.user(new Pen() { @Override public void write() { System.out.println("写子"); } }); } } 二: abstract 只能单继承 1.方法:抽象方法 不能有方法体 抽象方法所在类一定是抽象类 抽象方法存在就是被覆盖的,如果子类继承带有抽象方法的抽象类,必须对所以的抽象方法进行覆盖 2.类 :抽象类 抽象类不能被实例化 抽象类是对类的抽象,抽象所具有的共有特征和行为 抽象类所存在的目的就是用来被继承,实现代码的复用 抽象类可以有抽象方法也可以没有抽象方法,可以像普通的一个类具有成员变量和方法 如果一个类继承抽象类,必须实现抽象父类的抽象方法,或者子类也是一个抽象方法 三: interface 可以多实现(继承) 1.接口是比抽象类还抽象的存在,接口是抽象类的极致抽象。 2.接口中所有的方法都是public abstracht,接口中所有的变量都是public static final 3.接口主要用来定义标准。 4.接口可以多继承。一个类可以实现多个接口。 5.接口的存在本身可以规避java不能多继承的操作特点。 interface USBDevice{ String type="USB"; void driver(); } class Mouse{ select(); } class USBMouse extends Mouse implements USBDevice{ } class Computer{ void use(USBDevice usb){ usb.driver(); } }
以上是关于Java 内部类的主要内容,如果未能解决你的问题,请参考以下文章