Java面对对象19:内部类

一、内部类

  • 内部类就是在一个类的内部再定义一个类,比如:A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对B类来说就是外部类。
  • 使用内部类编写的代码,可读性很差。能不用尽量不用

  • 成员内部类
    //外部类
    public class Outer {
    
        private int id = 1123;
        public void out() {
            System.out.println("这是外部类的方法");
        }
    
        //成员内部类
        public class Inner{
            public void in() {
                System.out.println("这是内部类的方法");
            }
    
            //成员内部类可以直接访问外部类的私有变量和方法
            public void getID() {
                System.out.println(id);
            }
    
            public void getOut() {
                out();
            }
        }
    }
    
    class Application {//测试类
    
        public static void main(String[] args) {
    
            Outer outer = new Outer();//new外部类对象
            //new 内部类对象 可以通过外部类来实例化内部类
            Outer.Inner inner = outer.new Inner();
            inner.in();//输出:这是内部类的方法
           
            //简写
            new Outer().new Inner().in(); //输出:这是内部类的方法
    
            //通过内部类可以直接访问外部类的私有变量和方法
            inner.getID();//输出:1123
            inner.getOut();//输出:这是外部类的方法
        }
    }
    

  • 静态内部类
    //外部类
    public class Outer {
    
       private static int age = 23;
       public static void test() {
           System.out.println("这是外部类的静态方法");
       }
    
       private int id = 1123;
       public void out() {
           System.out.println("这是外部类的方法");
       }
    
       //静态内部类
       public static class Inner{
           public void in() {
               System.out.println("这是内部类的方法");
           }
    
           //静态内部类只能直接访问外部类的静态变量和方法,不能访问非静态的
           public void getAge() {
               System.out.println(age);
           }
    
           public void getTest() {
               test();
           }
       }
    }
    
    class Application {//测试类
    
       public static void main(String[] args) {
    
           //与成员内部类不同,静态内部类与外部类一起加载,则Outer.Inner
           //因为外部类Outer未实例化,所以要调用静态内部类的变量和方法,也需实例化
           //因为我们要调用的是静态内部类的东西,所以实例化的时候应该含有静态内部类
           Outer.Inner inner = new Outer.Inner();
           inner.in();//输出:这是内部类的方法
           //简写
           new Outer.Inner().in(); //输出:这是内部类的方法
    
           //通过静态内部类只能直接访问外部类的静态变量和方法
           inner.getAge();//输出:23
           inner.getTest();//输出:这是外部类的静态方法
       }
    }
    

  • 局部内部类
    //外部类
    public class Outer {
    
        public void method() {
            //局部内部类:方法里面的类
            class Inner {
                public void in() {
                    System.out.println("这是局部内部类的方法");
                }
            }
            //局部内部类不能直接在main()方法中实例化和调用方法
            //局部内部类只能在外部类方法中new出来并调用方法,才能在main()方法中调用局部内部类的方法
            new Inner().in();//这个相当于最后输出的内容——"这是局部内部类的方法"
        }
    }
    
    class Application {//测试类()
    
        public static void main(String[] args) {
            //先new 外部类
            Outer outer = new Outer();
            //因为局部内部类已经在外部类方法中实例化并调用方法,所以直接调用外部类方法就可以
            outer.method();//这是局部内部类的方法
        }
    }
    

  • 匿名内部类
    public class Test {//测试
        public static void main(String[] args) {
            //匿名内部类:没有名字初始化(实例化)类,不用将实例保存到变量中
            //没有指向引用变量,直接初始化(实例化)
            new Apple().eat();//输出:1123
    
            //———接口————
            //重写方法后指向给一个引用变量
            UserService userService = new UserService(){
                @Override
                public void happy() {
                    System.out.println("开心");
                }
            };
            userService.happy();//输出:开心
    
            //匿名(没有指向引用变量,直接初始化(实例化))
            new UserService(){
                @Override
                public void happy() {
                    System.out.println("好开心");
                }
            }.happy();//输出:好开心
        }
    }
    
    //=======================================================================
    class Apple {
        public void eat() {
            System.out.println("1123");
        }
    }
    
    //接口
    interface UserService {
        public abstract void happy();
    }
    
    /*
    	匿名内部类:
    
    		1、什么是内部类?
    			内部类:在类的内部又定义了一个新的类。被称为内部类。
    
    		2、内部类的分类:
    			静态内部类:类似于静态变量
    			实例内部类:类似于实例变量
    			局部内部类:类似于局部变量
    
    		3、使用内部类编写的代码,可读性很差。能不用尽量不用。
    
    		4、匿名内部类是局部内部类的一种。
    			因为这个类没有名字而得名,叫做匿名内部类。
    
    		5、学习匿名内部类主要是让大家以后在阅读别人代码的时候,能够理解。
    		并不代表以后都要这样写。因为匿名内部类有两个缺点:
    			缺点1:太复杂,太乱,可读性差。
    			缺点2:类没有名字,以后想重复使用,不能用。
    
    		6、不理解算了,你只要记住这种写法就行。
    */
    
    class ClassroomTest01 {
    
        // 静态变量
        static String country;
        // 该类在类的内部,所以称为内部类
        // 由于前面有static,所以称为“静态内部类”
        static class Inner1{
        }
    
        // 实例变量
        int age;
        // 该类在类的内部,所以称为内部类
        // 没有static叫做实例内部类。
        class Inner2{
        }
    
        // 方法
        public void doSome(){
            // 局部变量
            int i = 100;
            // 该类在类的内部,所以称为内部类
            // 局部内部类。
            class Inner3{
            }
        }
    
        public void doOther(){
            // doSome()方法中的局部内部类Inner3,在doOther()中不能用。
        }
    
        // main方法,入口
        public static void main(String[] args){
            // 调用MyMath中的mySum方法。
            MyMath mm = new MyMath();
    		/*
    		Compute c = new ComputeImpl();
    		mm.mySum(c, 100, 200);
    		*/
    
            //合并(这样写代码,表示这个类名是有的。类名是:ComputeImpl)
            //mm.mySum(new ComputeImpl(), 100, 200);
    
            // 使用匿名内部类,表示这个ComputeImpl这个类没名字了。
            // 这里表面看上去好像是接口可以直接new了,实际上并不是接口可以new了。
            // 后面的{} 代表了对接口的实现。
            // 不建议使用匿名内部类,为什么?
            // 因为一个类没有名字,没有办法重复使用。另外代码太乱,可读性太差。
            mm.mySum(new Compute(){
                public int sum(int a, int b){
                    return a + b;
                }
            }, 200, 300);
    
    
    
        }
    
    }
    
    // 负责计算的接口
    interface Compute{
    
        // 抽象方法
        int sum(int a, int b);
    }
    
    // 你自动会在这里编写一个Compute接口的实现类
    /*
    class ComputeImpl implements Compute{
    
    	// 对方法的实现
    	public int sum(int a, int b){
    		return a + b;
    	}
    }
    */
    
    // 数学类
    class MyMath{
        // 数学求和方法
        public void mySum(Compute c, int x, int y){
            int retValue = c.sum(x, y);
            System.out.println(x + "+" + y + "=" + retValue);
        }
    }
    
    
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值