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

    一、内部类的概念

         定义在类中或接口中的类称之为内部类。

         如果某个类只在另一个类中或另一个类的某个方法中使用,而不希望在整个项目中单独定义这个类,则可以通过定义内部类的方式,将这个类定义在需要使用它的类的内部或者该类方法的内部。

    二、内部类的分类

     内部类分为方法内部类、成员内部类、静态内部类和匿名内部类。

    1.方法内部类

      方法内部类的定义:在一个方法的内部定义的类,称之为方法内部类。方法内部类只能在当前定义到方法的结尾之间内能够被使用。

      如果某个类只在某个方法内部使用到,则可以将该类声明在方法内,限定其使用的范围。

     方法内部类的特点;

    1.  可以具有成员变量和成员属性
    2. 不能有静态变量和静态方法。因为此时内部类的寄生环境——外部类的方法还未生成,静态变量和静态方法不能访问
    3. 可以声明静态常量。常量放置在常量区。
    4. 可以继承其他类或者实现接口。
    5. 可以使用外部类的成员属性和成员方法。
    6. Jdk8之前不能访问包裹当前内部类的方法中定义的局部属性,除非将其声明为final;Jdk8之后可以访问了,但不能对该值进行修改,如果进行修改,访问会报错。即:内部类可以访问外部类的变量,外部类的变量不可以修改(通常修饰为final)。

             

    class Person {
        private String name;
        public void say() {
            System.out.println("说...");
        }
        
        
        //方法内部类
        public void eat() {
            String food = "羊肉串";
            //方法内部类
            class Cooker {
                //1.可以具有成员变量和成员方法
                private String tool = "菜刀";
                //2.可以有静态常量,不能有静态变量和方法
                private static final String name = "张三";
                public void cook() {
                    System.out.println("厨师使用"+ tool + "做菜给"  + name +"" + food);
                    //5.可以调用外部方法
                    say();
                }            
            }
            //6. 内部类访问方法内的成员变量,该变量不能修改
            //food = "牛肉串";
            
            Cooker cooker= new Cooker();
            cooker.cook();
            
            System.out.println("吃...");
            
            
            //4.可以继承和实现接口
            class SichuanCooker extends Cooker {}                
        }
    }

    2.成员内部类

       定义在一个类内部,可以当做类的一个成员使用的内部类称之为成员内部类。

       用法:如果某个类内部还需要具有一个类结构,且需要外部类作为环境存在,则可以定义成员内部类。

      成员内部类的特征:

    1. 成员内部类可以定义成员属性和成员方法。
    2. 成员内部类不可以定义静态变量和静态方法。
    3. 成员内部类可以定义静态常量。
    4. 成员内部类可以访问外部定义的成员属性,成员方法和静态方法。
    5. 可以通过访问权限修饰符修饰成员内部类。
    6. 可以在外部类中使用成员内部类。
    7. 在访问权限允许的情况下,可以在外部类之外通过对象来使用成员内部类。
    8. 可以继承类和实现接口。
    class Outer {
        String Oname;
        public void eat(){};
        //6.外部方法可以访问内部类
        public void run(Inner inner){};
        class Inner {
    //3.成员内部类可以定义静态常量
    private static final String name ="张安";
    //1.成员内部类可以定义成员属性和成员方法
    public void say() {
                System.out.println("说..." + Oname);
                //4.内部类可以访问外部类的方法
                eat();
            }
        }
        
        //8.一个内部类可以继承另外一个内部类
        public class Inner2 extends Inner{};
    }
    public class Demo02 {
        public static void main(String[] args) {
            Outer ou01 = new Outer();
            //7.可以使用外部类对象.new Inner()方式创建内部类对象
            Inner in01 = ou01.new Inner();
            in01.say();
        }
    
    }

    3.静态内部类

      用static修饰的成员内部类就是静态内部类;其本质上是成员内部类的静态版本。

      静态内部类的特点:

    1. 可以定义成员属性和成员方法。
    2. 可以定义静态属性和静态方法。
    3. 静态内部类不可以访问外部类中非静态的成员属性和成员方法。
    4. 在外部类的内部,可以使用静态内部类。
    5. 可以通过访问权限修饰符修饰内部类。
    6. 在访问权限允许的情况下也可以在外部类之外通过【外部类.内部类】的方式访问静态内部类。
    7. 可以继承类和实现接口。
    class Outer {
    //4.在外部类可以使用静态内部类
    private Inner in3 = null; static class Inner {
    //2.可以定义静态成员和方法
    private static String name;
    //1.可以定义成员属性和方法
    private int age; public static void say(){ System.out.println("说..."); } public static void say2() { System.out.println("说2..."); } } } public class StaticInnerClass { public static void main(String[] args) {
    //7.可以通过外部类.内部类方法访问静态内部类 Outer.Inner inner
    = new Outer.Inner(); } }

    4.匿名内部类

         定义: 当new一个类(或接口)之后,在其后紧跟一个大括号,此时new的不是这个类或接口;而是创建了这个类或接口的匿名的子类(或者匿名实现类),其中大括号内为子类(或匿名实现类)的实现代码,new出来的是这个匿名内部类的对象。

        用法:抽象类、普通类、接口都可以使用匿名内部类的用法;

        匿名内部类的好处:内名内部类用起来减少了类的声明,简单方便,使用场景较多。

        

    **
     * 匿名内部类
     * @author Administrator
     *
     */
    abstract class Car {
        public abstract void run();
    }
    
    //抽象类的实现类
    class Automobile extends Car {
    
        @Override
        public void run() {
            System.out.println("以60km/h速度跑...");
        }    
    }
    class TransDemo {
        public void trans(Car car) {
            System.out.println("准备货物...");
            System.out.println("发送货物...");
            //传输方法
            car.run();
            System.out.println("接收货物...");
            System.out.println("卸载货物...");
        }
    }
    
    interface Info01{
        public void mx();
    }
    
    public class Demo04 {
        public static void main(String[] args) {
            //1.--普通类
            TransDemo tDemo = new TransDemo();
            //传入子类
            tDemo.trans(new Automobile());
            
            //2.方法内部类
            class Train extends Car {
    
                @Override
                public void run() {
                    System.out.println("火车以160km/h速度跑...");
                }    
            }        
            TransDemo tDemo1 = new TransDemo();
            tDemo1.trans(new Train());
            
            
            //3.匿名内部类
            //--new 一个Car的子类的匿名内部类,该处相当于省去了class XXX extends
            //接口与之类似
            TransDemo tDemo2 = new TransDemo();
            tDemo2.trans(new Car() {
    
                @Override
                public void run() {
                    System.out.println("飞车以1600km/h速度飞...");                
                }            
            });
            tDemo2.trans(new Automobile() {
                @Override
                public void run() {
                    super.run();                
                }        
            });
            
            //4.实例化一个借口的匿名内部类
            new Info01() {
                @Override
                public void mx() {                
                    System.out.println("mx...");    
                }            
            };
        }
    
    }

      

      

  • 相关阅读:
    Java中的权限修饰符
    return,break,continue三者的区别
    JS代码放在不同位置的区别
    创建画笔工具
    关于SPH的核函数求导过程
    c++多级指针与“多维”数组 摘自别人博客
    RAP开发入门-搭建RAP开发环境(一)
    06 media媒体查询
    resolution 像素密度
    手动配置viewport-04
  • 原文地址:https://www.cnblogs.com/chhyan-dream/p/10707956.html
Copyright © 2011-2022 走看看