ToB企服应用市场:ToB评测及商务社交产业平台

标题: Java基础——内部类的分类 [打印本页]

作者: 钜形不锈钢水箱    时间: 2022-6-23 23:13
标题: Java基础——内部类的分类
1 内部类

1.1 概述

1、什么是内部类?
将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类
2、为什么要声明内部类呢?
总的来说,遵循高内聚低耦合的面向对象开发总原则。便于代码维护和扩展。
具体来说,当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,不在其他地方单独使用,那么整个内部的完整结构最好使用内部类。而且内部类因为在外部类的里面,因此可以直接访问外部类的私有成员。
3、内部类都有哪些形式?
根据内部类声明的位置(如同变量的分类),我们可以分为:
(1)成员内部类:
(2)局部内部类
1.2 成员内部类

如果成员内部类中不使用外部类的非静态成员,那么通常将内部类声明为静态内部类,否则声明为非静态内部类。
语法格式:
  1. 【修饰符】 class 外部类{<br>    【其他修饰符】 【static】 class 内部类{<br>    }<br>}
复制代码
1、静态内部类

有static修饰的成员内部类叫做静态内部类。它的特点:
其实严格的讲(在James Gosling等人编著的《The Java Language Specification》)静态内部类不是内部类,而是类似于C++的嵌套类的概念,外部类仅仅是静态内部类的一种命名空间的限定名形式而已。所以接口中的内部类通常都不叫内部类,因为接口中的内部成员都是隐式是静态的(即public static)。例如:Map.Entry。
2、非静态成员内部类

没有static修饰的成员内部类叫做非静态内部类。非静态内部类的特点:
  1. public class TestMemberInnerClass {<br>    public static void main(String[] args) {<br>        Outer.outMethod();<br>        System.out.println("-----------------------");<br>        Outer out = new Outer();<br>        out.outFun();<br>​<br>        System.out.println("####################################");<br>        Outer.Inner.inMethod();<br>        System.out.println("------------------------");<br>        Outer.Inner inner = new Outer.Inner();<br>        inner.inFun();<br>​<br>        System.out.println("####################################");<br>        Outer outer = new Outer();<br>//        Outer.Nei nei = outer.new Nei();<br>        Outer.Nei nei = out.getNei();<br>        nei.inFun();<br>    }<br>}<br>class Outer{<br>    private static String a = "外部类的静态a";<br>    private static String b  = "外部类的静态b";<br>    private String c = "外部类对象的非静态c";<br>    private String d = "外部类对象的非静态d";<br>​<br>    static class Inner{<br>        private static String a ="静态内部类的静态a";<br>        private String c = "静态内部类对象的非静态c";<br>        public static void inMethod(){<br>            System.out.println("Inner.inMethod");<br>            System.out.println("Outer.a = " + Outer.a);<br>            System.out.println("Inner.a = " + a);<br>            System.out.println("b = " + b);<br>//            System.out.println("c = " + c);//不能访问外部类和自己的非静态成员<br>//            System.out.println("d = " + d);//不能访问外部类的非静态成员<br>        }<br>        public void inFun(){<br>            System.out.println("Inner.inFun");<br>            System.out.println("Outer.a = " + Outer.a);<br>            System.out.println("Inner.a = " + a);<br>            System.out.println("b = " + b);<br>            System.out.println("c = " + c);<br>//            System.out.println("d = " + d);//不能访问外部类的非静态成员<br>        }<br>    }<br>​<br>    class Nei{<br>        private String a = "非静态内部类对象的非静态a";<br>        private String c = "非静态内部类对象的非静态c";<br>​<br>        public void inFun(){<br>            System.out.println("Nei.inFun");<br>            System.out.println("Outer.a = " + Outer.a);<br>            System.out.println("a = " + a);<br>            System.out.println("b = " + b);<br>            System.out.println("Outer.c = " + Outer.this.c);<br>            System.out.println("c = " + c);<br>            System.out.println("d = " + d);<br>        }<br>    }<br>​<br>    public static void outMethod(){<br>        System.out.println("Outer.outMethod");<br>        System.out.println("a = " + a);<br>        System.out.println("Inner.a = " + Inner.a);<br>        System.out.println("b = " + b);<br>//        System.out.println("c = " + c);<br>//        System.out.println("d = " + d);<br>        Inner in = new Inner();<br>        System.out.println("in.c = " + in.c);<br>    }<br>​<br>    public void outFun(){<br>        System.out.println("Outer.outFun");<br>        System.out.println("a = " + a);<br>        System.out.println("Inner.a = " + Inner.a);<br>        System.out.println("b = " + b);<br>        System.out.println("c = " + c);<br>        System.out.println("d = " + d);<br>        Inner in = new Inner();<br>        System.out.println("in.c = " + in.c);<br>    }<br>​<br>    public Nei getNei(){<br>        return new Nei();<br>    }<br>}
复制代码
1.4 局部内部类

1、局部内部类

语法格式:
  1. 【修饰符】 class 外部类{<br>    【修饰符】 返回值类型  方法名(【形参列表】){<br>            【final/abstract】 class 内部类{<br>        }<br>    }    <br>}
复制代码
局部内部类的特点:
示例代码:
  1. public class TestLocalInner {<br>    public static void main(String[] args) {<br>        Runner runner = Outer.getRunner();<br>        runner.run();<br>​<br>        System.out.println("-------------------");<br>        Outer.outMethod();<br>​<br>        System.out.println("-------------------");<br>        Outer out = new Outer();<br>        out.outTest();<br>    }<br>}<br>class Outer{<br>    private static String a = "外部类的静态a";<br>    private String b = "外部类对象的非静态b";<br>​<br>    public static void outMethod(){<br>        System.out.println("Outer.outMethod");<br>        final String c = "局部变量c";<br>        class Inner{<br>            public void inMethod(){<br>                System.out.println("Inner.inMethod");<br>                System.out.println("out.a = " + a);<br>//              System.out.println("out.b = " + b);//错误的,因为outMethod是静态的<br>                System.out.println("out.local.c = " + c);<br>            }<br>        }<br>​<br>        Inner in = new Inner();<br>        in.inMethod();<br>    }<br>​<br>    public void outTest(){<br>        class Inner{<br>            public void inMethod(){<br>                System.out.println("out.a = " + a);<br>                System.out.println("out.b = " + b);//可以,因为outTest是非静态的<br>            }<br>        }<br>​<br>        Inner in = new Inner();<br>        in.inMethod();<br>    }<br>​<br>    public static Runner getRunner(){<br>        class LocalRunner implements Runner{<br>            @Override<br>            public void run() {<br>                System.out.println("LocalRunner.run");<br>            }<br>        }<br>        return new LocalRunner();<br>    }<br>​<br>}<br>interface Runner{<br>    void run();<br>}
复制代码
2、匿名内部类

当我们在开发过程中,需要用到一个抽象类的子类的对象或一个接口的实现类的对象,而且只创建一个对象,而且逻辑代码也不复杂。那么我们原先怎么做的呢?
(1)编写类,继承这个父类或实现这个接口
(2)重写父类或父接口的方法
(3)创建这个子类或实现类的对象
这里,因为考虑到这个子类或实现类是一次性的,那么我们“费尽心机”的给它取名字,就显得多余。那么我们完全可以使用匿名内部类的方式来实现,避免给类命名的问题。
  1. new 父类(【实参列表】){<br>    重写方法...<br>}<br>//()中是否需要【实参列表】,看你想要让这个匿名内部类调用父类的哪个构造器,如果调用父类的无参构造,那么()中就不用写参数,如果调用父类的有参构造,那么()中需要传入实参
复制代码
  1. new 父接口(){<br>    重写方法...<br>}<br>//()中没有参数,因为此时匿名内部类的父类是Object类,它只有一个无参构造
复制代码
匿名内部类是没有名字的类,因此在声明类的同时就创建好了唯一的对象。
注意:
匿名内部类是一种特殊的局部内部类,只不过没有名称而已。所有局部内部类的限制都适用于匿名内部类。例如:
思考:这个对象能做什么呢?
(1)使用匿名内部类的对象直接调用方法
  1. interface A{<br>    void a();<br>}<br>public class Test{<br>    public static void main(String[] args){<br>        new A(){<br>            @Override<br>            public void a() {<br>                System.out.println("aaaa");<br>            }<br>        }.a();<br>    }<br>}
复制代码
(2)通过父类或父接口的变量多态引用匿名内部类的对象
  1. interface A{<br>    void a();<br>}<br>public class Test{<br>    public static void main(String[] args){<br>        A obj = new A(){<br>            @Override<br>            public void a() {<br>                System.out.println("aaaa");<br>            }<br>        };<br>        obj.a();<br>    }<br>}
复制代码
(3)匿名内部类的对象作为实参
  1. interface A{<br>    void method();<br>}<br>public class Test{<br>    public static void test(A a){<br>        a.method();<br>    }<br>    <br>    public static void main(String[] args){<br>        test(new A(){<br>​<br>            @Override<br>            public void method() {<br>                System.out.println("aaaa");<br>            }<br>        });<br>    }   <br>}
复制代码
  1. package net.cyan.cy.test04;<br>​<br>public class FlyDemo {<br>    public static void main(String[] args) {<br>        //匿名内部类<br>        Fly f=new Fly() {<br>            @Override<br>            public void fly() {<br>                System.out.println("再美不及姑娘你");<br>            }<br>        };<br>        f.fly();<br>        System.out.println("----------------------------------------------");<br>        //匿名内部类匿名对象调用<br>        new Fly(){<br>            @Override<br>            public void fly() {<br>                System.out.println("再美不及姑娘你你");<br>            }<br>        }.fly();<br>        System.out.println("-----------------------------------------------");<br>        //匿名内部类对象传参<br>        Fly f1=new Fly() {<br>            @Override<br>            public void fly() {<br>                System.out.println("再美不及姑娘你你你");<br>            }<br>        };<br>        method(f1);<br>        System.out.println("-----------------------------------------------------------");<br>            //匿名内部类对象匿名传参sifei<br>        method(new Fly() {<br>            @Override<br>            public void fly() {<br>                System.out.println("再美不及姑娘你你你你");<br>            }<br>        });<br>​<br>    }<br>    public static  void method(Fly f){<br>        f.fly();<br>    }<br>}
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4